2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
18 #include <stdlib.h> /* exit */
27 #include <livebox-errno.h>
29 #include "critical_log.h"
32 #include "so_handler.h"
34 #include "update_monitor.h"
38 #define IS_LB_SHOWN(itm) (!(itm)->inst->item->has_livebox_script || ((itm)->inst->item->has_livebox_script && (itm)->is_lb_show))
44 struct instance *inst;
48 double update_interval;
49 int heavy_updating; /* Only for debugging message */
50 int is_paused; /* 1 is paused, 0 is resumed */
61 Eina_List *pending_list;
62 Ecore_Timer *pending_timer;
63 Eina_List *pd_open_pending_list;
64 Ecore_Timer *pd_open_pending_timer;
68 int pending_timer_freezed;
73 .pending_timer = NULL,
74 .pd_open_pending_list = NULL,
75 .pd_open_pending_timer = NULL,
79 .pending_timer_freezed = 0,
82 static Eina_Bool updator_cb(void *data);
84 static void pending_timer_freeze(void)
86 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
87 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
88 DbgPrint("Freeze the pending timer\n");
89 ecore_timer_freeze(s_info.pending_timer);
92 s_info.pending_timer_freezed++;
95 static void pending_timer_thaw(void)
97 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
98 if (!s_info.pending_timer_freezed)
101 s_info.pending_timer_freezed--;
102 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
103 DbgPrint("Thaw the pending timer\n");
104 ecore_timer_thaw(s_info.pending_timer);
109 * -1 : PD is opened, but not mine
110 * 0 : PD is not opened
111 * 1 : my PD is opened
113 static inline int pd_is_opened(const char *pkgname)
120 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
121 if (pkgname && !strcmp(pkgname, tmp))
127 return i > 0 ? -1 : 0;
130 static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
134 item = eina_list_nth(s_info.pd_open_pending_list, 0);
139 return ECORE_CALLBACK_RENEW;
141 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
144 * To prevent from checking the is_updated function
146 (void)updator_cb(item);
147 if (s_info.pd_open_pending_list)
148 return ECORE_CALLBACK_RENEW;
151 s_info.pd_open_pending_timer = NULL;
152 return ECORE_CALLBACK_CANCEL;
155 static Eina_Bool pended_cmd_consumer_cb(void *data)
159 item = eina_list_nth(s_info.pending_list, 0);
163 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
164 return ECORE_CALLBACK_RENEW;
166 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
169 * To prevent from checking the is_updated function
171 (void)updator_cb(item);
172 if (s_info.pending_list)
173 return ECORE_CALLBACK_RENEW;
176 s_info.pending_timer = NULL;
177 s_info.pending_timer_freezed = 0;
178 return ECORE_CALLBACK_CANCEL;
181 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
183 if (s_info.pending_timer)
186 s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
187 if (!s_info.pending_timer) {
188 ErrPrint("Failed to add a new pended command consumer\n");
189 return LB_STATUS_ERROR_FAULT;
193 * Do not increase the freezed counter.
194 * Just freeze the timer.
196 if (s_info.pending_timer_freezed)
197 ecore_timer_freeze(s_info.pending_timer);
202 static inline void deactivate_pending_consumer(void)
204 if (!s_info.pending_timer)
207 ecore_timer_del(s_info.pending_timer);
208 s_info.pending_timer = NULL;
209 s_info.pending_timer_freezed = 0;
212 static inline void deactivate_pd_open_pending_consumer(void)
214 if (!s_info.pd_open_pending_timer)
217 ecore_timer_del(s_info.pd_open_pending_timer);
218 s_info.pd_open_pending_timer = NULL;
221 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
223 if (s_info.pd_open_pending_timer)
226 s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
227 if (!s_info.pd_open_pending_timer) {
228 ErrPrint("Failed to add a new pended command consumer\n");
229 return LB_STATUS_ERROR_FAULT;
235 static inline void migrate_to_pd_open_pending_list(const char *pkgname)
242 EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
243 if (strcmp(pkgname, item->inst->item->pkgname))
246 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
247 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
251 if (s_info.pd_open_pending_list)
252 activate_pd_open_pending_consumer();
254 if (!s_info.pending_list)
255 deactivate_pending_consumer();
258 static inline void migrate_to_pending_list(const char *pkgname)
265 EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
266 if (strcmp(pkgname, item->inst->item->pkgname))
269 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
270 s_info.pending_list = eina_list_append(s_info.pending_list, item);
274 if (s_info.pending_list)
275 activate_pending_consumer();
277 if (!s_info.pd_open_pending_list)
278 deactivate_pd_open_pending_consumer();
281 static inline int append_pending_list(struct item *item)
283 if (pd_is_opened(item->inst->item->pkgname) == 1) {
284 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
285 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
286 return LB_STATUS_ERROR_EXIST;
289 if (activate_pd_open_pending_consumer() < 0) {
290 ErrPrint("Failed to activate PD open pending consumer\n");
291 return LB_STATUS_ERROR_FAULT;
294 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
296 if (eina_list_data_find(s_info.pending_list, item) == item) {
297 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
298 return LB_STATUS_ERROR_EXIST;
301 if (activate_pending_consumer() < 0)
302 return LB_STATUS_ERROR_FAULT;
304 s_info.pending_list = eina_list_append(s_info.pending_list, item);
309 static inline void timer_thaw(struct item *item)
319 ecore_timer_thaw(item->timer);
320 period = ecore_timer_interval_get(item->timer);
321 pending = ecore_timer_pending_get(item->timer);
322 delay = util_time_delay_for_compensation(period) - pending;
323 ecore_timer_delay(item->timer, delay);
325 if (item->sleep_at == 0.0f)
328 sleep_time = util_timestamp() - item->sleep_at;
329 if (sleep_time > pending)
330 (void)updator_cb(item);
332 item->sleep_at = 0.0f;
335 static inline void timer_freeze(struct item *item)
342 ecore_timer_freeze(item->timer);
344 if (ecore_timer_interval_get(item->timer) <= 1.0f)
347 if (gettimeofday(&tv, NULL) < 0) {
348 ErrPrint("gettimeofday: %s\n", strerror(errno));
353 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
356 static inline void update_monitor_cnt(struct item *item)
361 now = util_timestamp();
362 interval = now - item->update_interval;
366 * If the content update is processed in too short time,
367 * don't increase the monitor counter, instead of it
368 * set the heavy updating flag.
369 * And handling this heavy updating from the
370 * file update callback.
372 if (interval >= MINIMUM_UPDATE_INTERVAL) {
373 if (s_info.update == item) {
376 * If already in updating mode,
377 * reset the monitor_cnt to 1,
378 * all updated event will be merged into A inotify event
380 DbgPrint("While waiting updated event, content is updated [%s]\n", item->inst->id);
381 item->monitor_cnt = 1;
386 item->heavy_updating = 1;
389 item->update_interval = now;
392 static inline Eina_List *find_item(struct instance *inst)
397 EINA_LIST_FOREACH(s_info.item_list, l, item) {
398 if (item->inst == inst)
405 static inline int output_handler(struct item *item)
410 if (item->monitor_cnt < 0 || item->heavy_updating) {
411 if (!item->heavy_updating) {
412 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
415 item->heavy_updating = 0; /* Reset flag */
418 item->monitor_cnt = 0;
421 if (item->monitor_cnt == 0) {
423 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
426 ecore_timer_del(item->monitor);
427 item->monitor = NULL;
430 if (s_info.update == item)
431 s_info.update = NULL;
433 if (item->deleteme) {
434 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
435 (void)so_destroy(item->inst);
444 static int desc_updated_cb(const char *filename, void *data, int over)
449 WarnPrint("Event Q overflow\n");
453 DbgPrint("DESC %s is updated\n", filename);
454 if (item->is_pd_show) {
455 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
457 ErrPrint("But PD is not opened, Ignore this update (%s)\n", item->inst->id);
462 static int file_updated_cb(const char *filename, void *data, int over)
468 char *content = NULL;
473 WarnPrint("Event Q overflow\n");
477 ret = util_get_filesize(filename);
479 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
480 return EXIT_SUCCESS; /*!< To keep the callback */
483 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
485 ErrPrint("livebox_get_info returns %d\n", ret);
486 return EXIT_SUCCESS; /*!< To keep the callback */
489 if (IS_LB_SHOWN(item)) {
490 provider_send_updated(item->inst->item->pkgname, item->inst->id,
491 item->inst->w, item->inst->h, item->inst->priority, content, title);
493 item->is_lb_updated++;
496 return output_handler(item);
499 static inline int clear_from_pd_open_pending_list(struct item *item)
504 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
508 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
509 if (!s_info.pd_open_pending_list)
510 deactivate_pd_open_pending_consumer();
511 return LB_STATUS_SUCCESS;
514 return LB_STATUS_ERROR_NOT_EXIST;
517 static inline int clear_from_pending_list(struct item *item)
522 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
526 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
527 if (!s_info.pending_list)
528 deactivate_pending_consumer();
529 return LB_STATUS_SUCCESS;
532 return LB_STATUS_ERROR_NOT_EXIST;
535 static Eina_Bool update_timeout_cb(void *data)
541 ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
543 if (s_info.update != item)
544 ErrPrint("Updating item is not matched\n");
546 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
547 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
548 s_info.update = NULL;
551 return ECORE_CALLBACK_CANCEL;
554 static Eina_Bool updator_cb(void *data)
561 if (item->monitor) {/*!< If this item is already in update process */
562 return ECORE_CALLBACK_RENEW;
565 if (!IS_LB_SHOWN(item)) {
566 DbgPrint("%s is not shown yet. delaying updates\n", item->inst->item->pkgname);
567 (void)append_pending_list(item);
568 return ECORE_CALLBACK_RENEW;
571 ret = so_is_updated(item->inst);
573 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
574 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
575 lb_destroy(item->inst->item->pkgname, item->inst->id);
577 ecore_timer_del(item->timer);
579 return ECORE_CALLBACK_CANCEL;
582 return ECORE_CALLBACK_RENEW;
585 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
586 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
587 (void)append_pending_list(item);
588 return ECORE_CALLBACK_RENEW;
591 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
592 if (!item->monitor) {
593 ErrPrint("Failed to add update monitor %s(%s):%d\n",
594 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
595 return ECORE_CALLBACK_RENEW;
598 ret = so_update(item->inst);
600 ecore_timer_del(item->monitor);
601 item->monitor = NULL;
602 return ECORE_CALLBACK_RENEW;
607 * Counter of the event monitor is only used for asynchronous content updating,
608 * So reset it to 1 from here because the async updating is started now,
609 * even if it is accumulated by other event function before this.
611 item->monitor_cnt = 1;
615 * While waiting the Callback function call,
616 * Add this for finding the crash
618 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
620 if (ret & NEED_TO_SCHEDULE)
621 (void)append_pending_list(item);
623 if (ret & OUTPUT_UPDATED) {
626 * In this case, there is potential issue
627 * 1. User added update CALLBACK -> Inotify event (Only once)
628 * > We have to detect this case. Is it possible to be a user callback called faster than inotify event handler?
629 * 2. Inotify event -> User added update CALLBACK -> Inotify event
630 * > Okay. What we want is this.
632 update_monitor_cnt(item);
637 * This should be updated after "update_monitor_cnt" function call,
638 * because the update_monitor_cnt function will see the s_info.update variable,
640 s_info.update = item;
642 return ECORE_CALLBACK_RENEW;
645 static inline void update_monitor_del(const char *id, struct item *item)
650 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
652 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
655 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
659 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
660 update_monitor_del_update_cb(tmp, desc_updated_cb);
664 static inline int add_desc_update_monitor(const char *id, struct item *item)
669 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
670 filename = malloc(len);
672 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
673 return LB_STATUS_ERROR_MEMORY;
676 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
677 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
680 static inline int add_file_update_monitor(const char *id, struct item *item)
684 filename = strdup(util_uri_to_path(id));
686 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
687 return LB_STATUS_ERROR_MEMORY;
690 return update_monitor_add_update_cb(filename, file_updated_cb, item);
693 static inline int update_monitor_add(const char *id, struct item *item)
697 * item->inst is not available yet.
699 add_file_update_monitor(id, item);
700 add_desc_update_monitor(id, item);
701 return LB_STATUS_SUCCESS;
704 HAPI int lb_init(void)
706 return LB_STATUS_SUCCESS;
709 HAPI int lb_fini(void)
715 deactivate_pending_consumer();
716 deactivate_pd_open_pending_consumer();
718 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
719 EINA_LIST_FREE(s_info.pending_list, item);
721 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
722 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
723 lb_destroy(item->inst->item->pkgname, item->inst->id);
726 return LB_STATUS_SUCCESS;
731 * Exported API for each liveboxes.
733 const char *livebox_find_pkgname(const char *filename)
738 EINA_LIST_FOREACH(s_info.item_list, l, item) {
739 if (!strcmp(item->inst->id, filename))
740 return item->inst->item->pkgname;
746 int livebox_request_update_by_id(const char *filename)
751 EINA_LIST_FOREACH(s_info.item_list, l, item) {
752 if (!strcmp(item->inst->id, filename)) {
753 return append_pending_list(item);
757 return LB_STATUS_ERROR_NOT_EXIST;
760 HAPI int lb_open_pd(const char *pkgname)
765 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
766 if (!strcmp(pkgname, tmp))
770 tmp = strdup(pkgname);
772 ErrPrint("Heap: %s\n", strerror(errno));
773 return LB_STATUS_ERROR_MEMORY;
777 pending_timer_freeze();
779 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
782 * Find all instances from the pending list.
783 * Move them to pd_open_pending_timer
785 migrate_to_pd_open_pending_list(pkgname);
786 return LB_STATUS_SUCCESS;
789 HAPI int lb_close_pd(const char *pkgname)
795 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
796 if (strcmp(tmp, pkgname))
799 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
803 pending_timer_thaw();
806 * Move all items in pd_open_pending_list
809 migrate_to_pending_list(pkgname);
810 return LB_STATUS_SUCCESS;
813 return LB_STATUS_ERROR_NOT_EXIST;
816 HAPI int lb_create(const char *pkgname, const char *id, const char *content_info, int timeout, int has_livebox_script, double period, const char *cluster, const char *category, int *w, int *h, double *priority, int skip_need_to_create, const char *abi, char **out_content, char **out_title)
818 struct instance *inst;
828 inst = so_find_instance(pkgname, id);
830 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
831 return LB_STATUS_SUCCESS;
834 if (!skip_need_to_create) {
835 ret = so_create_needed(pkgname, cluster, category, abi);
836 if (ret != NEED_TO_CREATE)
837 return LB_STATUS_ERROR_PERMISSION;
842 item = calloc(1, sizeof(*item));
844 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
845 return LB_STATUS_ERROR_MEMORY;
848 ret = update_monitor_add(id, item);
854 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
855 if (create_ret < 0) {
856 update_monitor_del(id, item);
867 if (period > 0.0f && !s_info.secured) {
868 item->timer = util_timer_add(period, updator_cb, item);
870 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
871 update_monitor_del(id, item);
872 (void)so_destroy(inst);
874 return LB_STATUS_ERROR_FAULT;
880 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
884 s_info.item_list = eina_list_append(s_info.item_list, item);
886 if (create_ret & NEED_TO_SCHEDULE) {
887 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
888 (void)append_pending_list(item);
891 if (create_ret & OUTPUT_UPDATED) {
892 update_monitor_cnt(item);
895 * To send a output info, get the info forcely.
896 * but the output file monitor will do this again
898 * This function will set the tmp_content and tmp_title
899 * even if it has no updates on the content, title,
900 * it will set them to NULL.
902 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
906 tmp = strdup(*out_content);
908 ErrPrint("Memory: %s\n", strerror(errno));
916 tmp = strdup(*out_title);
918 ErrPrint("Memory: %s\n", strerror(errno));
927 *priority = inst->priority;
928 return need_to_create;
931 HAPI int lb_destroy(const char *pkgname, const char *id)
934 struct instance *inst;
937 inst = so_find_instance(pkgname, id);
939 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
940 return LB_STATUS_ERROR_INVALID;
945 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
946 return LB_STATUS_ERROR_NOT_EXIST;
949 item = eina_list_data_get(l);
950 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
952 if (s_info.update == item)
953 s_info.update = NULL;
956 clear_from_pd_open_pending_list(item);
957 clear_from_pending_list(item);
958 ecore_timer_del(item->timer);
964 update_monitor_del(id, item);
967 if (!item->monitor) {
969 (void)so_destroy(inst);
972 return LB_STATUS_SUCCESS;
975 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
978 struct instance *inst;
982 inst = so_find_instance(pkgname, id);
984 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
985 return LB_STATUS_ERROR_INVALID;
990 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
991 return LB_STATUS_ERROR_NOT_EXIST;
994 item = eina_list_data_get(l);
996 ret = so_resize(inst, w, h);
1000 if (ret & NEED_TO_SCHEDULE) {
1001 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1002 (void)append_pending_list(item);
1005 if (ret & OUTPUT_UPDATED)
1006 update_monitor_cnt(item);
1008 return LB_STATUS_SUCCESS;
1011 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
1013 struct instance *inst;
1016 inst = so_find_instance(pkgname, id);
1018 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
1022 ret = so_pinup(inst, pinup);
1026 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
1029 struct instance *inst;
1032 inst = so_find_instance(pkgname, id);
1034 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
1035 return LB_STATUS_ERROR_INVALID;
1038 l = find_item(inst);
1040 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1041 return LB_STATUS_ERROR_NOT_EXIST;
1044 item = eina_list_data_get(l);
1046 if (period <= 0.0f) {
1048 ecore_timer_del(item->timer);
1053 util_timer_interval_set(item->timer, period);
1054 } else if (!s_info.secured) {
1055 item->timer = util_timer_add(period, updator_cb, item);
1057 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1058 return LB_STATUS_ERROR_FAULT;
1066 return LB_STATUS_SUCCESS;
1069 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1072 struct instance *inst;
1076 inst = so_find_instance(pkgname, id);
1078 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1079 return LB_STATUS_ERROR_INVALID;
1082 l = find_item(inst);
1084 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1085 return LB_STATUS_ERROR_NOT_EXIST;
1088 item = eina_list_data_get(l);
1090 ret = so_clicked(inst, event, timestamp, x, y);
1094 if (ret & NEED_TO_SCHEDULE) {
1095 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1096 (void)append_pending_list(item);
1099 if (ret & OUTPUT_UPDATED)
1100 update_monitor_cnt(item);
1102 return LB_STATUS_SUCCESS;
1105 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1108 struct instance *inst;
1112 inst = so_find_instance(pkgname, id);
1114 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1115 return LB_STATUS_ERROR_INVALID;
1118 l = find_item(inst);
1120 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1121 return LB_STATUS_ERROR_NOT_EXIST;
1124 item = eina_list_data_get(l);
1126 if (emission && source && !strcmp(source, id)) {
1127 if (item->inst->item->has_livebox_script) {
1128 if (!strcmp(emission, "lb,show")) {
1129 item->is_lb_show = 1;
1131 DbgPrint("[%s] Updated %d times, (content: %s), (title: %s)\n", id, item->is_lb_updated, item->inst->content, item->inst->title);
1132 if (item->is_lb_updated) {
1133 provider_send_updated(item->inst->item->pkgname, item->inst->id,
1134 item->inst->w, item->inst->h, item->inst->priority, item->inst->content, item->inst->title);
1135 item->is_lb_updated = 0;
1138 source = util_uri_to_path(source);
1139 } else if (!strcmp(emission, "lb,hide")) {
1140 DbgPrint("Livebox(%s) script is hide now\n", id);
1141 item->is_lb_show = 0;
1143 source = util_uri_to_path(source);
1147 if (!strcmp(emission, "pd,show")) {
1148 item->is_pd_show = 1;
1149 source = util_uri_to_path(source);
1150 } else if (!strcmp(emission, "pd,hide")) {
1151 item->is_pd_show = 0;
1152 source = util_uri_to_path(source);
1156 ret = so_script_event(inst, emission, source, event_info);
1160 if (ret & NEED_TO_SCHEDULE) {
1161 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1162 (void)append_pending_list(item);
1165 if (ret & OUTPUT_UPDATED)
1166 update_monitor_cnt(item);
1168 return LB_STATUS_SUCCESS;
1171 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1174 struct instance *inst;
1177 inst = so_find_instance(pkgname, id);
1179 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1180 return LB_STATUS_ERROR_INVALID;
1183 l = find_item(inst);
1185 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1186 return LB_STATUS_ERROR_NOT_EXIST;
1189 item = eina_list_data_get(l);
1191 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1192 return LB_STATUS_ERROR_FAULT;
1197 * Maybe this is not neccessary for this operation
1199 return so_is_pinned_up(inst);
1202 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1205 struct instance *inst;
1209 inst = so_find_instance(pkgname, id);
1211 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1212 return LB_STATUS_ERROR_INVALID;
1215 l = find_item(inst);
1217 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1218 return LB_STATUS_ERROR_NOT_EXIST;
1221 item = eina_list_data_get(l);
1223 ret = so_change_group(inst, cluster, category);
1227 if (ret & NEED_TO_SCHEDULE) {
1228 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1229 (void)append_pending_list(item);
1232 if (ret & OUTPUT_UPDATED)
1233 update_monitor_cnt(item);
1235 return LB_STATUS_SUCCESS;
1238 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1242 ret = so_sys_event(inst, event);
1246 if (ret & NEED_TO_SCHEDULE)
1247 (void)append_pending_list(item);
1249 if (ret & OUTPUT_UPDATED)
1250 update_monitor_cnt(item);
1252 return LB_STATUS_SUCCESS;
1255 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1258 struct instance *inst;
1261 inst = so_find_instance(pkgname, id);
1263 ErrPrint("instance %s - %s is not created\n");
1264 return LB_STATUS_ERROR_INVALID;
1267 l = find_item(inst);
1269 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1270 return LB_STATUS_ERROR_NOT_EXIST;
1273 item = eina_list_data_get(l);
1274 return lb_sys_event(inst, item, event);
1277 HAPI int lb_update(const char *pkgname, const char *id)
1280 struct instance *inst;
1283 inst = so_find_instance(pkgname, id);
1285 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1286 return LB_STATUS_ERROR_INVALID;
1289 l = find_item(inst);
1291 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1292 return LB_STATUS_ERROR_NOT_EXIST;
1295 item = eina_list_data_get(l);
1296 (void)append_pending_list(item);
1297 return LB_STATUS_SUCCESS;
1300 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1306 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1307 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1311 if (cluster && strcasecmp(item->inst->cluster, cluster))
1314 if (category && strcasecmp(item->inst->category, category))
1317 if (pkgname && strlen(pkgname)) {
1318 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1319 (void)append_pending_list(item);
1322 (void)append_pending_list(item);
1326 return LB_STATUS_SUCCESS;
1329 HAPI int lb_delete_all_deleteme(void)
1336 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1337 if (!item->deleteme)
1340 s_info.item_list = eina_list_remove(s_info.item_list, item);
1342 update_monitor_del(item->inst->id, item);
1343 (void)so_destroy(item->inst);
1348 DbgPrint("Delete all deleteme: %d\n", cnt);
1349 return LB_STATUS_SUCCESS;
1352 HAPI int lb_system_event_all(int event)
1358 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1362 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1363 lb_sys_event(item->inst, item, event);
1366 return LB_STATUS_SUCCESS;
1369 HAPI void lb_pause_all(void)
1376 pending_timer_freeze();
1378 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1379 if (item->deleteme) {
1380 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1384 if (item->is_paused)
1389 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1393 HAPI void lb_resume_all(void)
1400 pending_timer_thaw();
1402 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1403 if (item->deleteme) {
1404 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1408 if (item->is_paused)
1413 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1417 HAPI int lb_pause(const char *pkgname, const char *id)
1419 struct instance *inst;
1423 inst = so_find_instance(pkgname, id);
1425 return LB_STATUS_ERROR_INVALID;
1427 l = find_item(inst);
1429 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1430 return LB_STATUS_ERROR_NOT_EXIST;
1433 item = eina_list_data_get(l);
1435 return LB_STATUS_ERROR_FAULT;
1437 if (item->deleteme) {
1438 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1439 return LB_STATUS_ERROR_BUSY;
1442 item->is_paused = 1;
1445 return LB_STATUS_SUCCESS;
1449 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1451 return LB_STATUS_SUCCESS;
1454 HAPI int lb_resume(const char *pkgname, const char *id)
1456 struct instance *inst;
1460 inst = so_find_instance(pkgname, id);
1462 return LB_STATUS_ERROR_INVALID;
1464 l = find_item(inst);
1466 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1467 return LB_STATUS_ERROR_NOT_EXIST;
1470 item = eina_list_data_get(l);
1472 return LB_STATUS_ERROR_FAULT;
1474 if (item->deleteme) {
1475 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1476 return LB_STATUS_ERROR_BUSY;
1479 item->is_paused = 0;
1482 return LB_STATUS_SUCCESS;
1486 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1487 return LB_STATUS_SUCCESS;
1490 HAPI void lb_turn_secured_on(void)
1495 HAPI int lb_is_all_paused(void)
1497 return s_info.paused;