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 */
20 #include <unistd.h> /* access */
28 #include <livebox-errno.h>
30 #include "critical_log.h"
33 #include "so_handler.h"
35 #include "update_monitor.h"
39 #define IS_LB_SHOWN(itm) (!(itm)->inst->item->has_livebox_script || ((itm)->inst->item->has_livebox_script && (itm)->is_lb_show))
45 struct instance *inst;
49 double update_interval;
50 int heavy_updating; /* Only for debugging message */
51 int is_paused; /* 1 is paused, 0 is resumed */
54 unsigned int updated_in_pause;
64 Eina_List *pending_list;
65 Ecore_Timer *pending_timer;
66 Eina_List *pd_open_pending_list;
67 Ecore_Timer *pd_open_pending_timer;
71 int pending_timer_freezed;
76 .pending_timer = NULL,
77 .pd_open_pending_list = NULL,
78 .pd_open_pending_timer = NULL,
82 .pending_timer_freezed = 0,
85 static Eina_Bool updator_cb(void *data);
87 static void pending_timer_freeze(void)
89 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
90 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
91 DbgPrint("Freeze the pending timer\n");
92 ecore_timer_freeze(s_info.pending_timer);
95 s_info.pending_timer_freezed++;
98 static void pending_timer_thaw(void)
100 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
101 if (!s_info.pending_timer_freezed)
104 s_info.pending_timer_freezed--;
105 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
106 DbgPrint("Thaw the pending timer\n");
107 ecore_timer_thaw(s_info.pending_timer);
112 * -1 : PD is opened, but not mine
113 * 0 : PD is not opened
114 * 1 : my PD is opened
116 static inline int pd_is_opened(const char *pkgname)
123 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
124 if (pkgname && !strcmp(pkgname, tmp))
130 return i > 0 ? -1 : 0;
133 static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
137 item = eina_list_nth(s_info.pd_open_pending_list, 0);
142 return ECORE_CALLBACK_RENEW;
144 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
147 * To prevent from checking the is_updated function
149 (void)updator_cb(item);
150 if (s_info.pd_open_pending_list)
151 return ECORE_CALLBACK_RENEW;
154 s_info.pd_open_pending_timer = NULL;
155 return ECORE_CALLBACK_CANCEL;
158 static Eina_Bool pended_cmd_consumer_cb(void *data)
162 item = eina_list_nth(s_info.pending_list, 0);
166 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
167 return ECORE_CALLBACK_RENEW;
169 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
172 * To prevent from checking the is_updated function
174 (void)updator_cb(item);
175 if (s_info.pending_list)
176 return ECORE_CALLBACK_RENEW;
179 s_info.pending_timer = NULL;
180 s_info.pending_timer_freezed = 0;
181 return ECORE_CALLBACK_CANCEL;
184 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
186 if (s_info.pending_timer)
189 s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
190 if (!s_info.pending_timer) {
191 ErrPrint("Failed to add a new pended command consumer\n");
192 return LB_STATUS_ERROR_FAULT;
196 * Do not increase the freezed counter.
197 * Just freeze the timer.
199 if (s_info.pending_timer_freezed)
200 ecore_timer_freeze(s_info.pending_timer);
205 static inline void deactivate_pending_consumer(void)
207 if (!s_info.pending_timer)
210 ecore_timer_del(s_info.pending_timer);
211 s_info.pending_timer = NULL;
212 s_info.pending_timer_freezed = 0;
215 static inline void deactivate_pd_open_pending_consumer(void)
217 if (!s_info.pd_open_pending_timer)
220 ecore_timer_del(s_info.pd_open_pending_timer);
221 s_info.pd_open_pending_timer = NULL;
224 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
226 if (s_info.pd_open_pending_timer)
229 s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
230 if (!s_info.pd_open_pending_timer) {
231 ErrPrint("Failed to add a new pended command consumer\n");
232 return LB_STATUS_ERROR_FAULT;
238 static inline void migrate_to_pd_open_pending_list(const char *pkgname)
245 EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
246 if (strcmp(pkgname, item->inst->item->pkgname))
249 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
250 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
254 if (s_info.pd_open_pending_list)
255 activate_pd_open_pending_consumer();
257 if (!s_info.pending_list)
258 deactivate_pending_consumer();
261 static inline void migrate_to_pending_list(const char *pkgname)
268 EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
269 if (strcmp(pkgname, item->inst->item->pkgname))
272 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
273 s_info.pending_list = eina_list_append(s_info.pending_list, item);
277 if (s_info.pending_list)
278 activate_pending_consumer();
280 if (!s_info.pd_open_pending_list)
281 deactivate_pd_open_pending_consumer();
284 static inline int is_pended_item(struct item *item)
286 struct item *in_item;
287 if (pd_is_opened(item->inst->item->pkgname) == 1) {
288 in_item = eina_list_data_find(s_info.pd_open_pending_list, item);
290 in_item = eina_list_data_find(s_info.pending_list, item);
293 return (in_item == item);
296 static int append_pending_list(struct item *item)
298 if (pd_is_opened(item->inst->item->pkgname) == 1) {
299 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
300 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
301 return LB_STATUS_ERROR_EXIST;
304 if (activate_pd_open_pending_consumer() < 0) {
305 ErrPrint("Failed to activate PD open pending consumer\n");
306 return LB_STATUS_ERROR_FAULT;
309 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
311 if (eina_list_data_find(s_info.pending_list, item) == item) {
312 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
313 return LB_STATUS_ERROR_EXIST;
316 if (activate_pending_consumer() < 0)
317 return LB_STATUS_ERROR_FAULT;
319 s_info.pending_list = eina_list_append(s_info.pending_list, item);
324 static inline void timer_thaw(struct item *item)
334 ecore_timer_thaw(item->timer);
335 period = ecore_timer_interval_get(item->timer);
336 pending = ecore_timer_pending_get(item->timer);
337 delay = util_time_delay_for_compensation(period) - pending;
338 ecore_timer_delay(item->timer, delay);
340 if (item->sleep_at == 0.0f)
343 sleep_time = util_timestamp() - item->sleep_at;
344 if (sleep_time > pending)
345 (void)updator_cb(item);
347 item->sleep_at = 0.0f;
350 static inline void timer_freeze(struct item *item)
357 ecore_timer_freeze(item->timer);
359 if (ecore_timer_interval_get(item->timer) <= 1.0f)
362 if (gettimeofday(&tv, NULL) < 0) {
363 ErrPrint("gettimeofday: %s\n", strerror(errno));
368 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
371 static inline void update_monitor_cnt(struct item *item)
376 now = util_timestamp();
377 interval = now - item->update_interval;
381 * If the content update is processed in too short time,
382 * don't increase the monitor counter, instead of it
383 * set the heavy updating flag.
384 * And handling this heavy updating from the
385 * file update callback.
387 if (interval >= MINIMUM_UPDATE_INTERVAL) {
388 if (s_info.update == item) {
391 * If already in updating mode,
392 * reset the monitor_cnt to 1,
393 * all updated event will be merged into A inotify event
395 DbgPrint("While waiting updated event, content is updated [%s]\n", item->inst->id);
396 item->monitor_cnt = 1;
401 item->heavy_updating = 1;
404 item->update_interval = now;
407 static inline Eina_List *find_item(struct instance *inst)
412 EINA_LIST_FOREACH(s_info.item_list, l, item) {
413 if (item->inst == inst)
420 static inline int output_handler(struct item *item)
425 if (item->monitor_cnt < 0 || item->heavy_updating) {
426 if (!item->heavy_updating) {
427 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
430 item->heavy_updating = 0; /* Reset flag */
433 item->monitor_cnt = 0;
436 if (item->monitor_cnt == 0) {
438 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
441 ecore_timer_del(item->monitor);
442 item->monitor = NULL;
445 if (s_info.update == item)
446 s_info.update = NULL;
448 if (item->deleteme) {
449 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
450 (void)so_destroy(item->inst);
459 static int desc_updated_cb(const char *filename, void *data, int over)
464 WarnPrint("Event Q overflow\n");
468 DbgPrint("DESC %s is updated\n", filename);
469 if (item->is_pd_show) {
470 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
472 ErrPrint("But PD is not opened, Ignore this update (%s)\n", item->inst->id);
477 static int file_updated_cb(const char *filename, void *data, int over)
483 char *content = NULL;
488 WarnPrint("Event Q overflow\n");
492 ret = util_get_filesize(filename);
494 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
495 return EXIT_SUCCESS; /*!< To keep the callback */
498 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
500 ErrPrint("livebox_get_info returns %d\n", ret);
501 return EXIT_SUCCESS; /*!< To keep the callback */
504 if (IS_LB_SHOWN(item)) {
505 provider_send_updated(item->inst->item->pkgname, item->inst->id,
506 item->inst->w, item->inst->h, item->inst->priority,
509 item->is_lb_updated++;
512 return output_handler(item);
515 static void reset_lb_updated_flag(struct item *item)
517 if (!item->is_lb_updated)
520 DbgPrint("[%s] Updated %d times, (content: %s), (title: %s)\n",
521 item->inst->id, item->is_lb_updated,
522 item->inst->content, item->inst->title);
524 provider_send_updated(item->inst->item->pkgname, item->inst->id,
525 item->inst->w, item->inst->h, item->inst->priority,
526 item->inst->content, item->inst->title);
528 item->is_lb_updated = 0;
531 static inline int clear_from_pd_open_pending_list(struct item *item)
536 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
540 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
541 if (!s_info.pd_open_pending_list)
542 deactivate_pd_open_pending_consumer();
543 return LB_STATUS_SUCCESS;
546 return LB_STATUS_ERROR_NOT_EXIST;
549 static inline int clear_from_pending_list(struct item *item)
554 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
558 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
559 if (!s_info.pending_list)
560 deactivate_pending_consumer();
561 return LB_STATUS_SUCCESS;
564 return LB_STATUS_ERROR_NOT_EXIST;
567 static Eina_Bool update_timeout_cb(void *data)
573 ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
575 if (s_info.update != item)
576 ErrPrint("Updating item is not matched\n");
578 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
579 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
580 s_info.update = NULL;
583 return ECORE_CALLBACK_CANCEL;
586 static Eina_Bool updator_cb(void *data)
593 if (item->monitor) {/*!< If this item is already in update process */
594 return ECORE_CALLBACK_RENEW;
597 if (!IS_LB_SHOWN(item)) {
598 DbgPrint("%s is not shown yet. make delay for updates\n", item->inst->item->pkgname);
599 (void)append_pending_list(item);
600 return ECORE_CALLBACK_RENEW;
603 if (item->is_paused) {
604 item->updated_in_pause++;
605 DbgPrint("%s is paused[%d]. make delay for updating\n", item->inst->item->pkgname, item->updated_in_pause);
606 return ECORE_CALLBACK_RENEW;
609 item->updated_in_pause = 0;
611 ret = so_is_updated(item->inst);
613 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
614 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
615 lb_destroy(item->inst->item->pkgname, item->inst->id);
617 ecore_timer_del(item->timer);
619 return ECORE_CALLBACK_CANCEL;
622 reset_lb_updated_flag(item);
623 return ECORE_CALLBACK_RENEW;
626 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
627 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
628 (void)append_pending_list(item);
629 return ECORE_CALLBACK_RENEW;
632 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
633 if (!item->monitor) {
634 ErrPrint("Failed to add update monitor %s(%s):%d\n",
635 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
636 return ECORE_CALLBACK_RENEW;
639 ret = so_update(item->inst);
641 ecore_timer_del(item->monitor);
642 item->monitor = NULL;
643 reset_lb_updated_flag(item);
644 return ECORE_CALLBACK_RENEW;
649 * Counter of the event monitor is only used for asynchronous content updating,
650 * So reset it to 1 from here because the async updating is started now,
651 * even if it is accumulated by other event function before this.
653 item->monitor_cnt = 1;
657 * While waiting the Callback function call,
658 * Add this for finding the crash
660 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
662 if (ret & NEED_TO_SCHEDULE)
663 (void)append_pending_list(item);
665 if (ret & OUTPUT_UPDATED) {
668 * In this case, there is potential issue
669 * 1. User added update CALLBACK -> Inotify event (Only once)
670 * > We have to detect this case. Is it possible to be a user callback called faster than inotify event handler?
671 * 2. Inotify event -> User added update CALLBACK -> Inotify event
672 * > Okay. What we want is this.
674 update_monitor_cnt(item);
679 * This should be updated after "update_monitor_cnt" function call,
680 * because the update_monitor_cnt function will see the s_info.update variable,
682 s_info.update = item;
684 return ECORE_CALLBACK_RENEW;
687 static inline void update_monitor_del(const char *id, struct item *item)
692 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
694 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
697 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
701 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
702 update_monitor_del_update_cb(tmp, desc_updated_cb);
706 static inline int add_desc_update_monitor(const char *id, struct item *item)
711 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
712 filename = malloc(len);
714 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
715 return LB_STATUS_ERROR_MEMORY;
718 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
719 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
722 static inline int add_file_update_monitor(const char *id, struct item *item)
726 filename = strdup(util_uri_to_path(id));
728 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
729 return LB_STATUS_ERROR_MEMORY;
732 return update_monitor_add_update_cb(filename, file_updated_cb, item);
735 static inline int update_monitor_add(const char *id, struct item *item)
739 * item->inst is not available yet.
741 add_file_update_monitor(id, item);
742 add_desc_update_monitor(id, item);
743 return LB_STATUS_SUCCESS;
746 HAPI int lb_init(void)
748 return LB_STATUS_SUCCESS;
751 HAPI int lb_fini(void)
757 deactivate_pending_consumer();
758 deactivate_pd_open_pending_consumer();
760 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
761 EINA_LIST_FREE(s_info.pending_list, item);
763 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
764 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
765 lb_destroy(item->inst->item->pkgname, item->inst->id);
768 return LB_STATUS_SUCCESS;
773 * Exported API for each liveboxes.
775 const char *livebox_find_pkgname(const char *filename)
780 EINA_LIST_FOREACH(s_info.item_list, l, item) {
781 if (!strcmp(item->inst->id, filename))
782 return item->inst->item->pkgname;
788 int livebox_request_update_by_id(const char *filename)
793 if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
794 ErrPrint("Current operation: %d\n", so_current_op());
795 return LB_STATUS_ERROR_INVALID;
798 EINA_LIST_FOREACH(s_info.item_list, l, item) {
799 if (!strcmp(item->inst->id, filename)) {
800 return append_pending_list(item);
804 return LB_STATUS_ERROR_NOT_EXIST;
807 int livebox_trigger_update_monitor(const char *filename, int is_pd)
812 if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
813 ErrPrint("Current operation: %d\n", so_current_op());
814 return LB_STATUS_ERROR_INVALID;
819 len = strlen(filename) + strlen(".desc");
821 fname = malloc(len + 1);
823 ErrPrint("Heap: %s\n", strerror(errno));
824 return LB_STATUS_ERROR_MEMORY;
827 snprintf(fname, len, "%s.desc", filename);
829 fname = strdup(filename);
831 ErrPrint("Heap: %s\n", strerror(errno));
832 return LB_STATUS_ERROR_MEMORY;
836 if (access(fname, R_OK | W_OK) != 0) {
837 ErrPrint("access: %s (%s)\n", fname, strerror(errno));
838 ret = LB_STATUS_ERROR_IO;
840 ret = update_monitor_trigger_update_cb(fname, 0);
847 HAPI int lb_open_pd(const char *pkgname)
852 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
853 if (!strcmp(pkgname, tmp))
857 tmp = strdup(pkgname);
859 ErrPrint("Heap: %s\n", strerror(errno));
860 return LB_STATUS_ERROR_MEMORY;
864 pending_timer_freeze();
866 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
869 * Find all instances from the pending list.
870 * Move them to pd_open_pending_timer
872 migrate_to_pd_open_pending_list(pkgname);
873 return LB_STATUS_SUCCESS;
876 HAPI int lb_close_pd(const char *pkgname)
882 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
883 if (strcmp(tmp, pkgname))
886 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
890 pending_timer_thaw();
893 * Move all items in pd_open_pending_list
896 migrate_to_pending_list(pkgname);
897 return LB_STATUS_SUCCESS;
900 return LB_STATUS_ERROR_NOT_EXIST;
903 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)
905 struct instance *inst;
915 inst = so_find_instance(pkgname, id);
917 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
918 return LB_STATUS_SUCCESS;
921 if (!skip_need_to_create) {
922 ret = so_create_needed(pkgname, cluster, category, abi);
923 if (ret != NEED_TO_CREATE)
924 return LB_STATUS_ERROR_PERMISSION;
929 item = calloc(1, sizeof(*item));
931 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
932 return LB_STATUS_ERROR_MEMORY;
935 ret = update_monitor_add(id, item);
941 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
942 if (create_ret < 0) {
943 update_monitor_del(id, item);
954 if (period > 0.0f && !s_info.secured) {
955 item->timer = util_timer_add(period, updator_cb, item);
957 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
958 update_monitor_del(id, item);
959 (void)so_destroy(inst);
961 return LB_STATUS_ERROR_FAULT;
967 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
971 s_info.item_list = eina_list_append(s_info.item_list, item);
973 if (create_ret & NEED_TO_SCHEDULE) {
974 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
975 (void)append_pending_list(item);
978 if (create_ret & OUTPUT_UPDATED) {
979 update_monitor_cnt(item);
982 * To send a output info, get the info forcely.
983 * but the output file monitor will do this again
985 * This function will set the tmp_content and tmp_title
986 * even if it has no updates on the content, title,
987 * it will set them to NULL.
989 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
993 tmp = strdup(*out_content);
995 ErrPrint("Memory: %s\n", strerror(errno));
1003 tmp = strdup(*out_title);
1005 ErrPrint("Memory: %s\n", strerror(errno));
1014 *priority = inst->priority;
1015 return need_to_create;
1018 HAPI int lb_destroy(const char *pkgname, const char *id)
1021 struct instance *inst;
1024 inst = so_find_instance(pkgname, id);
1026 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1027 return LB_STATUS_ERROR_INVALID;
1030 l = find_item(inst);
1032 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1033 return LB_STATUS_ERROR_NOT_EXIST;
1036 item = eina_list_data_get(l);
1037 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
1039 if (s_info.update == item)
1040 s_info.update = NULL;
1043 clear_from_pd_open_pending_list(item);
1044 clear_from_pending_list(item);
1045 ecore_timer_del(item->timer);
1051 update_monitor_del(id, item);
1054 if (!item->monitor) {
1056 (void)so_destroy(inst);
1059 return LB_STATUS_SUCCESS;
1062 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
1065 struct instance *inst;
1069 inst = so_find_instance(pkgname, id);
1071 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
1072 return LB_STATUS_ERROR_INVALID;
1075 l = find_item(inst);
1077 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
1078 return LB_STATUS_ERROR_NOT_EXIST;
1081 item = eina_list_data_get(l);
1083 ret = so_resize(inst, w, h);
1087 if (ret & NEED_TO_SCHEDULE) {
1088 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1089 (void)append_pending_list(item);
1092 if (ret & OUTPUT_UPDATED)
1093 update_monitor_cnt(item);
1095 return LB_STATUS_SUCCESS;
1098 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
1100 struct instance *inst;
1103 inst = so_find_instance(pkgname, id);
1105 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
1109 ret = so_pinup(inst, pinup);
1113 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
1116 struct instance *inst;
1119 inst = so_find_instance(pkgname, id);
1121 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
1122 return LB_STATUS_ERROR_INVALID;
1125 l = find_item(inst);
1127 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1128 return LB_STATUS_ERROR_NOT_EXIST;
1131 item = eina_list_data_get(l);
1133 if (period <= 0.0f) {
1135 ecore_timer_del(item->timer);
1140 util_timer_interval_set(item->timer, period);
1141 } else if (!s_info.secured) {
1142 item->timer = util_timer_add(period, updator_cb, item);
1144 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1145 return LB_STATUS_ERROR_FAULT;
1153 return LB_STATUS_SUCCESS;
1156 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1159 struct instance *inst;
1163 inst = so_find_instance(pkgname, id);
1165 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1166 return LB_STATUS_ERROR_INVALID;
1169 l = find_item(inst);
1171 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1172 return LB_STATUS_ERROR_NOT_EXIST;
1175 item = eina_list_data_get(l);
1177 ret = so_clicked(inst, event, timestamp, x, y);
1181 if (ret & NEED_TO_SCHEDULE) {
1182 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1183 (void)append_pending_list(item);
1186 if (ret & OUTPUT_UPDATED)
1187 update_monitor_cnt(item);
1189 return LB_STATUS_SUCCESS;
1192 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1195 struct instance *inst;
1199 inst = so_find_instance(pkgname, id);
1201 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1202 return LB_STATUS_ERROR_INVALID;
1205 l = find_item(inst);
1207 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1208 return LB_STATUS_ERROR_NOT_EXIST;
1211 item = eina_list_data_get(l);
1213 if (emission && source && !strcmp(source, id)) {
1214 if (item->inst->item->has_livebox_script) {
1215 if (!strcmp(emission, "lb,show")) {
1216 item->is_lb_show = 1;
1218 if (item->is_lb_updated && !is_pended_item(item))
1219 reset_lb_updated_flag(item);
1221 source = util_uri_to_path(source);
1222 } else if (!strcmp(emission, "lb,hide")) {
1223 DbgPrint("Livebox(%s) script is hide now\n", id);
1224 item->is_lb_show = 0;
1226 source = util_uri_to_path(source);
1230 if (!strcmp(emission, "pd,show")) {
1231 item->is_pd_show = 1;
1232 source = util_uri_to_path(source);
1233 } else if (!strcmp(emission, "pd,hide")) {
1234 item->is_pd_show = 0;
1235 source = util_uri_to_path(source);
1239 ret = so_script_event(inst, emission, source, event_info);
1243 if (ret & NEED_TO_SCHEDULE) {
1244 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1245 (void)append_pending_list(item);
1248 if (ret & OUTPUT_UPDATED)
1249 update_monitor_cnt(item);
1251 return LB_STATUS_SUCCESS;
1254 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1257 struct instance *inst;
1260 inst = so_find_instance(pkgname, id);
1262 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1263 return LB_STATUS_ERROR_INVALID;
1266 l = find_item(inst);
1268 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1269 return LB_STATUS_ERROR_NOT_EXIST;
1272 item = eina_list_data_get(l);
1274 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1275 return LB_STATUS_ERROR_FAULT;
1280 * Maybe this is not neccessary for this operation
1282 return so_is_pinned_up(inst);
1285 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1288 struct instance *inst;
1292 inst = so_find_instance(pkgname, id);
1294 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1295 return LB_STATUS_ERROR_INVALID;
1298 l = find_item(inst);
1300 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1301 return LB_STATUS_ERROR_NOT_EXIST;
1304 item = eina_list_data_get(l);
1306 ret = so_change_group(inst, cluster, category);
1310 if (ret & NEED_TO_SCHEDULE) {
1311 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1312 (void)append_pending_list(item);
1315 if (ret & OUTPUT_UPDATED)
1316 update_monitor_cnt(item);
1318 return LB_STATUS_SUCCESS;
1321 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1325 ret = so_sys_event(inst, event);
1329 if (ret & NEED_TO_SCHEDULE)
1330 (void)append_pending_list(item);
1332 if (ret & OUTPUT_UPDATED)
1333 update_monitor_cnt(item);
1335 return LB_STATUS_SUCCESS;
1338 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1341 struct instance *inst;
1344 inst = so_find_instance(pkgname, id);
1346 ErrPrint("instance %s - %s is not created\n");
1347 return LB_STATUS_ERROR_INVALID;
1350 l = find_item(inst);
1352 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1353 return LB_STATUS_ERROR_NOT_EXIST;
1356 item = eina_list_data_get(l);
1357 return lb_sys_event(inst, item, event);
1360 HAPI int lb_update(const char *pkgname, const char *id)
1363 struct instance *inst;
1366 inst = so_find_instance(pkgname, id);
1368 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1369 return LB_STATUS_ERROR_INVALID;
1372 l = find_item(inst);
1374 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1375 return LB_STATUS_ERROR_NOT_EXIST;
1378 item = eina_list_data_get(l);
1379 (void)append_pending_list(item);
1380 return LB_STATUS_SUCCESS;
1383 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1389 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1390 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1394 if (cluster && strcasecmp(item->inst->cluster, cluster))
1397 if (category && strcasecmp(item->inst->category, category))
1400 if (pkgname && strlen(pkgname)) {
1401 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1402 (void)append_pending_list(item);
1405 (void)append_pending_list(item);
1409 return LB_STATUS_SUCCESS;
1412 HAPI int lb_delete_all_deleteme(void)
1419 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1420 if (!item->deleteme)
1423 s_info.item_list = eina_list_remove(s_info.item_list, item);
1425 update_monitor_del(item->inst->id, item);
1426 (void)so_destroy(item->inst);
1431 DbgPrint("Delete all deleteme: %d\n", cnt);
1432 return LB_STATUS_SUCCESS;
1435 HAPI int lb_system_event_all(int event)
1441 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1445 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1446 lb_sys_event(item->inst, item, event);
1449 return LB_STATUS_SUCCESS;
1452 HAPI void lb_pause_all(void)
1459 pending_timer_freeze();
1461 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1462 if (item->deleteme) {
1463 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1467 if (item->is_paused)
1472 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1476 HAPI void lb_resume_all(void)
1483 pending_timer_thaw();
1485 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1486 if (item->deleteme) {
1487 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1491 if (item->is_paused)
1496 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1498 if (item->updated_in_pause) {
1499 (void)append_pending_list(item);
1500 item->updated_in_pause = 0;
1505 HAPI int lb_pause(const char *pkgname, const char *id)
1507 struct instance *inst;
1511 inst = so_find_instance(pkgname, id);
1513 return LB_STATUS_ERROR_INVALID;
1515 l = find_item(inst);
1517 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1518 return LB_STATUS_ERROR_NOT_EXIST;
1521 item = eina_list_data_get(l);
1523 return LB_STATUS_ERROR_FAULT;
1525 if (item->deleteme) {
1526 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1527 return LB_STATUS_ERROR_BUSY;
1530 item->is_paused = 1;
1533 return LB_STATUS_SUCCESS;
1537 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1539 return LB_STATUS_SUCCESS;
1542 HAPI int lb_resume(const char *pkgname, const char *id)
1544 struct instance *inst;
1548 inst = so_find_instance(pkgname, id);
1550 return LB_STATUS_ERROR_INVALID;
1552 l = find_item(inst);
1554 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1555 return LB_STATUS_ERROR_NOT_EXIST;
1558 item = eina_list_data_get(l);
1560 return LB_STATUS_ERROR_FAULT;
1562 if (item->deleteme) {
1563 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1564 return LB_STATUS_ERROR_BUSY;
1567 item->is_paused = 0;
1570 return LB_STATUS_SUCCESS;
1574 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1576 if (item->updated_in_pause) {
1577 (void)append_pending_list(item);
1578 item->updated_in_pause = 0;
1581 return LB_STATUS_SUCCESS;
1584 HAPI void lb_turn_secured_on(void)
1589 HAPI int lb_is_all_paused(void)
1591 return s_info.paused;