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 */
62 Eina_List *pending_list;
63 Ecore_Timer *pending_timer;
64 Eina_List *pd_open_pending_list;
65 Ecore_Timer *pd_open_pending_timer;
69 int pending_timer_freezed;
74 .pending_timer = NULL,
75 .pd_open_pending_list = NULL,
76 .pd_open_pending_timer = NULL,
80 .pending_timer_freezed = 0,
83 static Eina_Bool updator_cb(void *data);
85 static void pending_timer_freeze(void)
87 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
88 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
89 DbgPrint("Freeze the pending timer\n");
90 ecore_timer_freeze(s_info.pending_timer);
93 s_info.pending_timer_freezed++;
96 static void pending_timer_thaw(void)
98 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
99 if (!s_info.pending_timer_freezed)
102 s_info.pending_timer_freezed--;
103 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
104 DbgPrint("Thaw the pending timer\n");
105 ecore_timer_thaw(s_info.pending_timer);
110 * -1 : PD is opened, but not mine
111 * 0 : PD is not opened
112 * 1 : my PD is opened
114 static inline int pd_is_opened(const char *pkgname)
121 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
122 if (pkgname && !strcmp(pkgname, tmp))
128 return i > 0 ? -1 : 0;
131 static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
135 item = eina_list_nth(s_info.pd_open_pending_list, 0);
140 return ECORE_CALLBACK_RENEW;
142 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
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 return ECORE_CALLBACK_CANCEL;
156 static Eina_Bool pended_cmd_consumer_cb(void *data)
160 item = eina_list_nth(s_info.pending_list, 0);
164 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
165 return ECORE_CALLBACK_RENEW;
167 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
170 * To prevent from checking the is_updated function
172 (void)updator_cb(item);
173 if (s_info.pending_list)
174 return ECORE_CALLBACK_RENEW;
177 s_info.pending_timer = NULL;
178 s_info.pending_timer_freezed = 0;
179 return ECORE_CALLBACK_CANCEL;
182 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
184 if (s_info.pending_timer)
187 s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
188 if (!s_info.pending_timer) {
189 ErrPrint("Failed to add a new pended command consumer\n");
190 return LB_STATUS_ERROR_FAULT;
194 * Do not increase the freezed counter.
195 * Just freeze the timer.
197 if (s_info.pending_timer_freezed)
198 ecore_timer_freeze(s_info.pending_timer);
203 static inline void deactivate_pending_consumer(void)
205 if (!s_info.pending_timer)
208 ecore_timer_del(s_info.pending_timer);
209 s_info.pending_timer = NULL;
210 s_info.pending_timer_freezed = 0;
213 static inline void deactivate_pd_open_pending_consumer(void)
215 if (!s_info.pd_open_pending_timer)
218 ecore_timer_del(s_info.pd_open_pending_timer);
219 s_info.pd_open_pending_timer = NULL;
222 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
224 if (s_info.pd_open_pending_timer)
227 s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
228 if (!s_info.pd_open_pending_timer) {
229 ErrPrint("Failed to add a new pended command consumer\n");
230 return LB_STATUS_ERROR_FAULT;
236 static inline void migrate_to_pd_open_pending_list(const char *pkgname)
243 EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
244 if (strcmp(pkgname, item->inst->item->pkgname))
247 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
248 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
252 if (s_info.pd_open_pending_list)
253 activate_pd_open_pending_consumer();
255 if (!s_info.pending_list)
256 deactivate_pending_consumer();
259 static inline void migrate_to_pending_list(const char *pkgname)
266 EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
267 if (strcmp(pkgname, item->inst->item->pkgname))
270 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
271 s_info.pending_list = eina_list_append(s_info.pending_list, item);
275 if (s_info.pending_list)
276 activate_pending_consumer();
278 if (!s_info.pd_open_pending_list)
279 deactivate_pd_open_pending_consumer();
282 static inline int append_pending_list(struct item *item)
284 if (pd_is_opened(item->inst->item->pkgname) == 1) {
285 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
286 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
287 return LB_STATUS_ERROR_EXIST;
290 if (activate_pd_open_pending_consumer() < 0) {
291 ErrPrint("Failed to activate PD open pending consumer\n");
292 return LB_STATUS_ERROR_FAULT;
295 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
297 if (eina_list_data_find(s_info.pending_list, item) == item) {
298 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
299 return LB_STATUS_ERROR_EXIST;
302 if (activate_pending_consumer() < 0)
303 return LB_STATUS_ERROR_FAULT;
305 s_info.pending_list = eina_list_append(s_info.pending_list, item);
310 static inline void timer_thaw(struct item *item)
320 ecore_timer_thaw(item->timer);
321 period = ecore_timer_interval_get(item->timer);
322 pending = ecore_timer_pending_get(item->timer);
323 delay = util_time_delay_for_compensation(period) - pending;
324 ecore_timer_delay(item->timer, delay);
326 if (item->sleep_at == 0.0f)
329 sleep_time = util_timestamp() - item->sleep_at;
330 if (sleep_time > pending)
331 (void)updator_cb(item);
333 item->sleep_at = 0.0f;
336 static inline void timer_freeze(struct item *item)
343 ecore_timer_freeze(item->timer);
345 if (ecore_timer_interval_get(item->timer) <= 1.0f)
348 if (gettimeofday(&tv, NULL) < 0) {
349 ErrPrint("gettimeofday: %s\n", strerror(errno));
354 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
357 static inline void update_monitor_cnt(struct item *item)
362 now = util_timestamp();
363 interval = now - item->update_interval;
367 * If the content update is processed in too short time,
368 * don't increase the monitor counter, instead of it
369 * set the heavy updating flag.
370 * And handling this heavy updating from the
371 * file update callback.
373 if (interval >= MINIMUM_UPDATE_INTERVAL) {
374 if (s_info.update == item) {
377 * If already in updating mode,
378 * reset the monitor_cnt to 1,
379 * all updated event will be merged into A inotify event
381 DbgPrint("While waiting updated event, content is updated [%s]\n", item->inst->id);
382 item->monitor_cnt = 1;
387 item->heavy_updating = 1;
390 item->update_interval = now;
393 static inline Eina_List *find_item(struct instance *inst)
398 EINA_LIST_FOREACH(s_info.item_list, l, item) {
399 if (item->inst == inst)
406 static inline int output_handler(struct item *item)
411 if (item->monitor_cnt < 0 || item->heavy_updating) {
412 if (!item->heavy_updating) {
413 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
416 item->heavy_updating = 0; /* Reset flag */
419 item->monitor_cnt = 0;
422 if (item->monitor_cnt == 0) {
424 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
427 ecore_timer_del(item->monitor);
428 item->monitor = NULL;
431 if (s_info.update == item)
432 s_info.update = NULL;
434 if (item->deleteme) {
435 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
436 (void)so_destroy(item->inst);
445 static int desc_updated_cb(const char *filename, void *data, int over)
450 WarnPrint("Event Q overflow\n");
454 DbgPrint("DESC %s is updated\n", filename);
455 if (item->is_pd_show) {
456 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
458 ErrPrint("But PD is not opened, Ignore this update (%s)\n", item->inst->id);
463 static int file_updated_cb(const char *filename, void *data, int over)
469 char *content = NULL;
474 WarnPrint("Event Q overflow\n");
478 ret = util_get_filesize(filename);
480 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
481 return EXIT_SUCCESS; /*!< To keep the callback */
484 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
486 ErrPrint("livebox_get_info returns %d\n", ret);
487 return EXIT_SUCCESS; /*!< To keep the callback */
490 if (IS_LB_SHOWN(item)) {
491 provider_send_updated(item->inst->item->pkgname, item->inst->id,
492 item->inst->w, item->inst->h, item->inst->priority, content, title);
494 item->is_lb_updated++;
497 return output_handler(item);
500 static inline int clear_from_pd_open_pending_list(struct item *item)
505 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
509 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
510 if (!s_info.pd_open_pending_list)
511 deactivate_pd_open_pending_consumer();
512 return LB_STATUS_SUCCESS;
515 return LB_STATUS_ERROR_NOT_EXIST;
518 static inline int clear_from_pending_list(struct item *item)
523 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
527 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
528 if (!s_info.pending_list)
529 deactivate_pending_consumer();
530 return LB_STATUS_SUCCESS;
533 return LB_STATUS_ERROR_NOT_EXIST;
536 static Eina_Bool update_timeout_cb(void *data)
542 ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
544 if (s_info.update != item)
545 ErrPrint("Updating item is not matched\n");
547 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
548 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
549 s_info.update = NULL;
552 return ECORE_CALLBACK_CANCEL;
555 static Eina_Bool updator_cb(void *data)
562 if (item->monitor) {/*!< If this item is already in update process */
563 return ECORE_CALLBACK_RENEW;
566 if (!IS_LB_SHOWN(item)) {
567 DbgPrint("%s is not shown yet. delaying updates\n", item->inst->item->pkgname);
568 (void)append_pending_list(item);
569 return ECORE_CALLBACK_RENEW;
572 ret = so_is_updated(item->inst);
574 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
575 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
576 lb_destroy(item->inst->item->pkgname, item->inst->id);
578 ecore_timer_del(item->timer);
580 return ECORE_CALLBACK_CANCEL;
583 return ECORE_CALLBACK_RENEW;
586 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
587 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
588 (void)append_pending_list(item);
589 return ECORE_CALLBACK_RENEW;
592 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
593 if (!item->monitor) {
594 ErrPrint("Failed to add update monitor %s(%s):%d\n",
595 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
596 return ECORE_CALLBACK_RENEW;
599 ret = so_update(item->inst);
601 ecore_timer_del(item->monitor);
602 item->monitor = NULL;
603 return ECORE_CALLBACK_RENEW;
608 * Counter of the event monitor is only used for asynchronous content updating,
609 * So reset it to 1 from here because the async updating is started now,
610 * even if it is accumulated by other event function before this.
612 item->monitor_cnt = 1;
616 * While waiting the Callback function call,
617 * Add this for finding the crash
619 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
621 if (ret & NEED_TO_SCHEDULE)
622 (void)append_pending_list(item);
624 if (ret & OUTPUT_UPDATED) {
627 * In this case, there is potential issue
628 * 1. User added update CALLBACK -> Inotify event (Only once)
629 * > We have to detect this case. Is it possible to be a user callback called faster than inotify event handler?
630 * 2. Inotify event -> User added update CALLBACK -> Inotify event
631 * > Okay. What we want is this.
633 update_monitor_cnt(item);
638 * This should be updated after "update_monitor_cnt" function call,
639 * because the update_monitor_cnt function will see the s_info.update variable,
641 s_info.update = item;
643 return ECORE_CALLBACK_RENEW;
646 static inline void update_monitor_del(const char *id, struct item *item)
651 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
653 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
656 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
660 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
661 update_monitor_del_update_cb(tmp, desc_updated_cb);
665 static inline int add_desc_update_monitor(const char *id, struct item *item)
670 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
671 filename = malloc(len);
673 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
674 return LB_STATUS_ERROR_MEMORY;
677 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
678 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
681 static inline int add_file_update_monitor(const char *id, struct item *item)
685 filename = strdup(util_uri_to_path(id));
687 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
688 return LB_STATUS_ERROR_MEMORY;
691 return update_monitor_add_update_cb(filename, file_updated_cb, item);
694 static inline int update_monitor_add(const char *id, struct item *item)
698 * item->inst is not available yet.
700 add_file_update_monitor(id, item);
701 add_desc_update_monitor(id, item);
702 return LB_STATUS_SUCCESS;
705 HAPI int lb_init(void)
707 return LB_STATUS_SUCCESS;
710 HAPI int lb_fini(void)
716 deactivate_pending_consumer();
717 deactivate_pd_open_pending_consumer();
719 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
720 EINA_LIST_FREE(s_info.pending_list, item);
722 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
723 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
724 lb_destroy(item->inst->item->pkgname, item->inst->id);
727 return LB_STATUS_SUCCESS;
732 * Exported API for each liveboxes.
734 const char *livebox_find_pkgname(const char *filename)
739 EINA_LIST_FOREACH(s_info.item_list, l, item) {
740 if (!strcmp(item->inst->id, filename))
741 return item->inst->item->pkgname;
747 int livebox_request_update_by_id(const char *filename)
752 if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
753 ErrPrint("Current operation: %d\n", so_current_op());
754 return LB_STATUS_ERROR_INVALID;
757 EINA_LIST_FOREACH(s_info.item_list, l, item) {
758 if (!strcmp(item->inst->id, filename)) {
759 return append_pending_list(item);
763 return LB_STATUS_ERROR_NOT_EXIST;
766 int livebox_trigger_update_monitor(const char *filename, int is_pd)
771 if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
772 ErrPrint("Current operation: %d\n", so_current_op());
773 return LB_STATUS_ERROR_INVALID;
778 len = strlen(filename) + strlen(".desc");
780 fname = malloc(len + 1);
782 ErrPrint("Heap: %s\n", strerror(errno));
783 return LB_STATUS_ERROR_MEMORY;
786 snprintf(fname, len, "%s.desc", filename);
788 fname = strdup(filename);
790 ErrPrint("Heap: %s\n", strerror(errno));
791 return LB_STATUS_ERROR_MEMORY;
795 if (access(fname, R_OK | W_OK) != 0) {
796 ErrPrint("access: %s (%s)\n", fname, strerror(errno));
797 ret = LB_STATUS_ERROR_IO;
799 ret = update_monitor_trigger_update_cb(fname, 0);
806 HAPI int lb_open_pd(const char *pkgname)
811 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
812 if (!strcmp(pkgname, tmp))
816 tmp = strdup(pkgname);
818 ErrPrint("Heap: %s\n", strerror(errno));
819 return LB_STATUS_ERROR_MEMORY;
823 pending_timer_freeze();
825 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
828 * Find all instances from the pending list.
829 * Move them to pd_open_pending_timer
831 migrate_to_pd_open_pending_list(pkgname);
832 return LB_STATUS_SUCCESS;
835 HAPI int lb_close_pd(const char *pkgname)
841 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
842 if (strcmp(tmp, pkgname))
845 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
849 pending_timer_thaw();
852 * Move all items in pd_open_pending_list
855 migrate_to_pending_list(pkgname);
856 return LB_STATUS_SUCCESS;
859 return LB_STATUS_ERROR_NOT_EXIST;
862 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)
864 struct instance *inst;
874 inst = so_find_instance(pkgname, id);
876 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
877 return LB_STATUS_SUCCESS;
880 if (!skip_need_to_create) {
881 ret = so_create_needed(pkgname, cluster, category, abi);
882 if (ret != NEED_TO_CREATE)
883 return LB_STATUS_ERROR_PERMISSION;
888 item = calloc(1, sizeof(*item));
890 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
891 return LB_STATUS_ERROR_MEMORY;
894 ret = update_monitor_add(id, item);
900 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
901 if (create_ret < 0) {
902 update_monitor_del(id, item);
913 if (period > 0.0f && !s_info.secured) {
914 item->timer = util_timer_add(period, updator_cb, item);
916 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
917 update_monitor_del(id, item);
918 (void)so_destroy(inst);
920 return LB_STATUS_ERROR_FAULT;
926 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
930 s_info.item_list = eina_list_append(s_info.item_list, item);
932 if (create_ret & NEED_TO_SCHEDULE) {
933 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
934 (void)append_pending_list(item);
937 if (create_ret & OUTPUT_UPDATED) {
938 update_monitor_cnt(item);
941 * To send a output info, get the info forcely.
942 * but the output file monitor will do this again
944 * This function will set the tmp_content and tmp_title
945 * even if it has no updates on the content, title,
946 * it will set them to NULL.
948 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
952 tmp = strdup(*out_content);
954 ErrPrint("Memory: %s\n", strerror(errno));
962 tmp = strdup(*out_title);
964 ErrPrint("Memory: %s\n", strerror(errno));
973 *priority = inst->priority;
974 return need_to_create;
977 HAPI int lb_destroy(const char *pkgname, const char *id)
980 struct instance *inst;
983 inst = so_find_instance(pkgname, id);
985 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
986 return LB_STATUS_ERROR_INVALID;
991 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
992 return LB_STATUS_ERROR_NOT_EXIST;
995 item = eina_list_data_get(l);
996 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
998 if (s_info.update == item)
999 s_info.update = NULL;
1002 clear_from_pd_open_pending_list(item);
1003 clear_from_pending_list(item);
1004 ecore_timer_del(item->timer);
1010 update_monitor_del(id, item);
1013 if (!item->monitor) {
1015 (void)so_destroy(inst);
1018 return LB_STATUS_SUCCESS;
1021 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
1024 struct instance *inst;
1028 inst = so_find_instance(pkgname, id);
1030 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
1031 return LB_STATUS_ERROR_INVALID;
1034 l = find_item(inst);
1036 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
1037 return LB_STATUS_ERROR_NOT_EXIST;
1040 item = eina_list_data_get(l);
1042 ret = so_resize(inst, w, h);
1046 if (ret & NEED_TO_SCHEDULE) {
1047 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1048 (void)append_pending_list(item);
1051 if (ret & OUTPUT_UPDATED)
1052 update_monitor_cnt(item);
1054 return LB_STATUS_SUCCESS;
1057 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
1059 struct instance *inst;
1062 inst = so_find_instance(pkgname, id);
1064 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
1068 ret = so_pinup(inst, pinup);
1072 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
1075 struct instance *inst;
1078 inst = so_find_instance(pkgname, id);
1080 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
1081 return LB_STATUS_ERROR_INVALID;
1084 l = find_item(inst);
1086 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1087 return LB_STATUS_ERROR_NOT_EXIST;
1090 item = eina_list_data_get(l);
1092 if (period <= 0.0f) {
1094 ecore_timer_del(item->timer);
1099 util_timer_interval_set(item->timer, period);
1100 } else if (!s_info.secured) {
1101 item->timer = util_timer_add(period, updator_cb, item);
1103 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1104 return LB_STATUS_ERROR_FAULT;
1112 return LB_STATUS_SUCCESS;
1115 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1118 struct instance *inst;
1122 inst = so_find_instance(pkgname, id);
1124 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1125 return LB_STATUS_ERROR_INVALID;
1128 l = find_item(inst);
1130 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1131 return LB_STATUS_ERROR_NOT_EXIST;
1134 item = eina_list_data_get(l);
1136 ret = so_clicked(inst, event, timestamp, x, y);
1140 if (ret & NEED_TO_SCHEDULE) {
1141 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1142 (void)append_pending_list(item);
1145 if (ret & OUTPUT_UPDATED)
1146 update_monitor_cnt(item);
1148 return LB_STATUS_SUCCESS;
1151 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1154 struct instance *inst;
1158 inst = so_find_instance(pkgname, id);
1160 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1161 return LB_STATUS_ERROR_INVALID;
1164 l = find_item(inst);
1166 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1167 return LB_STATUS_ERROR_NOT_EXIST;
1170 item = eina_list_data_get(l);
1172 if (emission && source && !strcmp(source, id)) {
1173 if (item->inst->item->has_livebox_script) {
1174 if (!strcmp(emission, "lb,show")) {
1175 item->is_lb_show = 1;
1177 DbgPrint("[%s] Updated %d times, (content: %s), (title: %s)\n", id, item->is_lb_updated, item->inst->content, item->inst->title);
1178 if (item->is_lb_updated) {
1179 provider_send_updated(item->inst->item->pkgname, item->inst->id,
1180 item->inst->w, item->inst->h, item->inst->priority, item->inst->content, item->inst->title);
1181 item->is_lb_updated = 0;
1184 source = util_uri_to_path(source);
1185 } else if (!strcmp(emission, "lb,hide")) {
1186 DbgPrint("Livebox(%s) script is hide now\n", id);
1187 item->is_lb_show = 0;
1189 source = util_uri_to_path(source);
1193 if (!strcmp(emission, "pd,show")) {
1194 item->is_pd_show = 1;
1195 source = util_uri_to_path(source);
1196 } else if (!strcmp(emission, "pd,hide")) {
1197 item->is_pd_show = 0;
1198 source = util_uri_to_path(source);
1202 ret = so_script_event(inst, emission, source, event_info);
1206 if (ret & NEED_TO_SCHEDULE) {
1207 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1208 (void)append_pending_list(item);
1211 if (ret & OUTPUT_UPDATED)
1212 update_monitor_cnt(item);
1214 return LB_STATUS_SUCCESS;
1217 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1220 struct instance *inst;
1223 inst = so_find_instance(pkgname, id);
1225 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1226 return LB_STATUS_ERROR_INVALID;
1229 l = find_item(inst);
1231 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1232 return LB_STATUS_ERROR_NOT_EXIST;
1235 item = eina_list_data_get(l);
1237 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1238 return LB_STATUS_ERROR_FAULT;
1243 * Maybe this is not neccessary for this operation
1245 return so_is_pinned_up(inst);
1248 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1251 struct instance *inst;
1255 inst = so_find_instance(pkgname, id);
1257 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1258 return LB_STATUS_ERROR_INVALID;
1261 l = find_item(inst);
1263 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1264 return LB_STATUS_ERROR_NOT_EXIST;
1267 item = eina_list_data_get(l);
1269 ret = so_change_group(inst, cluster, category);
1273 if (ret & NEED_TO_SCHEDULE) {
1274 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1275 (void)append_pending_list(item);
1278 if (ret & OUTPUT_UPDATED)
1279 update_monitor_cnt(item);
1281 return LB_STATUS_SUCCESS;
1284 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1288 ret = so_sys_event(inst, event);
1292 if (ret & NEED_TO_SCHEDULE)
1293 (void)append_pending_list(item);
1295 if (ret & OUTPUT_UPDATED)
1296 update_monitor_cnt(item);
1298 return LB_STATUS_SUCCESS;
1301 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1304 struct instance *inst;
1307 inst = so_find_instance(pkgname, id);
1309 ErrPrint("instance %s - %s is not created\n");
1310 return LB_STATUS_ERROR_INVALID;
1313 l = find_item(inst);
1315 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1316 return LB_STATUS_ERROR_NOT_EXIST;
1319 item = eina_list_data_get(l);
1320 return lb_sys_event(inst, item, event);
1323 HAPI int lb_update(const char *pkgname, const char *id)
1326 struct instance *inst;
1329 inst = so_find_instance(pkgname, id);
1331 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1332 return LB_STATUS_ERROR_INVALID;
1335 l = find_item(inst);
1337 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1338 return LB_STATUS_ERROR_NOT_EXIST;
1341 item = eina_list_data_get(l);
1342 (void)append_pending_list(item);
1343 return LB_STATUS_SUCCESS;
1346 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1352 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1353 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1357 if (cluster && strcasecmp(item->inst->cluster, cluster))
1360 if (category && strcasecmp(item->inst->category, category))
1363 if (pkgname && strlen(pkgname)) {
1364 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1365 (void)append_pending_list(item);
1368 (void)append_pending_list(item);
1372 return LB_STATUS_SUCCESS;
1375 HAPI int lb_delete_all_deleteme(void)
1382 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1383 if (!item->deleteme)
1386 s_info.item_list = eina_list_remove(s_info.item_list, item);
1388 update_monitor_del(item->inst->id, item);
1389 (void)so_destroy(item->inst);
1394 DbgPrint("Delete all deleteme: %d\n", cnt);
1395 return LB_STATUS_SUCCESS;
1398 HAPI int lb_system_event_all(int event)
1404 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1408 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1409 lb_sys_event(item->inst, item, event);
1412 return LB_STATUS_SUCCESS;
1415 HAPI void lb_pause_all(void)
1422 pending_timer_freeze();
1424 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1425 if (item->deleteme) {
1426 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1430 if (item->is_paused)
1435 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1439 HAPI void lb_resume_all(void)
1446 pending_timer_thaw();
1448 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1449 if (item->deleteme) {
1450 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1454 if (item->is_paused)
1459 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1463 HAPI int lb_pause(const char *pkgname, const char *id)
1465 struct instance *inst;
1469 inst = so_find_instance(pkgname, id);
1471 return LB_STATUS_ERROR_INVALID;
1473 l = find_item(inst);
1475 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1476 return LB_STATUS_ERROR_NOT_EXIST;
1479 item = eina_list_data_get(l);
1481 return LB_STATUS_ERROR_FAULT;
1483 if (item->deleteme) {
1484 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1485 return LB_STATUS_ERROR_BUSY;
1488 item->is_paused = 1;
1491 return LB_STATUS_SUCCESS;
1495 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1497 return LB_STATUS_SUCCESS;
1500 HAPI int lb_resume(const char *pkgname, const char *id)
1502 struct instance *inst;
1506 inst = so_find_instance(pkgname, id);
1508 return LB_STATUS_ERROR_INVALID;
1510 l = find_item(inst);
1512 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1513 return LB_STATUS_ERROR_NOT_EXIST;
1516 item = eina_list_data_get(l);
1518 return LB_STATUS_ERROR_FAULT;
1520 if (item->deleteme) {
1521 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1522 return LB_STATUS_ERROR_BUSY;
1525 item->is_paused = 0;
1528 return LB_STATUS_SUCCESS;
1532 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1533 return LB_STATUS_SUCCESS;
1536 HAPI void lb_turn_secured_on(void)
1541 HAPI int lb_is_all_paused(void)
1543 return s_info.paused;