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 is_pended_item(struct item *item)
284 struct item *in_item;
285 if (pd_is_opened(item->inst->item->pkgname) == 1) {
286 in_item = eina_list_data_find(s_info.pd_open_pending_list, item);
288 in_item = eina_list_data_find(s_info.pending_list, item);
291 return (in_item == item);
294 static inline int append_pending_list(struct item *item)
296 if (pd_is_opened(item->inst->item->pkgname) == 1) {
297 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
298 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
299 return LB_STATUS_ERROR_EXIST;
302 if (activate_pd_open_pending_consumer() < 0) {
303 ErrPrint("Failed to activate PD open pending consumer\n");
304 return LB_STATUS_ERROR_FAULT;
307 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
309 if (eina_list_data_find(s_info.pending_list, item) == item) {
310 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
311 return LB_STATUS_ERROR_EXIST;
314 if (activate_pending_consumer() < 0)
315 return LB_STATUS_ERROR_FAULT;
317 s_info.pending_list = eina_list_append(s_info.pending_list, item);
322 static inline void timer_thaw(struct item *item)
332 ecore_timer_thaw(item->timer);
333 period = ecore_timer_interval_get(item->timer);
334 pending = ecore_timer_pending_get(item->timer);
335 delay = util_time_delay_for_compensation(period) - pending;
336 ecore_timer_delay(item->timer, delay);
338 if (item->sleep_at == 0.0f)
341 sleep_time = util_timestamp() - item->sleep_at;
342 if (sleep_time > pending)
343 (void)updator_cb(item);
345 item->sleep_at = 0.0f;
348 static inline void timer_freeze(struct item *item)
355 ecore_timer_freeze(item->timer);
357 if (ecore_timer_interval_get(item->timer) <= 1.0f)
360 if (gettimeofday(&tv, NULL) < 0) {
361 ErrPrint("gettimeofday: %s\n", strerror(errno));
366 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
369 static inline void update_monitor_cnt(struct item *item)
374 now = util_timestamp();
375 interval = now - item->update_interval;
379 * If the content update is processed in too short time,
380 * don't increase the monitor counter, instead of it
381 * set the heavy updating flag.
382 * And handling this heavy updating from the
383 * file update callback.
385 if (interval >= MINIMUM_UPDATE_INTERVAL) {
386 if (s_info.update == item) {
389 * If already in updating mode,
390 * reset the monitor_cnt to 1,
391 * all updated event will be merged into A inotify event
393 DbgPrint("While waiting updated event, content is updated [%s]\n", item->inst->id);
394 item->monitor_cnt = 1;
399 item->heavy_updating = 1;
402 item->update_interval = now;
405 static inline Eina_List *find_item(struct instance *inst)
410 EINA_LIST_FOREACH(s_info.item_list, l, item) {
411 if (item->inst == inst)
418 static inline int output_handler(struct item *item)
423 if (item->monitor_cnt < 0 || item->heavy_updating) {
424 if (!item->heavy_updating) {
425 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
428 item->heavy_updating = 0; /* Reset flag */
431 item->monitor_cnt = 0;
434 if (item->monitor_cnt == 0) {
436 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
439 ecore_timer_del(item->monitor);
440 item->monitor = NULL;
443 if (s_info.update == item)
444 s_info.update = NULL;
446 if (item->deleteme) {
447 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
448 (void)so_destroy(item->inst);
457 static int desc_updated_cb(const char *filename, void *data, int over)
462 WarnPrint("Event Q overflow\n");
466 DbgPrint("DESC %s is updated\n", filename);
467 if (item->is_pd_show) {
468 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
470 ErrPrint("But PD is not opened, Ignore this update (%s)\n", item->inst->id);
475 static int file_updated_cb(const char *filename, void *data, int over)
481 char *content = NULL;
486 WarnPrint("Event Q overflow\n");
490 ret = util_get_filesize(filename);
492 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
493 return EXIT_SUCCESS; /*!< To keep the callback */
496 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
498 ErrPrint("livebox_get_info returns %d\n", ret);
499 return EXIT_SUCCESS; /*!< To keep the callback */
502 if (IS_LB_SHOWN(item)) {
503 provider_send_updated(item->inst->item->pkgname, item->inst->id,
504 item->inst->w, item->inst->h, item->inst->priority,
507 item->is_lb_updated++;
510 return output_handler(item);
513 static void reset_lb_updated_flag(struct item *item)
515 if (!item->is_lb_updated)
518 DbgPrint("[%s] Updated %d times, (content: %s), (title: %s)\n",
519 item->inst->id, item->is_lb_updated,
520 item->inst->content, item->inst->title);
522 provider_send_updated(item->inst->item->pkgname, item->inst->id,
523 item->inst->w, item->inst->h, item->inst->priority,
524 item->inst->content, item->inst->title);
526 item->is_lb_updated = 0;
529 static inline int clear_from_pd_open_pending_list(struct item *item)
534 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
538 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
539 if (!s_info.pd_open_pending_list)
540 deactivate_pd_open_pending_consumer();
541 return LB_STATUS_SUCCESS;
544 return LB_STATUS_ERROR_NOT_EXIST;
547 static inline int clear_from_pending_list(struct item *item)
552 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
556 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
557 if (!s_info.pending_list)
558 deactivate_pending_consumer();
559 return LB_STATUS_SUCCESS;
562 return LB_STATUS_ERROR_NOT_EXIST;
565 static Eina_Bool update_timeout_cb(void *data)
571 ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
573 if (s_info.update != item)
574 ErrPrint("Updating item is not matched\n");
576 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
577 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
578 s_info.update = NULL;
581 return ECORE_CALLBACK_CANCEL;
584 static Eina_Bool updator_cb(void *data)
591 if (item->monitor) {/*!< If this item is already in update process */
592 return ECORE_CALLBACK_RENEW;
595 if (!IS_LB_SHOWN(item)) {
596 DbgPrint("%s is not shown yet. delaying updates\n", item->inst->item->pkgname);
597 (void)append_pending_list(item);
598 return ECORE_CALLBACK_RENEW;
601 ret = so_is_updated(item->inst);
603 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
604 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
605 lb_destroy(item->inst->item->pkgname, item->inst->id);
607 ecore_timer_del(item->timer);
609 return ECORE_CALLBACK_CANCEL;
612 reset_lb_updated_flag(item);
613 return ECORE_CALLBACK_RENEW;
616 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
617 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
618 (void)append_pending_list(item);
619 return ECORE_CALLBACK_RENEW;
622 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
623 if (!item->monitor) {
624 ErrPrint("Failed to add update monitor %s(%s):%d\n",
625 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
626 return ECORE_CALLBACK_RENEW;
629 ret = so_update(item->inst);
631 ecore_timer_del(item->monitor);
632 item->monitor = NULL;
633 reset_lb_updated_flag(item);
634 return ECORE_CALLBACK_RENEW;
639 * Counter of the event monitor is only used for asynchronous content updating,
640 * So reset it to 1 from here because the async updating is started now,
641 * even if it is accumulated by other event function before this.
643 item->monitor_cnt = 1;
647 * While waiting the Callback function call,
648 * Add this for finding the crash
650 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
652 if (ret & NEED_TO_SCHEDULE)
653 (void)append_pending_list(item);
655 if (ret & OUTPUT_UPDATED) {
658 * In this case, there is potential issue
659 * 1. User added update CALLBACK -> Inotify event (Only once)
660 * > We have to detect this case. Is it possible to be a user callback called faster than inotify event handler?
661 * 2. Inotify event -> User added update CALLBACK -> Inotify event
662 * > Okay. What we want is this.
664 update_monitor_cnt(item);
669 * This should be updated after "update_monitor_cnt" function call,
670 * because the update_monitor_cnt function will see the s_info.update variable,
672 s_info.update = item;
674 return ECORE_CALLBACK_RENEW;
677 static inline void update_monitor_del(const char *id, struct item *item)
682 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
684 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
687 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
691 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
692 update_monitor_del_update_cb(tmp, desc_updated_cb);
696 static inline int add_desc_update_monitor(const char *id, struct item *item)
701 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
702 filename = malloc(len);
704 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
705 return LB_STATUS_ERROR_MEMORY;
708 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
709 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
712 static inline int add_file_update_monitor(const char *id, struct item *item)
716 filename = strdup(util_uri_to_path(id));
718 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
719 return LB_STATUS_ERROR_MEMORY;
722 return update_monitor_add_update_cb(filename, file_updated_cb, item);
725 static inline int update_monitor_add(const char *id, struct item *item)
729 * item->inst is not available yet.
731 add_file_update_monitor(id, item);
732 add_desc_update_monitor(id, item);
733 return LB_STATUS_SUCCESS;
736 HAPI int lb_init(void)
738 return LB_STATUS_SUCCESS;
741 HAPI int lb_fini(void)
747 deactivate_pending_consumer();
748 deactivate_pd_open_pending_consumer();
750 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
751 EINA_LIST_FREE(s_info.pending_list, item);
753 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
754 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
755 lb_destroy(item->inst->item->pkgname, item->inst->id);
758 return LB_STATUS_SUCCESS;
763 * Exported API for each liveboxes.
765 const char *livebox_find_pkgname(const char *filename)
770 EINA_LIST_FOREACH(s_info.item_list, l, item) {
771 if (!strcmp(item->inst->id, filename))
772 return item->inst->item->pkgname;
778 int livebox_request_update_by_id(const char *filename)
783 if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
784 ErrPrint("Current operation: %d\n", so_current_op());
785 return LB_STATUS_ERROR_INVALID;
788 EINA_LIST_FOREACH(s_info.item_list, l, item) {
789 if (!strcmp(item->inst->id, filename)) {
790 return append_pending_list(item);
794 return LB_STATUS_ERROR_NOT_EXIST;
797 int livebox_trigger_update_monitor(const char *filename, int is_pd)
802 if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
803 ErrPrint("Current operation: %d\n", so_current_op());
804 return LB_STATUS_ERROR_INVALID;
809 len = strlen(filename) + strlen(".desc");
811 fname = malloc(len + 1);
813 ErrPrint("Heap: %s\n", strerror(errno));
814 return LB_STATUS_ERROR_MEMORY;
817 snprintf(fname, len, "%s.desc", filename);
819 fname = strdup(filename);
821 ErrPrint("Heap: %s\n", strerror(errno));
822 return LB_STATUS_ERROR_MEMORY;
826 if (access(fname, R_OK | W_OK) != 0) {
827 ErrPrint("access: %s (%s)\n", fname, strerror(errno));
828 ret = LB_STATUS_ERROR_IO;
830 ret = update_monitor_trigger_update_cb(fname, 0);
837 HAPI int lb_open_pd(const char *pkgname)
842 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
843 if (!strcmp(pkgname, tmp))
847 tmp = strdup(pkgname);
849 ErrPrint("Heap: %s\n", strerror(errno));
850 return LB_STATUS_ERROR_MEMORY;
854 pending_timer_freeze();
856 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
859 * Find all instances from the pending list.
860 * Move them to pd_open_pending_timer
862 migrate_to_pd_open_pending_list(pkgname);
863 return LB_STATUS_SUCCESS;
866 HAPI int lb_close_pd(const char *pkgname)
872 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
873 if (strcmp(tmp, pkgname))
876 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
880 pending_timer_thaw();
883 * Move all items in pd_open_pending_list
886 migrate_to_pending_list(pkgname);
887 return LB_STATUS_SUCCESS;
890 return LB_STATUS_ERROR_NOT_EXIST;
893 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)
895 struct instance *inst;
905 inst = so_find_instance(pkgname, id);
907 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
908 return LB_STATUS_SUCCESS;
911 if (!skip_need_to_create) {
912 ret = so_create_needed(pkgname, cluster, category, abi);
913 if (ret != NEED_TO_CREATE)
914 return LB_STATUS_ERROR_PERMISSION;
919 item = calloc(1, sizeof(*item));
921 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
922 return LB_STATUS_ERROR_MEMORY;
925 ret = update_monitor_add(id, item);
931 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
932 if (create_ret < 0) {
933 update_monitor_del(id, item);
944 if (period > 0.0f && !s_info.secured) {
945 item->timer = util_timer_add(period, updator_cb, item);
947 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
948 update_monitor_del(id, item);
949 (void)so_destroy(inst);
951 return LB_STATUS_ERROR_FAULT;
957 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
961 s_info.item_list = eina_list_append(s_info.item_list, item);
963 if (create_ret & NEED_TO_SCHEDULE) {
964 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
965 (void)append_pending_list(item);
968 if (create_ret & OUTPUT_UPDATED) {
969 update_monitor_cnt(item);
972 * To send a output info, get the info forcely.
973 * but the output file monitor will do this again
975 * This function will set the tmp_content and tmp_title
976 * even if it has no updates on the content, title,
977 * it will set them to NULL.
979 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
983 tmp = strdup(*out_content);
985 ErrPrint("Memory: %s\n", strerror(errno));
993 tmp = strdup(*out_title);
995 ErrPrint("Memory: %s\n", strerror(errno));
1004 *priority = inst->priority;
1005 return need_to_create;
1008 HAPI int lb_destroy(const char *pkgname, const char *id)
1011 struct instance *inst;
1014 inst = so_find_instance(pkgname, id);
1016 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1017 return LB_STATUS_ERROR_INVALID;
1020 l = find_item(inst);
1022 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1023 return LB_STATUS_ERROR_NOT_EXIST;
1026 item = eina_list_data_get(l);
1027 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
1029 if (s_info.update == item)
1030 s_info.update = NULL;
1033 clear_from_pd_open_pending_list(item);
1034 clear_from_pending_list(item);
1035 ecore_timer_del(item->timer);
1041 update_monitor_del(id, item);
1044 if (!item->monitor) {
1046 (void)so_destroy(inst);
1049 return LB_STATUS_SUCCESS;
1052 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
1055 struct instance *inst;
1059 inst = so_find_instance(pkgname, id);
1061 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
1062 return LB_STATUS_ERROR_INVALID;
1065 l = find_item(inst);
1067 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
1068 return LB_STATUS_ERROR_NOT_EXIST;
1071 item = eina_list_data_get(l);
1073 ret = so_resize(inst, w, h);
1077 if (ret & NEED_TO_SCHEDULE) {
1078 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1079 (void)append_pending_list(item);
1082 if (ret & OUTPUT_UPDATED)
1083 update_monitor_cnt(item);
1085 return LB_STATUS_SUCCESS;
1088 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
1090 struct instance *inst;
1093 inst = so_find_instance(pkgname, id);
1095 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
1099 ret = so_pinup(inst, pinup);
1103 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
1106 struct instance *inst;
1109 inst = so_find_instance(pkgname, id);
1111 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
1112 return LB_STATUS_ERROR_INVALID;
1115 l = find_item(inst);
1117 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1118 return LB_STATUS_ERROR_NOT_EXIST;
1121 item = eina_list_data_get(l);
1123 if (period <= 0.0f) {
1125 ecore_timer_del(item->timer);
1130 util_timer_interval_set(item->timer, period);
1131 } else if (!s_info.secured) {
1132 item->timer = util_timer_add(period, updator_cb, item);
1134 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1135 return LB_STATUS_ERROR_FAULT;
1143 return LB_STATUS_SUCCESS;
1146 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1149 struct instance *inst;
1153 inst = so_find_instance(pkgname, id);
1155 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1156 return LB_STATUS_ERROR_INVALID;
1159 l = find_item(inst);
1161 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1162 return LB_STATUS_ERROR_NOT_EXIST;
1165 item = eina_list_data_get(l);
1167 ret = so_clicked(inst, event, timestamp, x, y);
1171 if (ret & NEED_TO_SCHEDULE) {
1172 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1173 (void)append_pending_list(item);
1176 if (ret & OUTPUT_UPDATED)
1177 update_monitor_cnt(item);
1179 return LB_STATUS_SUCCESS;
1182 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1185 struct instance *inst;
1189 inst = so_find_instance(pkgname, id);
1191 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1192 return LB_STATUS_ERROR_INVALID;
1195 l = find_item(inst);
1197 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1198 return LB_STATUS_ERROR_NOT_EXIST;
1201 item = eina_list_data_get(l);
1203 if (emission && source && !strcmp(source, id)) {
1204 if (item->inst->item->has_livebox_script) {
1205 if (!strcmp(emission, "lb,show")) {
1206 item->is_lb_show = 1;
1208 if (item->is_lb_updated && !is_pended_item(item))
1209 reset_lb_updated_flag(item);
1211 source = util_uri_to_path(source);
1212 } else if (!strcmp(emission, "lb,hide")) {
1213 DbgPrint("Livebox(%s) script is hide now\n", id);
1214 item->is_lb_show = 0;
1216 source = util_uri_to_path(source);
1220 if (!strcmp(emission, "pd,show")) {
1221 item->is_pd_show = 1;
1222 source = util_uri_to_path(source);
1223 } else if (!strcmp(emission, "pd,hide")) {
1224 item->is_pd_show = 0;
1225 source = util_uri_to_path(source);
1229 ret = so_script_event(inst, emission, source, event_info);
1233 if (ret & NEED_TO_SCHEDULE) {
1234 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1235 (void)append_pending_list(item);
1238 if (ret & OUTPUT_UPDATED)
1239 update_monitor_cnt(item);
1241 return LB_STATUS_SUCCESS;
1244 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1247 struct instance *inst;
1250 inst = so_find_instance(pkgname, id);
1252 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1253 return LB_STATUS_ERROR_INVALID;
1256 l = find_item(inst);
1258 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1259 return LB_STATUS_ERROR_NOT_EXIST;
1262 item = eina_list_data_get(l);
1264 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1265 return LB_STATUS_ERROR_FAULT;
1270 * Maybe this is not neccessary for this operation
1272 return so_is_pinned_up(inst);
1275 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1278 struct instance *inst;
1282 inst = so_find_instance(pkgname, id);
1284 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1285 return LB_STATUS_ERROR_INVALID;
1288 l = find_item(inst);
1290 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1291 return LB_STATUS_ERROR_NOT_EXIST;
1294 item = eina_list_data_get(l);
1296 ret = so_change_group(inst, cluster, category);
1300 if (ret & NEED_TO_SCHEDULE) {
1301 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1302 (void)append_pending_list(item);
1305 if (ret & OUTPUT_UPDATED)
1306 update_monitor_cnt(item);
1308 return LB_STATUS_SUCCESS;
1311 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1315 ret = so_sys_event(inst, event);
1319 if (ret & NEED_TO_SCHEDULE)
1320 (void)append_pending_list(item);
1322 if (ret & OUTPUT_UPDATED)
1323 update_monitor_cnt(item);
1325 return LB_STATUS_SUCCESS;
1328 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1331 struct instance *inst;
1334 inst = so_find_instance(pkgname, id);
1336 ErrPrint("instance %s - %s is not created\n");
1337 return LB_STATUS_ERROR_INVALID;
1340 l = find_item(inst);
1342 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1343 return LB_STATUS_ERROR_NOT_EXIST;
1346 item = eina_list_data_get(l);
1347 return lb_sys_event(inst, item, event);
1350 HAPI int lb_update(const char *pkgname, const char *id)
1353 struct instance *inst;
1356 inst = so_find_instance(pkgname, id);
1358 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1359 return LB_STATUS_ERROR_INVALID;
1362 l = find_item(inst);
1364 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1365 return LB_STATUS_ERROR_NOT_EXIST;
1368 item = eina_list_data_get(l);
1369 (void)append_pending_list(item);
1370 return LB_STATUS_SUCCESS;
1373 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1379 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1380 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1384 if (cluster && strcasecmp(item->inst->cluster, cluster))
1387 if (category && strcasecmp(item->inst->category, category))
1390 if (pkgname && strlen(pkgname)) {
1391 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1392 (void)append_pending_list(item);
1395 (void)append_pending_list(item);
1399 return LB_STATUS_SUCCESS;
1402 HAPI int lb_delete_all_deleteme(void)
1409 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1410 if (!item->deleteme)
1413 s_info.item_list = eina_list_remove(s_info.item_list, item);
1415 update_monitor_del(item->inst->id, item);
1416 (void)so_destroy(item->inst);
1421 DbgPrint("Delete all deleteme: %d\n", cnt);
1422 return LB_STATUS_SUCCESS;
1425 HAPI int lb_system_event_all(int event)
1431 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1435 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1436 lb_sys_event(item->inst, item, event);
1439 return LB_STATUS_SUCCESS;
1442 HAPI void lb_pause_all(void)
1449 pending_timer_freeze();
1451 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1452 if (item->deleteme) {
1453 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1457 if (item->is_paused)
1462 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1466 HAPI void lb_resume_all(void)
1473 pending_timer_thaw();
1475 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1476 if (item->deleteme) {
1477 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1481 if (item->is_paused)
1486 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1490 HAPI int lb_pause(const char *pkgname, const char *id)
1492 struct instance *inst;
1496 inst = so_find_instance(pkgname, id);
1498 return LB_STATUS_ERROR_INVALID;
1500 l = find_item(inst);
1502 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1503 return LB_STATUS_ERROR_NOT_EXIST;
1506 item = eina_list_data_get(l);
1508 return LB_STATUS_ERROR_FAULT;
1510 if (item->deleteme) {
1511 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1512 return LB_STATUS_ERROR_BUSY;
1515 item->is_paused = 1;
1518 return LB_STATUS_SUCCESS;
1522 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1524 return LB_STATUS_SUCCESS;
1527 HAPI int lb_resume(const char *pkgname, const char *id)
1529 struct instance *inst;
1533 inst = so_find_instance(pkgname, id);
1535 return LB_STATUS_ERROR_INVALID;
1537 l = find_item(inst);
1539 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1540 return LB_STATUS_ERROR_NOT_EXIST;
1543 item = eina_list_data_get(l);
1545 return LB_STATUS_ERROR_FAULT;
1547 if (item->deleteme) {
1548 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1549 return LB_STATUS_ERROR_BUSY;
1552 item->is_paused = 0;
1555 return LB_STATUS_SUCCESS;
1559 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1560 return LB_STATUS_SUCCESS;
1563 HAPI void lb_turn_secured_on(void)
1568 HAPI int lb_is_all_paused(void)
1570 return s_info.paused;