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"
42 struct instance *inst;
46 double update_interval;
47 int heavy_updating; /* Only for debugging message */
48 int is_paused; /* 1 is paused, 0 is resumed */
59 Eina_List *pending_list;
60 Ecore_Timer *pending_timer;
61 Eina_List *pd_open_pending_list;
62 Ecore_Timer *pd_open_pending_timer;
66 int pending_timer_freezed;
71 .pending_timer = NULL,
72 .pd_open_pending_list = NULL,
73 .pd_open_pending_timer = NULL,
77 .pending_timer_freezed = 0,
80 static Eina_Bool updator_cb(void *data);
82 static void pending_timer_freeze(void)
84 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
85 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
86 DbgPrint("Freeze the pending timer\n");
87 ecore_timer_freeze(s_info.pending_timer);
90 s_info.pending_timer_freezed++;
93 static void pending_timer_thaw(void)
95 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
96 if (!s_info.pending_timer_freezed)
99 s_info.pending_timer_freezed--;
100 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
101 DbgPrint("Thaw the pending timer\n");
102 ecore_timer_thaw(s_info.pending_timer);
107 * -1 : PD is opened, but not mine
108 * 0 : PD is not opened
109 * 1 : my PD is opened
111 static inline int pd_is_opened(const char *pkgname)
118 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
119 if (pkgname && !strcmp(pkgname, tmp)) {
120 DbgPrint("PD(%s) is opened\n", pkgname);
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);
142 DbgPrint("Consuming pended item: %s\n", item->inst->id);
145 * To prevent from checking the is_updated function
147 (void)updator_cb(item);
148 if (s_info.pd_open_pending_list)
149 return ECORE_CALLBACK_RENEW;
152 s_info.pd_open_pending_timer = NULL;
153 DbgPrint("open pd pending list exhausted\n");
154 return ECORE_CALLBACK_CANCEL;
157 static Eina_Bool pended_cmd_consumer_cb(void *data)
161 item = eina_list_nth(s_info.pending_list, 0);
165 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
166 return ECORE_CALLBACK_RENEW;
168 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
169 DbgPrint("Consuming pended item: %s\n", item->inst->id);
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 DbgPrint("pending list exhausted\n");
182 return ECORE_CALLBACK_CANCEL;
185 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
187 if (s_info.pending_timer)
190 s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
191 if (!s_info.pending_timer) {
192 ErrPrint("Failed to add a new pended command consumer\n");
193 return LB_STATUS_ERROR_FAULT;
197 * Do not increase the freezed counter.
198 * Just freeze the timer.
200 if (s_info.pending_timer_freezed) {
201 DbgPrint("Pending timer created and freezed\n");
202 ecore_timer_freeze(s_info.pending_timer);
208 static inline void deactivate_pending_consumer(void)
210 if (!s_info.pending_timer)
213 ecore_timer_del(s_info.pending_timer);
214 s_info.pending_timer = NULL;
215 s_info.pending_timer_freezed = 0;
216 DbgPrint("Clear the pending timer\n");
219 static inline void deactivate_pd_open_pending_consumer(void)
221 if (!s_info.pd_open_pending_timer)
224 ecore_timer_del(s_info.pd_open_pending_timer);
225 s_info.pd_open_pending_timer = NULL;
226 DbgPrint("Clear the open_pd_pending timer\n");
229 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
231 if (s_info.pd_open_pending_timer)
234 s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
235 if (!s_info.pd_open_pending_timer) {
236 ErrPrint("Failed to add a new pended command consumer\n");
237 return LB_STATUS_ERROR_FAULT;
243 static inline void migrate_to_pd_open_pending_list(const char *pkgname)
250 EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
251 if (strcmp(pkgname, item->inst->item->pkgname))
254 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
255 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
259 if (s_info.pd_open_pending_list) {
260 DbgPrint("Activate PD open pending consumer (%s)\n", pkgname);
261 activate_pd_open_pending_consumer();
264 if (!s_info.pending_list)
265 deactivate_pending_consumer();
267 DbgPrint("%d items are migrated\n", cnt);
270 static inline void migrate_to_pending_list(const char *pkgname)
277 EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
278 if (strcmp(pkgname, item->inst->item->pkgname))
281 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
282 s_info.pending_list = eina_list_append(s_info.pending_list, item);
286 if (s_info.pending_list)
287 activate_pending_consumer();
289 if (!s_info.pd_open_pending_list)
290 deactivate_pd_open_pending_consumer();
292 DbgPrint("%d items are migrated\n", cnt);
295 static inline int append_pending_list(struct item *item)
297 if (pd_is_opened(item->inst->item->pkgname) == 1) {
298 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
299 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
300 return LB_STATUS_ERROR_EXIST;
303 DbgPrint("Activate PD open pending consumer (%s)\n", item->inst->item->pkgname);
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);
339 DbgPrint("Compensated: %lf, Instance %s resume timer\n", delay, item->inst->item->pkgname);
341 if (item->sleep_at == 0.0f)
344 sleep_time = util_timestamp() - item->sleep_at;
345 if (sleep_time > pending) {
346 DbgPrint("Update time elapsed\n");
347 (void)updator_cb(item);
350 item->sleep_at = 0.0f;
353 static inline void timer_freeze(struct item *item)
360 ecore_timer_freeze(item->timer);
362 if (ecore_timer_interval_get(item->timer) <= 1.0f)
365 if (gettimeofday(&tv, NULL) < 0) {
366 ErrPrint("gettimeofday: %s\n", strerror(errno));
371 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
372 DbgPrint("Instance %s freeze timer\n", item->inst->item->pkgname);
375 static inline void update_monitor_cnt(struct item *item)
380 now = util_timestamp();
381 interval = now - item->update_interval;
385 * If the content update is processed in too short time,
386 * don't increase the monitor counter, instead of it
387 * set the heavy updating flag.
388 * And handling this heavy updating from the
389 * file update callback.
391 if (interval >= MINIMUM_UPDATE_INTERVAL)
394 item->heavy_updating = 1;
396 item->update_interval = now;
399 static inline Eina_List *find_item(struct instance *inst)
404 EINA_LIST_FOREACH(s_info.item_list, l, item) {
405 if (item->inst == inst)
412 static inline int output_handler(struct item *item)
417 if (item->monitor_cnt < 0 || item->heavy_updating) {
418 if (!item->heavy_updating) {
419 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
422 item->heavy_updating = 0; /* Reset flag */
425 item->monitor_cnt = 0;
428 if (item->monitor_cnt == 0) {
430 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
433 ecore_timer_del(item->monitor);
434 item->monitor = NULL;
437 if (s_info.update == item)
438 s_info.update = NULL;
440 if (item->deleteme) {
441 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
442 (void)so_destroy(item->inst);
451 static int desc_updated_cb(const char *filename, void *data, int over)
456 WarnPrint("Event Q overflow\n");
460 DbgPrint("DESC %s is updated\n", filename);
461 if (item->is_pd_show) {
462 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
464 ErrPrint("But PD is not opened, Ignore this update (%s)\n", item->inst->id);
469 static int file_updated_cb(const char *filename, void *data, int over)
475 char *content = NULL;
480 WarnPrint("Event Q overflow\n");
484 ret = util_get_filesize(filename);
486 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
487 return EXIT_SUCCESS; /*!< To keep the callback */
490 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
492 ErrPrint("livebox_get_info returns %d\n", ret);
493 return EXIT_SUCCESS; /*!< To keep the callback */
496 if (!item->inst->item->has_livebox_script || (item->inst->item->has_livebox_script && item->is_lb_show)) {
497 provider_send_updated(item->inst->item->pkgname, item->inst->id,
498 item->inst->w, item->inst->h, item->inst->priority, content, title);
500 DbgPrint("Livebox script is not ready yet\n");
501 item->is_lb_updated++;
504 return output_handler(item);
507 static inline int clear_from_pd_open_pending_list(struct item *item)
512 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
516 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
517 if (!s_info.pd_open_pending_list)
518 deactivate_pd_open_pending_consumer();
519 return LB_STATUS_SUCCESS;
522 return LB_STATUS_ERROR_NOT_EXIST;
525 static inline int clear_from_pending_list(struct item *item)
530 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
534 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
535 if (!s_info.pending_list)
536 deactivate_pending_consumer();
537 return LB_STATUS_SUCCESS;
540 return LB_STATUS_ERROR_NOT_EXIST;
543 static Eina_Bool update_timeout_cb(void *data)
549 DbgPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
551 if (s_info.update != item)
552 ErrPrint("Updating item is not matched\n");
554 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
555 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
556 s_info.update = NULL;
559 return ECORE_CALLBACK_CANCEL;
562 static Eina_Bool updator_cb(void *data)
569 if (item->monitor) {/*!< If this item is already in update process */
570 return ECORE_CALLBACK_RENEW;
573 ret = so_is_updated(item->inst);
575 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
576 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
577 lb_destroy(item->inst->item->pkgname, item->inst->id);
579 ecore_timer_del(item->timer);
581 return ECORE_CALLBACK_CANCEL;
584 return ECORE_CALLBACK_RENEW;
587 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
588 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
589 (void)append_pending_list(item);
590 return ECORE_CALLBACK_RENEW;
593 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
594 if (!item->monitor) {
595 ErrPrint("Failed to add update monitor %s(%s):%d\n",
596 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
597 return ECORE_CALLBACK_RENEW;
602 * Counter of the event monitor is only used for asynchronous content updating,
603 * So reset it to 1 from here because the async updating is started now,
604 * even if it is accumulated by other event function before this.
606 item->monitor_cnt = 1;
608 s_info.update = item;
610 ret = so_update(item->inst);
614 ecore_timer_del(item->monitor);
615 item->monitor = NULL;
616 s_info.update = NULL;
617 return ECORE_CALLBACK_RENEW;
622 * While waiting the Callback function call,
623 * Add this for finding the crash
625 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
627 if (ret & NEED_TO_SCHEDULE) {
628 (void)append_pending_list(item);
631 if (ret & OUTPUT_UPDATED)
632 update_monitor_cnt(item);
634 return ECORE_CALLBACK_RENEW;
637 static inline void update_monitor_del(const char *id, struct item *item)
642 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
644 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
647 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
651 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
652 update_monitor_del_update_cb(tmp, desc_updated_cb);
656 static inline int add_desc_update_monitor(const char *id, struct item *item)
661 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
662 filename = malloc(len);
664 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
665 return LB_STATUS_ERROR_MEMORY;
668 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
669 DbgPrint("Add DESC monitor: %s\n", filename);
670 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
673 static inline int add_file_update_monitor(const char *id, struct item *item)
677 filename = strdup(util_uri_to_path(id));
679 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
680 return LB_STATUS_ERROR_MEMORY;
683 return update_monitor_add_update_cb(filename, file_updated_cb, item);
686 static inline int update_monitor_add(const char *id, struct item *item)
690 * item->inst is not available yet.
692 add_file_update_monitor(id, item);
693 add_desc_update_monitor(id, item);
694 return LB_STATUS_SUCCESS;
697 HAPI int lb_init(void)
699 return LB_STATUS_SUCCESS;
702 HAPI int lb_fini(void)
708 deactivate_pending_consumer();
709 deactivate_pd_open_pending_consumer();
711 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
712 EINA_LIST_FREE(s_info.pending_list, item);
714 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
715 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
716 lb_destroy(item->inst->item->pkgname, item->inst->id);
719 return LB_STATUS_SUCCESS;
724 * Exported API for each liveboxes.
726 const char *livebox_find_pkgname(const char *filename)
731 EINA_LIST_FOREACH(s_info.item_list, l, item) {
732 if (!strcmp(item->inst->id, filename))
733 return item->inst->item->pkgname;
739 int livebox_request_update_by_id(const char *filename)
744 EINA_LIST_FOREACH(s_info.item_list, l, item) {
745 if (!strcmp(item->inst->id, filename)) {
746 return append_pending_list(item);
750 return LB_STATUS_ERROR_NOT_EXIST;
753 HAPI int lb_open_pd(const char *pkgname)
758 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
759 if (!strcmp(pkgname, tmp))
763 tmp = strdup(pkgname);
765 ErrPrint("Heap: %s\n", strerror(errno));
766 return LB_STATUS_ERROR_MEMORY;
770 pending_timer_freeze();
772 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
775 * Find all instances from the pending list.
776 * Move them to pd_open_pending_timer
778 migrate_to_pd_open_pending_list(pkgname);
779 return LB_STATUS_SUCCESS;
782 HAPI int lb_close_pd(const char *pkgname)
788 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
789 if (strcmp(tmp, pkgname))
792 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
796 pending_timer_thaw();
799 * Move all items in pd_open_pending_list
802 migrate_to_pending_list(pkgname);
803 return LB_STATUS_SUCCESS;
806 return LB_STATUS_ERROR_NOT_EXIST;
809 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)
811 struct instance *inst;
821 inst = so_find_instance(pkgname, id);
823 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
824 return LB_STATUS_SUCCESS;
827 if (!skip_need_to_create) {
828 ret = so_create_needed(pkgname, cluster, category, abi);
829 if (ret != NEED_TO_CREATE)
830 return LB_STATUS_ERROR_PERMISSION;
835 item = calloc(1, sizeof(*item));
837 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
838 return LB_STATUS_ERROR_MEMORY;
841 ret = update_monitor_add(id, item);
847 DbgPrint("Content: [%s]\n", content_info);
848 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
849 if (create_ret < 0) {
850 update_monitor_del(id, item);
861 if (period > 0.0f && !s_info.secured) {
862 item->timer = util_timer_add(period, updator_cb, item);
864 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
865 update_monitor_del(id, item);
866 (void)so_destroy(inst);
868 return LB_STATUS_ERROR_FAULT;
874 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
878 s_info.item_list = eina_list_append(s_info.item_list, item);
880 if (create_ret & NEED_TO_SCHEDULE) {
881 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
882 (void)append_pending_list(item);
885 if (create_ret & OUTPUT_UPDATED) {
886 update_monitor_cnt(item);
889 * To send a output info, get the info forcely.
890 * but the output file monitor will do this again
892 * This function will set the tmp_content and tmp_title
893 * even if it has no updates on the content, title,
894 * it will set them to NULL.
896 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
900 tmp = strdup(*out_content);
902 ErrPrint("Memory: %s\n", strerror(errno));
910 tmp = strdup(*out_title);
912 ErrPrint("Memory: %s\n", strerror(errno));
921 *priority = inst->priority;
922 return need_to_create;
925 HAPI int lb_destroy(const char *pkgname, const char *id)
928 struct instance *inst;
931 inst = so_find_instance(pkgname, id);
933 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
934 return LB_STATUS_ERROR_INVALID;
939 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
940 return LB_STATUS_ERROR_NOT_EXIST;
943 item = eina_list_data_get(l);
944 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
946 if (s_info.update == item)
947 s_info.update = NULL;
950 clear_from_pd_open_pending_list(item);
951 clear_from_pending_list(item);
952 ecore_timer_del(item->timer);
958 update_monitor_del(id, item);
961 if (!item->monitor) {
963 (void)so_destroy(inst);
966 return LB_STATUS_SUCCESS;
969 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
972 struct instance *inst;
976 inst = so_find_instance(pkgname, id);
978 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
979 return LB_STATUS_ERROR_INVALID;
984 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
985 return LB_STATUS_ERROR_NOT_EXIST;
988 item = eina_list_data_get(l);
990 ret = so_resize(inst, w, h);
994 if (ret & NEED_TO_SCHEDULE) {
995 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
996 (void)append_pending_list(item);
999 if (ret & OUTPUT_UPDATED)
1000 update_monitor_cnt(item);
1002 return LB_STATUS_SUCCESS;
1005 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
1007 struct instance *inst;
1010 inst = so_find_instance(pkgname, id);
1012 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
1016 ret = so_pinup(inst, pinup);
1020 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
1023 struct instance *inst;
1026 inst = so_find_instance(pkgname, id);
1028 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
1029 return LB_STATUS_ERROR_INVALID;
1032 l = find_item(inst);
1034 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1035 return LB_STATUS_ERROR_NOT_EXIST;
1038 item = eina_list_data_get(l);
1040 if (period <= 0.0f) {
1042 ecore_timer_del(item->timer);
1047 util_timer_interval_set(item->timer, period);
1048 } else if (!s_info.secured) {
1049 item->timer = util_timer_add(period, updator_cb, item);
1051 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1052 return LB_STATUS_ERROR_FAULT;
1060 return LB_STATUS_SUCCESS;
1063 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1066 struct instance *inst;
1070 inst = so_find_instance(pkgname, id);
1072 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1073 return LB_STATUS_ERROR_INVALID;
1076 l = find_item(inst);
1078 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1079 return LB_STATUS_ERROR_NOT_EXIST;
1082 item = eina_list_data_get(l);
1084 ret = so_clicked(inst, event, timestamp, x, y);
1088 if (ret & NEED_TO_SCHEDULE) {
1089 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1090 (void)append_pending_list(item);
1093 if (ret & OUTPUT_UPDATED)
1094 update_monitor_cnt(item);
1096 return LB_STATUS_SUCCESS;
1099 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1102 struct instance *inst;
1106 inst = so_find_instance(pkgname, id);
1108 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1109 return LB_STATUS_ERROR_INVALID;
1112 l = find_item(inst);
1114 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1115 return LB_STATUS_ERROR_NOT_EXIST;
1118 item = eina_list_data_get(l);
1120 DbgPrint("source(%s) emission(%s) %d\n", source, emission, item->inst->item->has_livebox_script);
1121 if (emission && source && !strcmp(source, util_uri_to_path(id))) {
1122 if (item->inst->item->has_livebox_script) {
1123 if (!strcmp(emission, "lb,show")) {
1124 DbgPrint("Livebox(%s) script is ready now\n", id);
1125 item->is_lb_show = 1;
1127 DbgPrint("Updated %d times, (content: %s), (title: %s)\n", item->is_lb_updated, item->inst->content, item->inst->title);
1128 if (item->is_lb_updated) {
1129 provider_send_updated(item->inst->item->pkgname, item->inst->id,
1130 item->inst->w, item->inst->h, item->inst->priority, item->inst->content, item->inst->title);
1131 item->is_lb_updated = 0;
1133 } else if (!strcmp(emission, "lb,hide")) {
1134 DbgPrint("Livebox(%s) script is hide now\n", id);
1135 item->is_lb_show = 0;
1139 if (!strcmp(emission, "pd,show")) {
1140 item->is_pd_show = 1;
1141 } else if (!strcmp(emission, "pd,hide")) {
1142 item->is_pd_show = 0;
1146 ret = so_script_event(inst, emission, source, event_info);
1150 if (ret & NEED_TO_SCHEDULE) {
1151 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1152 (void)append_pending_list(item);
1155 if (ret & OUTPUT_UPDATED)
1156 update_monitor_cnt(item);
1158 return LB_STATUS_SUCCESS;
1161 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1164 struct instance *inst;
1167 inst = so_find_instance(pkgname, id);
1169 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1170 return LB_STATUS_ERROR_INVALID;
1173 l = find_item(inst);
1175 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1176 return LB_STATUS_ERROR_NOT_EXIST;
1179 item = eina_list_data_get(l);
1181 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1182 return LB_STATUS_ERROR_FAULT;
1187 * Maybe this is not neccessary for this operation
1189 return so_is_pinned_up(inst);
1192 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1195 struct instance *inst;
1199 inst = so_find_instance(pkgname, id);
1201 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1202 return LB_STATUS_ERROR_INVALID;
1205 l = find_item(inst);
1207 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1208 return LB_STATUS_ERROR_NOT_EXIST;
1211 item = eina_list_data_get(l);
1213 ret = so_change_group(inst, cluster, category);
1217 if (ret & NEED_TO_SCHEDULE) {
1218 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1219 (void)append_pending_list(item);
1222 if (ret & OUTPUT_UPDATED)
1223 update_monitor_cnt(item);
1225 return LB_STATUS_SUCCESS;
1228 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1232 ret = so_sys_event(inst, event);
1236 if (ret & NEED_TO_SCHEDULE)
1237 (void)append_pending_list(item);
1239 if (ret & OUTPUT_UPDATED)
1240 update_monitor_cnt(item);
1242 return LB_STATUS_SUCCESS;
1245 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1248 struct instance *inst;
1251 inst = so_find_instance(pkgname, id);
1253 ErrPrint("instance %s - %s is not created\n");
1254 return LB_STATUS_ERROR_INVALID;
1257 l = find_item(inst);
1259 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1260 return LB_STATUS_ERROR_NOT_EXIST;
1263 item = eina_list_data_get(l);
1264 return lb_sys_event(inst, item, event);
1267 HAPI int lb_update(const char *pkgname, const char *id)
1270 struct instance *inst;
1273 inst = so_find_instance(pkgname, id);
1275 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1276 return LB_STATUS_ERROR_INVALID;
1279 l = find_item(inst);
1281 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1282 return LB_STATUS_ERROR_NOT_EXIST;
1285 item = eina_list_data_get(l);
1286 (void)append_pending_list(item);
1287 return LB_STATUS_SUCCESS;
1290 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1296 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1297 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1301 if (cluster && strcasecmp(item->inst->cluster, cluster))
1304 if (category && strcasecmp(item->inst->category, category))
1307 if (pkgname && strlen(pkgname)) {
1308 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1309 (void)append_pending_list(item);
1312 (void)append_pending_list(item);
1316 return LB_STATUS_SUCCESS;
1319 HAPI int lb_delete_all_deleteme(void)
1326 DbgPrint("Delete all deleteme\n");
1327 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1328 if (!item->deleteme)
1331 s_info.item_list = eina_list_remove(s_info.item_list, item);
1333 update_monitor_del(item->inst->id, item);
1334 (void)so_destroy(item->inst);
1339 DbgPrint("Deleteme: %d\n", cnt);
1340 return LB_STATUS_SUCCESS;
1343 HAPI int lb_system_event_all(int event)
1349 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1353 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1354 lb_sys_event(item->inst, item, event);
1357 return LB_STATUS_SUCCESS;
1360 HAPI void lb_pause_all(void)
1367 pending_timer_freeze();
1369 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1370 if (item->deleteme) {
1371 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1375 if (item->is_paused) {
1376 DbgPrint("Instance %s is already paused\n", item->inst->id);
1382 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1386 HAPI void lb_resume_all(void)
1393 pending_timer_thaw();
1395 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1396 if (item->deleteme) {
1397 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1401 if (item->is_paused) {
1402 DbgPrint("Instance %s is still paused\n", item->inst->id);
1408 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1412 HAPI int lb_pause(const char *pkgname, const char *id)
1414 struct instance *inst;
1418 inst = so_find_instance(pkgname, id);
1420 return LB_STATUS_ERROR_INVALID;
1422 l = find_item(inst);
1424 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1425 return LB_STATUS_ERROR_NOT_EXIST;
1428 item = eina_list_data_get(l);
1430 return LB_STATUS_ERROR_FAULT;
1432 if (item->deleteme) {
1433 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1434 return LB_STATUS_ERROR_BUSY;
1437 item->is_paused = 1;
1439 if (s_info.paused) {
1440 DbgPrint("Already paused: %s\n", item->inst->id);
1441 return LB_STATUS_SUCCESS;
1446 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1448 return LB_STATUS_SUCCESS;
1451 HAPI int lb_resume(const char *pkgname, const char *id)
1453 struct instance *inst;
1457 inst = so_find_instance(pkgname, id);
1459 return LB_STATUS_ERROR_INVALID;
1461 l = find_item(inst);
1463 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1464 return LB_STATUS_ERROR_NOT_EXIST;
1467 item = eina_list_data_get(l);
1469 return LB_STATUS_ERROR_FAULT;
1471 if (item->deleteme) {
1472 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1473 return LB_STATUS_ERROR_BUSY;
1476 item->is_paused = 0;
1478 if (s_info.paused) {
1479 DbgPrint("Instance %s is still paused\n", item->inst->id);
1480 return LB_STATUS_SUCCESS;
1485 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1486 return LB_STATUS_SUCCESS;
1489 HAPI void lb_turn_secured_on(void)
1494 HAPI int lb_is_all_paused(void)
1496 return s_info.paused;