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://www.tizenopensource.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 */
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))
121 return i > 0 ? -1 : 0;
124 static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
128 item = eina_list_nth(s_info.pd_open_pending_list, 0);
133 return ECORE_CALLBACK_RENEW;
135 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
136 DbgPrint("Consuming pended item: %s\n", item->inst->id);
139 * To prevent from checking the is_updated function
141 (void)updator_cb(item);
142 if (s_info.pd_open_pending_list)
143 return ECORE_CALLBACK_RENEW;
146 s_info.pd_open_pending_timer = NULL;
147 DbgPrint("open pd pending list exhausted\n");
148 return ECORE_CALLBACK_CANCEL;
151 static Eina_Bool pended_cmd_consumer_cb(void *data)
155 item = eina_list_nth(s_info.pending_list, 0);
159 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
160 return ECORE_CALLBACK_RENEW;
162 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
163 DbgPrint("Consuming pended item: %s\n", item->inst->id);
166 * To prevent from checking the is_updated function
168 (void)updator_cb(item);
169 if (s_info.pending_list)
170 return ECORE_CALLBACK_RENEW;
173 s_info.pending_timer = NULL;
174 s_info.pending_timer_freezed = 0;
175 DbgPrint("pending list exhausted\n");
176 return ECORE_CALLBACK_CANCEL;
179 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
181 if (s_info.pending_timer)
184 s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
185 if (!s_info.pending_timer) {
186 ErrPrint("Failed to add a new pended command consumer\n");
187 return LB_STATUS_ERROR_FAULT;
191 * Do not increase the freezed counter.
192 * Just freeze the timer.
194 if (s_info.pending_timer_freezed) {
195 DbgPrint("Pending timer created and freezed\n");
196 ecore_timer_freeze(s_info.pending_timer);
202 static inline void deactivate_pending_consumer(void)
204 if (!s_info.pending_timer)
207 ecore_timer_del(s_info.pending_timer);
208 s_info.pending_timer = NULL;
209 s_info.pending_timer_freezed = 0;
210 DbgPrint("Clear the pending timer\n");
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;
220 DbgPrint("Clear the open_pd_pending timer\n");
223 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
225 if (s_info.pd_open_pending_timer)
228 s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
229 if (!s_info.pd_open_pending_timer) {
230 ErrPrint("Failed to add a new pended command consumer\n");
231 return LB_STATUS_ERROR_FAULT;
237 static inline void migrate_to_pd_open_pending_list(const char *pkgname)
244 EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
245 if (strcmp(pkgname, item->inst->item->pkgname))
248 s_info.pending_list = eina_list_remove(s_info.pending_list, item);
249 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
253 if (s_info.pd_open_pending_list)
254 activate_pd_open_pending_consumer();
256 if (!s_info.pending_list)
257 deactivate_pending_consumer();
259 DbgPrint("%d items are migrated\n", cnt);
262 static inline void migrate_to_pending_list(const char *pkgname)
269 EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
270 if (strcmp(pkgname, item->inst->item->pkgname))
273 s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
274 s_info.pending_list = eina_list_append(s_info.pending_list, item);
278 if (s_info.pending_list)
279 activate_pending_consumer();
281 if (!s_info.pd_open_pending_list)
282 deactivate_pd_open_pending_consumer();
284 DbgPrint("%d items are migrated\n", cnt);
287 static inline int append_pending_list(struct item *item)
289 if (pd_is_opened(item->inst->item->pkgname) == 1) {
290 if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
291 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
292 return LB_STATUS_ERROR_EXIST;
295 if (activate_pd_open_pending_consumer() < 0)
296 return LB_STATUS_ERROR_FAULT;
298 s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
300 if (eina_list_data_find(s_info.pending_list, item) == item) {
301 DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
302 return LB_STATUS_ERROR_EXIST;
305 if (activate_pending_consumer() < 0)
306 return LB_STATUS_ERROR_FAULT;
308 s_info.pending_list = eina_list_append(s_info.pending_list, item);
313 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);
325 DbgPrint("Compensated: %lf\n", delay);
327 if (item->sleep_at == 0.0f)
330 sleep_time = util_timestamp() - item->sleep_at;
331 if (sleep_time > pending) {
332 DbgPrint("Update time elapsed\n");
333 (void)updator_cb(item);
336 item->sleep_at = 0.0f;
339 static inline void timer_freeze(struct item *item)
342 ecore_timer_freeze(item->timer);
344 if (ecore_timer_interval_get(item->timer) <= 1.0f)
347 gettimeofday(&tv, NULL);
348 item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
351 static inline void update_monitor_cnt(struct item *item)
356 now = util_timestamp();
357 interval = now - item->update_interval;
361 * If the content update is processed in too short time,
362 * don't increase the monitor counter, instead of it
363 * set the heavy updating flag.
364 * And handling this heavy updating from the
365 * file update callback.
367 if (interval >= MINIMUM_UPDATE_INTERVAL)
370 item->heavy_updating = 1;
372 item->update_interval = now;
375 static inline Eina_List *find_item(struct instance *inst)
380 EINA_LIST_FOREACH(s_info.item_list, l, item) {
381 if (item->inst == inst)
388 static inline int output_handler(struct item *item)
393 if (item->monitor_cnt < 0 || item->heavy_updating) {
394 if (!item->heavy_updating) {
395 WarnPrint("%s has invalid monitor_cnt\n", item->inst->id);
398 item->heavy_updating = 0; /* Reset flag */
401 item->monitor_cnt = 0;
404 if (item->monitor_cnt == 0) {
406 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
409 ecore_timer_del(item->monitor);
410 item->monitor = NULL;
413 if (s_info.update == item)
414 s_info.update = NULL;
416 if (item->deleteme) {
417 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
418 (void)so_destroy(item->inst);
427 static int desc_updated_cb(const char *filename, void *data, int over)
432 WarnPrint("Event Q overflow\n");
436 DbgPrint("DESC %s is updated\n", filename);
437 provider_send_desc_updated(item->inst->item->pkgname, item->inst->id, filename);
441 static int file_updated_cb(const char *filename, void *data, int over)
447 char *content = NULL;
452 WarnPrint("Event Q overflow\n");
456 ret = util_get_filesize(filename);
458 ErrPrint("Content is updated. but invalid. ret = %d (Update is ignored)\n", ret);
459 return EXIT_SUCCESS; /*!< To keep the callback */
462 ret = so_get_output_info(item->inst, &w, &h, &priority, &content, &title);
464 ErrPrint("livebox_get_info returns %d\n", ret);
465 return EXIT_SUCCESS; /*!< To keep the callback */
468 provider_send_updated(item->inst->item->pkgname, item->inst->id,
469 item->inst->w, item->inst->h, item->inst->priority, content, title);
471 return output_handler(item);
474 static inline int clear_from_pd_open_pending_list(struct item *item)
479 EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
483 s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
484 if (!s_info.pd_open_pending_list)
485 deactivate_pd_open_pending_consumer();
486 return LB_STATUS_SUCCESS;
489 return LB_STATUS_ERROR_NOT_EXIST;
492 static inline int clear_from_pending_list(struct item *item)
497 EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
501 s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
502 if (!s_info.pending_list)
503 deactivate_pending_consumer();
504 return LB_STATUS_SUCCESS;
507 return LB_STATUS_ERROR_NOT_EXIST;
510 static Eina_Bool update_timeout_cb(void *data)
516 DbgPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
518 if (s_info.update != item)
519 ErrPrint("Updating item is not matched\n");
521 fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
522 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
523 s_info.update = NULL;
526 return ECORE_CALLBACK_CANCEL;
529 static Eina_Bool updator_cb(void *data)
536 if (item->monitor) {/*!< If this item is already in update process */
537 return ECORE_CALLBACK_RENEW;
540 ret = so_is_updated(item->inst);
542 if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
543 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
544 lb_destroy(item->inst->item->pkgname, item->inst->id);
546 ecore_timer_del(item->timer);
548 return ECORE_CALLBACK_CANCEL;
551 return ECORE_CALLBACK_RENEW;
554 if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
555 DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
556 (void)append_pending_list(item);
557 return ECORE_CALLBACK_RENEW;
560 item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
561 if (!item->monitor) {
562 ErrPrint("Failed to add update monitor %s(%s):%d\n",
563 item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
564 return ECORE_CALLBACK_RENEW;
569 * Counter of the event monitor is only used for asynchronous content updating,
570 * So reset it to 1 from here because the async updating is started now,
571 * even if it is accumulated by other event function before this.
573 item->monitor_cnt = 1;
575 s_info.update = item;
577 ret = so_update(item->inst);
581 ecore_timer_del(item->monitor);
582 item->monitor = NULL;
583 s_info.update = NULL;
584 return ECORE_CALLBACK_RENEW;
589 * While waiting the Callback function call,
590 * Add this for finding the crash
592 fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
594 if (ret & NEED_TO_SCHEDULE) {
595 (void)append_pending_list(item);
598 if (ret & OUTPUT_UPDATED)
599 update_monitor_cnt(item);
601 return ECORE_CALLBACK_RENEW;
604 static inline void update_monitor_del(const char *id, struct item *item)
609 update_monitor_del_update_cb(util_uri_to_path(id), file_updated_cb);
611 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
614 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
618 snprintf(tmp, len, "%s.desc", util_uri_to_path(id));
619 update_monitor_del_update_cb(tmp, desc_updated_cb);
623 static inline int add_desc_update_monitor(const char *id, struct item *item)
628 len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
629 filename = malloc(len);
631 ErrPrint("Heap: %s (%s.desc)\n", strerror(errno), util_uri_to_path(id));
632 return LB_STATUS_ERROR_MEMORY;
635 snprintf(filename, len, "%s.desc", util_uri_to_path(id));
636 DbgPrint("Add DESC monitor: %s\n", filename);
637 return update_monitor_add_update_cb(filename, desc_updated_cb, item);
640 static inline int add_file_update_monitor(const char *id, struct item *item)
644 filename = strdup(util_uri_to_path(id));
646 ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
647 return LB_STATUS_ERROR_MEMORY;
650 return update_monitor_add_update_cb(filename, file_updated_cb, item);
653 static inline int update_monitor_add(const char *id, struct item *item)
657 * item->inst is not available yet.
659 add_file_update_monitor(id, item);
660 add_desc_update_monitor(id, item);
661 return LB_STATUS_SUCCESS;
664 HAPI int lb_init(void)
666 return LB_STATUS_SUCCESS;
669 HAPI int lb_fini(void)
675 deactivate_pending_consumer();
676 deactivate_pd_open_pending_consumer();
678 EINA_LIST_FREE(s_info.pd_open_pending_list, item);
679 EINA_LIST_FREE(s_info.pending_list, item);
681 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
682 provider_send_deleted(item->inst->item->pkgname, item->inst->id);
683 lb_destroy(item->inst->item->pkgname, item->inst->id);
686 return LB_STATUS_SUCCESS;
691 * Exported API for each liveboxes.
693 const char *livebox_find_pkgname(const char *filename)
698 EINA_LIST_FOREACH(s_info.item_list, l, item) {
699 if (!strcmp(item->inst->id, filename))
700 return item->inst->item->pkgname;
706 int livebox_request_update_by_id(const char *filename)
711 EINA_LIST_FOREACH(s_info.item_list, l, item) {
712 if (!strcmp(item->inst->id, filename)) {
713 return append_pending_list(item);
717 return LB_STATUS_ERROR_NOT_EXIST;
720 HAPI int lb_open_pd(const char *pkgname)
725 EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
726 if (!strcmp(pkgname, tmp))
730 tmp = strdup(pkgname);
732 ErrPrint("Heap: %s\n", strerror(errno));
733 return LB_STATUS_ERROR_MEMORY;
737 pending_timer_freeze();
739 s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
742 * Find all instances from the pending list.
743 * Move them to pd_open_pending_timer
745 migrate_to_pd_open_pending_list(pkgname);
746 return LB_STATUS_SUCCESS;
749 HAPI int lb_close_pd(const char *pkgname)
755 EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
756 if (strcmp(tmp, pkgname))
759 s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
763 pending_timer_thaw();
766 * Move all items in pd_open_pending_list
769 migrate_to_pending_list(pkgname);
770 return LB_STATUS_SUCCESS;
773 return LB_STATUS_ERROR_NOT_EXIST;
776 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)
778 struct instance *inst;
788 inst = so_find_instance(pkgname, id);
790 DbgPrint("Instance is already exists [%s - %s] content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
791 return LB_STATUS_SUCCESS;
794 if (!skip_need_to_create) {
795 ret = so_create_needed(pkgname, cluster, category, abi);
796 if (ret != NEED_TO_CREATE)
797 return LB_STATUS_ERROR_PERMISSION;
802 item = calloc(1, sizeof(*item));
804 ErrPrint("Heap: %s (%s - %s, content[%s], cluster[%s], category[%s], abi[%s])\n", strerror(errno), pkgname, id, content_info, cluster, category, abi);
805 return LB_STATUS_ERROR_MEMORY;
808 ret = update_monitor_add(id, item);
814 DbgPrint("Content: [%s]\n", content_info);
815 create_ret = so_create(pkgname, id, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
816 if (create_ret < 0) {
817 update_monitor_del(id, item);
828 if (period > 0.0f && !s_info.secured) {
829 item->timer = util_timer_add(period, updator_cb, item);
831 ErrPrint("Failed to add timer (%s - %s, content[%s], cluster[%s], category[%s], abi[%s]\n", pkgname, id, content_info, cluster, category, abi);
832 update_monitor_del(id, item);
835 return LB_STATUS_ERROR_FAULT;
841 DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
845 s_info.item_list = eina_list_append(s_info.item_list, item);
847 if (create_ret & NEED_TO_SCHEDULE) {
848 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
849 (void)append_pending_list(item);
852 if (create_ret & OUTPUT_UPDATED) {
853 update_monitor_cnt(item);
856 * To send a output info, get the info forcely.
857 * but the output file monitor will do this again
859 * This function will set the tmp_content and tmp_title
860 * even if it has no updates on the content, title,
861 * it will set them to NULL.
863 if (so_get_output_info(inst, w, h, priority, out_content, out_title) == LB_STATUS_SUCCESS) {
867 tmp = strdup(*out_content);
869 ErrPrint("Memory: %s\n", strerror(errno));
877 tmp = strdup(*out_title);
879 ErrPrint("Memory: %s\n", strerror(errno));
888 *priority = inst->priority;
889 return need_to_create;
892 HAPI int lb_destroy(const char *pkgname, const char *id)
895 struct instance *inst;
898 inst = so_find_instance(pkgname, id);
900 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
901 return LB_STATUS_ERROR_INVALID;
906 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
907 return LB_STATUS_ERROR_NOT_EXIST;
910 item = eina_list_data_get(l);
911 s_info.item_list = eina_list_remove_list(s_info.item_list, l);
913 if (s_info.update == item)
914 s_info.update = NULL;
917 clear_from_pd_open_pending_list(item);
918 clear_from_pending_list(item);
919 ecore_timer_del(item->timer);
925 update_monitor_del(id, item);
928 if (!item->monitor) {
930 (void)so_destroy(inst);
933 return LB_STATUS_SUCCESS;
936 HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
939 struct instance *inst;
943 inst = so_find_instance(pkgname, id);
945 ErrPrint("Instance %s - %s is not created (%dx%d)\n", pkgname, id, w, h);
946 return LB_STATUS_ERROR_INVALID;
951 ErrPrint("Instance is not found (%s - %s, %dx%d)\n", pkgname, id, w, h);
952 return LB_STATUS_ERROR_NOT_EXIST;
955 item = eina_list_data_get(l);
957 ret = so_resize(inst, w, h);
961 if (ret & NEED_TO_SCHEDULE) {
962 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
963 (void)append_pending_list(item);
966 if (ret & OUTPUT_UPDATED)
967 update_monitor_cnt(item);
969 return LB_STATUS_SUCCESS;
972 HAPI char *lb_pinup(const char *pkgname, const char *id, int pinup)
974 struct instance *inst;
977 inst = so_find_instance(pkgname, id);
979 ErrPrint("Instance %s - %s is not found (pinup[%d])\n", pkgname, id, pinup);
983 ret = so_pinup(inst, pinup);
987 HAPI int lb_set_period(const char *pkgname, const char *id, double period)
990 struct instance *inst;
993 inst = so_find_instance(pkgname, id);
995 ErrPrint("Instance %s - %s is not found (period[%lf])\n", pkgname, id, period);
996 return LB_STATUS_ERROR_INVALID;
1001 ErrPrint("Instance is not found (%s - %s, period[%lf])\n", pkgname, id, period);
1002 return LB_STATUS_ERROR_NOT_EXIST;
1005 item = eina_list_data_get(l);
1007 if (period <= 0.0f) {
1009 ecore_timer_del(item->timer);
1014 util_timer_interval_set(item->timer, period);
1015 } else if (!s_info.secured) {
1016 item->timer = util_timer_add(period, updator_cb, item);
1018 ErrPrint("Failed to add timer (%s - %s)\n", pkgname, id);
1019 return LB_STATUS_ERROR_FAULT;
1027 return LB_STATUS_SUCCESS;
1030 HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, double timestamp, double x, double y)
1033 struct instance *inst;
1037 inst = so_find_instance(pkgname, id);
1039 ErrPrint("Instance %s - %s is not exists (event[%s])\n", pkgname, id, event);
1040 return LB_STATUS_ERROR_INVALID;
1043 l = find_item(inst);
1045 ErrPrint("Instance is not found (%s - %s, event[%s])\n", pkgname, id, event);
1046 return LB_STATUS_ERROR_NOT_EXIST;
1049 item = eina_list_data_get(l);
1051 ret = so_clicked(inst, event, timestamp, x, y);
1055 if (ret & NEED_TO_SCHEDULE) {
1056 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1057 (void)append_pending_list(item);
1060 if (ret & OUTPUT_UPDATED)
1061 update_monitor_cnt(item);
1063 return LB_STATUS_SUCCESS;
1066 HAPI int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info)
1069 struct instance *inst;
1073 inst = so_find_instance(pkgname, id);
1075 ErrPrint("Instance %s - %s is not exists (emission[%s], source[%s])\n", pkgname, id, emission, source);
1076 return LB_STATUS_ERROR_INVALID;
1079 l = find_item(inst);
1081 ErrPrint("Instance is not found (%s - %s, emissino[%s], source[%s])\n", pkgname, id, emission, source);
1082 return LB_STATUS_ERROR_NOT_EXIST;
1085 item = eina_list_data_get(l);
1087 ret = so_script_event(inst, emission, source, event_info);
1091 if (ret & NEED_TO_SCHEDULE) {
1092 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1093 (void)append_pending_list(item);
1096 if (ret & OUTPUT_UPDATED)
1097 update_monitor_cnt(item);
1099 return LB_STATUS_SUCCESS;
1102 HAPI int lb_is_pinned_up(const char *pkgname, const char *id)
1105 struct instance *inst;
1108 inst = so_find_instance(pkgname, id);
1110 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1111 return LB_STATUS_ERROR_INVALID;
1114 l = find_item(inst);
1116 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1117 return LB_STATUS_ERROR_NOT_EXIST;
1120 item = eina_list_data_get(l);
1122 ErrPrint("Invalid item(%s - %s)\n", pkgname, id);
1123 return LB_STATUS_ERROR_FAULT;
1128 * Maybe this is not neccessary for this operation
1130 return so_is_pinned_up(inst);
1133 HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category)
1136 struct instance *inst;
1140 inst = so_find_instance(pkgname, id);
1142 ErrPrint("Instance %s - %s is not created (cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1143 return LB_STATUS_ERROR_INVALID;
1146 l = find_item(inst);
1148 ErrPrint("Instance is not found(%s - %s, cluster[%s], category[%s])\n", pkgname, id, cluster, category);
1149 return LB_STATUS_ERROR_NOT_EXIST;
1152 item = eina_list_data_get(l);
1154 ret = so_change_group(inst, cluster, category);
1158 if (ret & NEED_TO_SCHEDULE) {
1159 DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
1160 (void)append_pending_list(item);
1163 if (ret & OUTPUT_UPDATED)
1164 update_monitor_cnt(item);
1166 return LB_STATUS_SUCCESS;
1169 static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
1173 ret = so_sys_event(inst, event);
1177 if (ret & NEED_TO_SCHEDULE)
1178 (void)append_pending_list(item);
1180 if (ret & OUTPUT_UPDATED)
1181 update_monitor_cnt(item);
1183 return LB_STATUS_SUCCESS;
1186 HAPI int lb_system_event(const char *pkgname, const char *id, int event)
1189 struct instance *inst;
1192 inst = so_find_instance(pkgname, id);
1194 ErrPrint("instance %s - %s is not created\n");
1195 return LB_STATUS_ERROR_INVALID;
1198 l = find_item(inst);
1200 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1201 return LB_STATUS_ERROR_NOT_EXIST;
1204 item = eina_list_data_get(l);
1205 return lb_sys_event(inst, item, event);
1208 HAPI int lb_update(const char *pkgname, const char *id)
1211 struct instance *inst;
1214 inst = so_find_instance(pkgname, id);
1216 ErrPrint("Instance %s - %s is not created\n", pkgname, id);
1217 return LB_STATUS_ERROR_INVALID;
1220 l = find_item(inst);
1222 ErrPrint("Instance is not found(%s - %s)\n", pkgname, id);
1223 return LB_STATUS_ERROR_NOT_EXIST;
1226 item = eina_list_data_get(l);
1227 (void)append_pending_list(item);
1228 return LB_STATUS_SUCCESS;
1231 HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
1237 DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
1238 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1242 if (cluster && strcasecmp(item->inst->cluster, cluster))
1245 if (category && strcasecmp(item->inst->category, category))
1248 if (pkgname && strlen(pkgname)) {
1249 if (!strcmp(item->inst->item->pkgname, pkgname)) {
1250 (void)append_pending_list(item);
1253 (void)append_pending_list(item);
1257 return LB_STATUS_SUCCESS;
1260 HAPI int lb_system_event_all(int event)
1266 EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
1270 DbgPrint("System event for %s (%d)\n", item->inst->id, event);
1271 lb_sys_event(item->inst, item, event);
1274 return LB_STATUS_SUCCESS;
1277 HAPI void lb_pause_all(void)
1284 pending_timer_freeze();
1286 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1287 if (item->deleteme) {
1288 DbgPrint("Instance %s skip timer pause (deleteme)\n", item->inst->item->pkgname);
1292 if (item->is_paused) {
1293 DbgPrint("Instance %s is already paused\n", item->inst->id);
1298 DbgPrint("Instance %s freeze timer\n", item->inst->item->pkgname);
1301 DbgPrint("Instance %s has no timer\n", item->inst->item->pkgname);
1304 lb_sys_event(item->inst, item, LB_SYS_EVENT_PAUSED);
1308 HAPI void lb_resume_all(void)
1315 pending_timer_thaw();
1317 EINA_LIST_FOREACH(s_info.item_list, l, item) {
1318 if (item->deleteme) {
1319 DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
1323 if (item->is_paused) {
1324 DbgPrint("Instance %s is still paused\n", item->inst->id);
1329 DbgPrint("Instance %s resume timer\n", item->inst->item->pkgname);
1333 lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
1337 HAPI int lb_pause(const char *pkgname, const char *id)
1339 struct instance *inst;
1343 inst = so_find_instance(pkgname, id);
1345 return LB_STATUS_ERROR_INVALID;
1347 l = find_item(inst);
1349 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1350 return LB_STATUS_ERROR_NOT_EXIST;
1353 item = eina_list_data_get(l);
1355 return LB_STATUS_ERROR_FAULT;
1357 if (item->deleteme) {
1358 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1359 return LB_STATUS_ERROR_BUSY;
1362 item->is_paused = 1;
1364 if (s_info.paused) {
1365 DbgPrint("Already paused: %s\n", item->inst->id);
1366 return LB_STATUS_SUCCESS;
1372 lb_sys_event(inst, item, LB_SYS_EVENT_PAUSED);
1374 return LB_STATUS_SUCCESS;
1377 HAPI int lb_resume(const char *pkgname, const char *id)
1379 struct instance *inst;
1383 inst = so_find_instance(pkgname, id);
1385 return LB_STATUS_ERROR_INVALID;
1387 l = find_item(inst);
1389 ErrPrint("Instance is not found (%s - %s)\n", pkgname, id);
1390 return LB_STATUS_ERROR_NOT_EXIST;
1393 item = eina_list_data_get(l);
1395 return LB_STATUS_ERROR_FAULT;
1397 if (item->deleteme) {
1398 DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
1399 return LB_STATUS_ERROR_BUSY;
1402 item->is_paused = 0;
1404 if (s_info.paused) {
1405 DbgPrint("Instance %s is still paused\n", item->inst->id);
1406 return LB_STATUS_SUCCESS;
1412 lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
1413 return LB_STATUS_SUCCESS;
1416 HAPI void lb_turn_secured_on(void)