2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (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
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 */
55 Eina_List *pending_list;
56 Ecore_Timer *pending_timer;
57 Eina_List *pd_open_pending_list;
58 Ecore_Timer *pd_open_pending_timer;
62 int pending_timer_freezed;
67 .pending_timer = NULL,
68 .pd_open_pending_list = NULL,
69 .pd_open_pending_timer = NULL,
73 .pending_timer_freezed = 0,
76 static Eina_Bool updator_cb(void *data);
78 static void pending_timer_freeze(void)
80 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
81 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
82 DbgPrint("Freeze the pending timer\n");
83 ecore_timer_freeze(s_info.pending_timer);
86 s_info.pending_timer_freezed++;
89 static void pending_timer_thaw(void)
91 DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
92 if (!s_info.pending_timer_freezed)
95 s_info.pending_timer_freezed--;
96 if (s_info.pending_timer && !s_info.pending_timer_freezed) {
97 DbgPrint("Thaw the pending timer\n");
98 ecore_timer_thaw(s_info.pending_timer);
103 * -1 : PD is opened, but not mine
104 * 0 : PD is not opened
105 * 1 : my PD is opened
107 static inline int pd_is_opened(const char *pkgname)
114 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
115 if (pkgname && !strcmp(pkgname, tmp)) {
116 DbgPrint("PD(%s) is opened\n", pkgname);
123 return i > 0 ? -1 : 0;
126 static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
130 item = eina_list_nth(s_info.pd_open_pending_list, 0);
135 return ECORE_CALLBACK_RENEW;
137 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
138 DbgPrint("Consuming pended item: %s\n", item->inst->id);
141 * To prevent from checking the is_updated function
143 (void)updator_cb(item);
144 if (s_info.pd_open_pending_list)
145 return ECORE_CALLBACK_RENEW;
148 s_info.pd_open_pending_timer = NULL;
149 DbgPrint("open pd pending list exhausted\n");
150 return ECORE_CALLBACK_CANCEL;
153 static Eina_Bool pended_cmd_consumer_cb(void *data)
157 item = eina_list_nth(s_info.pending_list, 0);
161 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
162 return ECORE_CALLBACK_RENEW;
164 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
165 DbgPrint("Consuming pended item: %s\n", item->inst->id);
168 * To prevent from checking the is_updated function
170 (void)updator_cb(item);
171 if (s_info.pending_list)
172 return ECORE_CALLBACK_RENEW;
175 s_info.pending_timer = NULL;
176 s_info.pending_timer_freezed = 0;
177 DbgPrint("pending list exhausted\n");
178 return ECORE_CALLBACK_CANCEL;
181 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
183 if (s_info.pending_timer)
186 s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
187 if (!s_info.pending_timer) {
188 ErrPrint("Failed to add a new pended command consumer\n");
189 return LB_STATUS_ERROR_FAULT;
193 * Do not increase the freezed counter.
194 * Just freeze the timer.
196 if (s_info.pending_timer_freezed) {
197 DbgPrint("Pending timer created and freezed\n");
198 ecore_timer_freeze(s_info.pending_timer);
204 static inline void deactivate_pending_consumer(void)
206 if (!s_info.pending_timer)
209 ecore_timer_del(s_info.pending_timer);
210 s_info.pending_timer = NULL;
211 s_info.pending_timer_freezed = 0;
212 DbgPrint("Clear the pending timer\n");
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;
222 DbgPrint("Clear the open_pd_pending timer\n");
225 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
227 if (s_info.pd_open_pending_timer)
230 s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
231 if (!s_info.pd_open_pending_timer) {
232 ErrPrint("Failed to add a new pended command consumer\n");
233 return LB_STATUS_ERROR_FAULT;
239 static inline void migrate_to_pd_open_pending_list(const char *pkgname)
246 EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
247 if (strcmp(pkgname, item->inst->item->pkgname))
250 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
251 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
255 if (s_info.pd_open_pending_list) {
256 DbgPrint("Activate PD open pending consumer (%s)\n", pkgname);
257 activate_pd_open_pending_consumer();
260 if (!s_info.pending_list)
261 deactivate_pending_consumer();
263 DbgPrint("%d items are migrated\n", cnt);
266 static inline void migrate_to_pending_list(const char *pkgname)
273 EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
274 if (strcmp(pkgname, item->inst->item->pkgname))
277 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
278 s_info.pending_list = eina_list_append(s_info.pending_list, item);
282 if (s_info.pending_list)
283 activate_pending_consumer();
285 if (!s_info.pd_open_pending_list)
286 deactivate_pd_open_pending_consumer();
288 DbgPrint("%d items are migrated\n", cnt);
291 static inline int append_pending_list(struct item *item)
293 if (pd_is_opened(item->inst->item->pkgname) == 1) {
294 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
295 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
296 return LB_STATUS_ERROR_EXIST;
299 DbgPrint("Activate PD open pending consumer (%s)\n", item->inst->item->pkgname);
300 if (activate_pd_open_pending_consumer() < 0) {
301 ErrPrint("Failed to activate PD open pending consumer\n");
302 return LB_STATUS_ERROR_FAULT;
305 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
307 if (eina_list_data_find(s_info.pending_list, item) == item) {
308 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
309 return LB_STATUS_ERROR_EXIST;
312 if (activate_pending_consumer() < 0)
313 return LB_STATUS_ERROR_FAULT;
315 s_info.pending_list = eina_list_append(s_info.pending_list, item);
320 static inline void timer_thaw(struct item *item)
327 ecore_timer_thaw(item->timer);
328 period = ecore_timer_interval_get(item->timer);
329 pending = ecore_timer_pending_get(item->timer);
330 delay = util_time_delay_for_compensation(period) - pending;
331 ecore_timer_delay(item->timer, delay);
332 DbgPrint("Compensated: %lf\n", delay);
334 if (item->sleep_at == 0.0f)
337 sleep_time = util_timestamp() - item->sleep_at;
338 if (sleep_time > pending) {
339 DbgPrint("Update time elapsed\n");
340 (void)updator_cb(item);
343 item->sleep_at = 0.0f;
346 static inline void timer_freeze(struct item *item)
349 ecore_timer_freeze(item->timer);
351 if (ecore_timer_interval_get(item->timer) <= 1.0f)
354 gettimeofday(&tv, NULL);
355 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
358 static inline void update_monitor_cnt(struct item *item)
363 now = util_timestamp();
364 interval = now - item->update_interval;
368 * If the content update is processed in too short time,
369 * don't increase the monitor counter, instead of it
370 * set the heavy updating flag.
371 * And handling this heavy updating from the
372 * file update callback.
374 if (interval >= MINIMUM_UPDATE_INTERVAL)
377 item->heavy_updating = 1;
379 item->update_interval = now;
382 static inline Eina_List *find_item(struct instance *inst)
387 EINA_LIST_FOREACH(s_info.item_list, l, item) {
388 if (item->inst == inst)
395 static inline int output_handler(struct item *item)
400 if (item->monitor_cnt < 0 || item->heavy_updating) {
401 if (!item->heavy_updating) {
402 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
405 item->heavy_updating = 0; /* Reset flag */
408 item->monitor_cnt = 0;
411 if (item->monitor_cnt == 0) {
413 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
416 ecore_timer_del(item->monitor);
417 item->monitor = NULL;
420 if (s_info.update == item)
421 s_info.update = NULL;
423 if (item->deleteme) {
424 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
425 (void)so_destroy(item->inst);
434 static int desc_updated_cb(const char *filename, void *data, int over)
439 WarnPrint("Event Q overflow\n");
443 DbgPrint("DESC %s is updated\n", filename);
444 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
448 static int file_updated_cb(const char *filename, void *data, int over)
454 char *content = NULL;
459 WarnPrint("Event Q overflow\n");
463 ret = util_get_filesize(filename);
465 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
466 return EXIT_SUCCESS; /*!< To keep the callback */
469 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
471 ErrPrint("livebox_get_info returns %d\n", ret);
472 return EXIT_SUCCESS; /*!< To keep the callback */
475 provider_send_updated(item->inst->item->pkgname, item->inst->id,
476 item->inst->w, item->inst->h, item->inst->priority, content, title);
478 return output_handler(item);
481 static inline int clear_from_pd_open_pending_list(struct item *item)
486 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
490 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
491 if (!s_info.pd_open_pending_list)
492 deactivate_pd_open_pending_consumer();
493 return LB_STATUS_SUCCESS;
496 return LB_STATUS_ERROR_NOT_EXIST;
499 static inline int clear_from_pending_list(struct item *item)
504 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
508 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
509 if (!s_info.pending_list)
510 deactivate_pending_consumer();
511 return LB_STATUS_SUCCESS;
514 return LB_STATUS_ERROR_NOT_EXIST;
517 static Eina_Bool update_timeout_cb(void *data)
523 DbgPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
525 if (s_info.update != item)
526 ErrPrint("Updating item is not matched\n");
528 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
529 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
530 s_info.update = NULL;
533 return ECORE_CALLBACK_CANCEL;
536 static Eina_Bool updator_cb(void *data)
543 if (item->monitor) {/*!< If this item is already in update process */
544 return ECORE_CALLBACK_RENEW;
547 ret = so_is_updated(item->inst);
549 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
550 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
551 lb_destroy(item->inst->item->pkgname, item->inst->id);
553 ecore_timer_del(item->timer);
555 return ECORE_CALLBACK_CANCEL;
558 return ECORE_CALLBACK_RENEW;
561 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
562 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
563 (void)append_pending_list(item);
564 return ECORE_CALLBACK_RENEW;
567 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
568 if (!item->monitor) {
569 ErrPrint("Failed to add update monitor %s(%s):%d\n",
570 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
571 return ECORE_CALLBACK_RENEW;
576 * Counter of the event monitor is only used for asynchronous content updating,
577 * So reset it to 1 from here because the async updating is started now,
578 * even if it is accumulated by other event function before this.
580 item->monitor_cnt = 1;
582 s_info.update = item;
584 ret = so_update(item->inst);
588 ecore_timer_del(item->monitor);
589 item->monitor = NULL;
590 s_info.update = NULL;
591 return ECORE_CALLBACK_RENEW;
596 * While waiting the Callback function call,
597 * Add this for finding the crash
599 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
601 if (ret & NEED_TO_SCHEDULE) {
602 (void)append_pending_list(item);
605 if (ret & OUTPUT_UPDATED)
606 update_monitor_cnt(item);
608 return ECORE_CALLBACK_RENEW;
611 static inline void update_monitor_del(const char *id, struct item *item)
616 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
618 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
621 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
625 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
626 update_monitor_del_update_cb(tmp, desc_updated_cb);
630 static inline int add_desc_update_monitor(const char *id, struct item *item)
635 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
636 filename = malloc(len);
638 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
639 return LB_STATUS_ERROR_MEMORY;
642 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
643 DbgPrint("Add DESC monitor: %s\n", filename);
644 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
647 static inline int add_file_update_monitor(const char *id, struct item *item)
651 filename = strdup(util_uri_to_path(id));
653 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
654 return LB_STATUS_ERROR_MEMORY;
657 return update_monitor_add_update_cb(filename, file_updated_cb, item);
660 static inline int update_monitor_add(const char *id, struct item *item)
664 * item->inst is not available yet.
666 add_file_update_monitor(id, item);
667 add_desc_update_monitor(id, item);
668 return LB_STATUS_SUCCESS;
671 HAPI int lb_init(void)
673 return LB_STATUS_SUCCESS;
676 HAPI int lb_fini(void)
682 deactivate_pending_consumer();
683 deactivate_pd_open_pending_consumer();
685 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
686 EINA_LIST_FREE(s_info.pending_list, item);
688 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
689 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
690 lb_destroy(item->inst->item->pkgname, item->inst->id);
693 return LB_STATUS_SUCCESS;
698 * Exported API for each liveboxes.
700 const char *livebox_find_pkgname(const char *filename)
705 EINA_LIST_FOREACH(s_info.item_list, l, item) {
706 if (!strcmp(item->inst->id, filename))
707 return item->inst->item->pkgname;
713 int livebox_request_update_by_id(const char *filename)
718 EINA_LIST_FOREACH(s_info.item_list, l, item) {
719 if (!strcmp(item->inst->id, filename)) {
720 return append_pending_list(item);
724 return LB_STATUS_ERROR_NOT_EXIST;
727 HAPI int lb_open_pd(const char *pkgname)
732 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
733 if (!strcmp(pkgname, tmp))
737 tmp = strdup(pkgname);
739 ErrPrint("Heap: %s\n", strerror(errno));
740 return LB_STATUS_ERROR_MEMORY;
744 pending_timer_freeze();
746 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
749 * Find all instances from the pending list.
750 * Move them to pd_open_pending_timer
752 migrate_to_pd_open_pending_list(pkgname);
753 return LB_STATUS_SUCCESS;
756 HAPI int lb_close_pd(const char *pkgname)
762 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
763 if (strcmp(tmp, pkgname))
766 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
770 pending_timer_thaw();
773 * Move all items in pd_open_pending_list
776 migrate_to_pending_list(pkgname);
777 return LB_STATUS_SUCCESS;
780 return LB_STATUS_ERROR_NOT_EXIST;
783 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)
785 struct instance *inst;
795 inst = so_find_instance(pkgname, id);
797 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
798 return LB_STATUS_SUCCESS;
801 if (!skip_need_to_create) {
802 ret = so_create_needed(pkgname, cluster, category, abi);
803 if (ret != NEED_TO_CREATE)
804 return LB_STATUS_ERROR_PERMISSION;
809 item = calloc(1, sizeof(*item));
811 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
812 return LB_STATUS_ERROR_MEMORY;
815 ret = update_monitor_add(id, item);
821 DbgPrint("Content: [%s]\n", content_info);
822 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
823 if (create_ret < 0) {
824 update_monitor_del(id, item);
835 if (period > 0.0f && !s_info.secured) {
836 item->timer = util_timer_add(period, updator_cb, item);
838 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
839 update_monitor_del(id, item);
842 return LB_STATUS_ERROR_FAULT;
848 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
852 s_info.item_list = eina_list_append(s_info.item_list, item);
854 if (create_ret & NEED_TO_SCHEDULE) {
855 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
856 (void)append_pending_list(item);
859 if (create_ret & OUTPUT_UPDATED) {
860 update_monitor_cnt(item);
863 * To send a output info, get the info forcely.
864 * but the output file monitor will do this again
866 * This function will set the tmp_content and tmp_title
867 * even if it has no updates on the content, title,
868 * it will set them to NULL.
870 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
874 tmp = strdup(*out_content);
876 ErrPrint("Memory: %s\n", strerror(errno));
884 tmp = strdup(*out_title);
886 ErrPrint("Memory: %s\n", strerror(errno));
895 *priority = inst->priority;
896 return need_to_create;
899 HAPI int lb_destroy(const char *pkgname, const char *id)
902 struct instance *inst;
905 inst = so_find_instance(pkgname, id);
907 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
908 return LB_STATUS_ERROR_INVALID;
913 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
914 return LB_STATUS_ERROR_NOT_EXIST;
917 item = eina_list_data_get(l);
918 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
920 if (s_info.update == item)
921 s_info.update = NULL;
924 clear_from_pd_open_pending_list(item);
925 clear_from_pending_list(item);
926 ecore_timer_del(item->timer);
932 update_monitor_del(id, item);
935 if (!item->monitor) {
937 (void)so_destroy(inst);
940 return LB_STATUS_SUCCESS;
943 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
946 struct instance *inst;
950 inst = so_find_instance(pkgname, id);
952 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
953 return LB_STATUS_ERROR_INVALID;
958 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
959 return LB_STATUS_ERROR_NOT_EXIST;
962 item = eina_list_data_get(l);
964 ret = so_resize(inst, w, h);
968 if (ret & NEED_TO_SCHEDULE) {
969 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
970 (void)append_pending_list(item);
973 if (ret & OUTPUT_UPDATED)
974 update_monitor_cnt(item);
976 return LB_STATUS_SUCCESS;
979 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
981 struct instance *inst;
984 inst = so_find_instance(pkgname, id);
986 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
990 ret = so_pinup(inst, pinup);
994 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
997 struct instance *inst;
1000 inst = so_find_instance(pkgname, id);
1002 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
1003 return LB_STATUS_ERROR_INVALID;
1006 l = find_item(inst);
1008 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1009 return LB_STATUS_ERROR_NOT_EXIST;
1012 item = eina_list_data_get(l);
1014 if (period <= 0.0f) {
1016 ecore_timer_del(item->timer);
1021 util_timer_interval_set(item->timer, period);
1022 } else if (!s_info.secured) {
1023 item->timer = util_timer_add(period, updator_cb, item);
1025 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1026 return LB_STATUS_ERROR_FAULT;
1034 return LB_STATUS_SUCCESS;
1037 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1040 struct instance *inst;
1044 inst = so_find_instance(pkgname, id);
1046 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1047 return LB_STATUS_ERROR_INVALID;
1050 l = find_item(inst);
1052 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1053 return LB_STATUS_ERROR_NOT_EXIST;
1056 item = eina_list_data_get(l);
1058 ret = so_clicked(inst, event, timestamp, x, y);
1062 if (ret & NEED_TO_SCHEDULE) {
1063 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1064 (void)append_pending_list(item);
1067 if (ret & OUTPUT_UPDATED)
1068 update_monitor_cnt(item);
1070 return LB_STATUS_SUCCESS;
1073 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1076 struct instance *inst;
1080 inst = so_find_instance(pkgname, id);
1082 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1083 return LB_STATUS_ERROR_INVALID;
1086 l = find_item(inst);
1088 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1089 return LB_STATUS_ERROR_NOT_EXIST;
1092 item = eina_list_data_get(l);
1094 ret = so_script_event(inst, emission, source, event_info);
1098 if (ret & NEED_TO_SCHEDULE) {
1099 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1100 (void)append_pending_list(item);
1103 if (ret & OUTPUT_UPDATED)
1104 update_monitor_cnt(item);
1106 return LB_STATUS_SUCCESS;
1109 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1112 struct instance *inst;
1115 inst = so_find_instance(pkgname, id);
1117 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1118 return LB_STATUS_ERROR_INVALID;
1121 l = find_item(inst);
1123 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1124 return LB_STATUS_ERROR_NOT_EXIST;
1127 item = eina_list_data_get(l);
1129 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1130 return LB_STATUS_ERROR_FAULT;
1135 * Maybe this is not neccessary for this operation
1137 return so_is_pinned_up(inst);
1140 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1143 struct instance *inst;
1147 inst = so_find_instance(pkgname, id);
1149 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1150 return LB_STATUS_ERROR_INVALID;
1153 l = find_item(inst);
1155 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1156 return LB_STATUS_ERROR_NOT_EXIST;
1159 item = eina_list_data_get(l);
1161 ret = so_change_group(inst, cluster, category);
1165 if (ret & NEED_TO_SCHEDULE) {
1166 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1167 (void)append_pending_list(item);
1170 if (ret & OUTPUT_UPDATED)
1171 update_monitor_cnt(item);
1173 return LB_STATUS_SUCCESS;
1176 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1180 ret = so_sys_event(inst, event);
1184 if (ret & NEED_TO_SCHEDULE)
1185 (void)append_pending_list(item);
1187 if (ret & OUTPUT_UPDATED)
1188 update_monitor_cnt(item);
1190 return LB_STATUS_SUCCESS;
1193 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1196 struct instance *inst;
1199 inst = so_find_instance(pkgname, id);
1201 ErrPrint("instance %s - %s is not created\n");
1202 return LB_STATUS_ERROR_INVALID;
1205 l = find_item(inst);
1207 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1208 return LB_STATUS_ERROR_NOT_EXIST;
1211 item = eina_list_data_get(l);
1212 return lb_sys_event(inst, item, event);
1215 HAPI int lb_update(const char *pkgname, const char *id)
1218 struct instance *inst;
1221 inst = so_find_instance(pkgname, id);
1223 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1224 return LB_STATUS_ERROR_INVALID;
1227 l = find_item(inst);
1229 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1230 return LB_STATUS_ERROR_NOT_EXIST;
1233 item = eina_list_data_get(l);
1234 (void)append_pending_list(item);
1235 return LB_STATUS_SUCCESS;
1238 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1244 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1245 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1249 if (cluster && strcasecmp(item->inst->cluster, cluster))
1252 if (category && strcasecmp(item->inst->category, category))
1255 if (pkgname && strlen(pkgname)) {
1256 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1257 (void)append_pending_list(item);
1260 (void)append_pending_list(item);
1264 return LB_STATUS_SUCCESS;
1267 HAPI int lb_system_event_all(int event)
1273 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1277 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1278 lb_sys_event(item->inst, item, event);
1281 return LB_STATUS_SUCCESS;
1284 HAPI void lb_pause_all(void)
1291 pending_timer_freeze();
1293 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1294 if (item->deleteme) {
1295 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1299 if (item->is_paused) {
1300 DbgPrint("Instance %s is already paused\n", item->inst->id);
1305 DbgPrint("Instance %s freeze timer\n", item->inst->item->pkgname);
1308 DbgPrint("Instance %s has no timer\n", item->inst->item->pkgname);
1311 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1315 HAPI void lb_resume_all(void)
1322 pending_timer_thaw();
1324 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1325 if (item->deleteme) {
1326 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1330 if (item->is_paused) {
1331 DbgPrint("Instance %s is still paused\n", item->inst->id);
1336 DbgPrint("Instance %s resume timer\n", item->inst->item->pkgname);
1340 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1344 HAPI int lb_pause(const char *pkgname, const char *id)
1346 struct instance *inst;
1350 inst = so_find_instance(pkgname, id);
1352 return LB_STATUS_ERROR_INVALID;
1354 l = find_item(inst);
1356 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1357 return LB_STATUS_ERROR_NOT_EXIST;
1360 item = eina_list_data_get(l);
1362 return LB_STATUS_ERROR_FAULT;
1364 if (item->deleteme) {
1365 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1366 return LB_STATUS_ERROR_BUSY;
1369 item->is_paused = 1;
1371 if (s_info.paused) {
1372 DbgPrint("Already paused: %s\n", item->inst->id);
1373 return LB_STATUS_SUCCESS;
1379 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1381 return LB_STATUS_SUCCESS;
1384 HAPI int lb_resume(const char *pkgname, const char *id)
1386 struct instance *inst;
1390 inst = so_find_instance(pkgname, id);
1392 return LB_STATUS_ERROR_INVALID;
1394 l = find_item(inst);
1396 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1397 return LB_STATUS_ERROR_NOT_EXIST;
1400 item = eina_list_data_get(l);
1402 return LB_STATUS_ERROR_FAULT;
1404 if (item->deleteme) {
1405 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1406 return LB_STATUS_ERROR_BUSY;
1409 item->is_paused = 0;
1411 if (s_info.paused) {
1412 DbgPrint("Instance %s is still paused\n", item->inst->id);
1413 return LB_STATUS_SUCCESS;
1419 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1420 return LB_STATUS_SUCCESS;
1423 HAPI void lb_turn_secured_on(void)