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.
19 #include <string.h> /* strcmp */
20 #include <stdlib.h> /* free */
24 #include <Ecore_Evas.h>
27 #include <livebox-errno.h>
28 #include <livebox-service.h>
31 #include "critical_log.h"
36 #include "slave_life.h"
37 #include "slave_rpc.h"
38 #include "client_life.h"
40 #include "fault_manager.h"
42 #include "script_handler.h"
58 * pkg_info describes the loaded package.
75 /*!< Reserved for future use */
79 /*!< Reserved for future use */
83 /*!< Reserved for future use */
87 unsigned int size_list;
105 /*!< Reserved for future use */
109 /*!< Reserved for future use */
119 char *script; /* script type: edje, ... */
123 struct fault_info *fault_info;
125 struct slave_node *slave;
128 Eina_List *inst_list;
140 static int slave_activated_cb(struct slave_node *slave, void *data)
142 struct pkg_info *info = data;
143 struct inst_info *inst;
149 if (!slave_need_to_reactivate_instances(slave)) {
150 DbgPrint("Do not need to reactivate instances\n");
155 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
156 ret = instance_recover_state(inst);
161 instance_thaw_updator(inst);
165 DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
169 static int slave_fault_cb(struct slave_node *slave, void *data)
173 struct inst_info *inst;
174 struct pkg_info *info = (struct pkg_info *)data;
176 if (package_is_fault(info)) {
177 ErrPrint("Already faulted package: %s\n", package_name(info));
181 (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
182 fault_broadcast_info(package_name(info), slave_name(slave), __func__);
184 DbgPrint("Slave critical fault - package: %s (by slave fault %s\n", package_name(info), slave_name(slave));
185 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
186 DbgPrint("Destroy instance %p\n", inst);
187 instance_destroyed(inst, LB_STATUS_ERROR_FAULT);
193 static int slave_deactivated_cb(struct slave_node *slave, void *data)
195 struct pkg_info *info = data;
196 struct inst_info *inst;
201 if (info->fault_info) {
202 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
203 instance_destroyed(inst, LB_STATUS_ERROR_FAULT);
206 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
207 cnt += instance_need_slave(inst);
209 * instance_deactivated will call the slave_unload_instance.
210 * if the loaded instance counter meets 0,
211 * the slave will be deactivated.
212 * so we should not call the instance activate function
215 * activate slave when the slave is reactivated
220 return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
223 static int xmonitor_paused_cb(void *data)
225 struct pkg_info *info = (struct pkg_info *)data;
226 struct inst_info *inst;
229 if (slave_state(info->slave) != SLAVE_TERMINATED) {
233 EINA_LIST_FOREACH(info->inst_list, l, inst) {
234 instance_freeze_updator(inst);
240 static int xmonitor_resumed_cb(void *data)
242 struct pkg_info *info = data;
243 struct inst_info *inst;
246 if (slave_state(info->slave) != SLAVE_TERMINATED) {
250 EINA_LIST_FOREACH(info->inst_list, l, inst) {
251 instance_thaw_updator(inst);
257 static int slave_paused_cb(struct slave_node *slave, void *data)
259 struct pkg_info *info = (struct pkg_info *)data;
260 struct inst_info *inst;
263 EINA_LIST_FOREACH(info->inst_list, l, inst) {
264 instance_freeze_updator(inst);
270 static int slave_resumed_cb(struct slave_node *slave, void *data)
272 struct pkg_info *info = (struct pkg_info *)data;
273 struct inst_info *inst;
276 EINA_LIST_FOREACH(info->inst_list, l, inst) {
277 instance_thaw_updator(inst);
283 static inline void destroy_package(struct pkg_info *info)
285 struct context_info *ctx_info __attribute__((unused));
287 EINA_LIST_FREE(info->ctx_list, ctx_info) {
288 /* This items will be deleted from group_del_livebox */
291 group_del_livebox(info->lbid);
292 package_clear_fault(info);
294 s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
296 if (info->lb.type == LB_TYPE_SCRIPT) {
297 DbgFree(info->lb.info.script.path);
298 DbgFree(info->lb.info.script.group);
301 if (info->pd.type == PD_TYPE_SCRIPT) {
302 DbgFree(info->pd.info.script.path);
303 DbgFree(info->pd.info.script.group);
306 DbgFree(info->script);
309 DbgFree(info->lb.libexec);
310 DbgFree(info->lb.auto_launch);
311 DbgFree(info->pkgid);
316 static inline int load_conf(struct pkg_info *info)
318 struct parser *parser;
322 parser = parser_load(info->lbid);
324 info->lb.size_list = 0x01; /* Default */
326 info->script = strdup(DEFAULT_SCRIPT);
328 ErrPrint("Heap: %s\n", strerror(errno));
329 return LB_STATUS_ERROR_MEMORY;
332 info->abi = strdup(DEFAULT_ABI);
334 ErrPrint("Heap: %s\n", strerror(errno));
335 DbgFree(info->script);
337 return LB_STATUS_ERROR_MEMORY;
340 info->pd.width = g_conf.width;
341 info->pd.height = g_conf.height >> 2;
343 return LB_STATUS_SUCCESS;
346 info->lb.type = LB_TYPE_FILE;
347 if (parser_text_lb(parser)) {
348 info->lb.type = LB_TYPE_TEXT;
349 } else if (parser_buffer_lb(parser)) {
350 info->lb.type = LB_TYPE_BUFFER;
352 str = parser_lb_path(parser);
354 info->lb.type = LB_TYPE_SCRIPT;
356 info->lb.info.script.path = strdup(str);
357 if (!info->lb.info.script.path) {
358 ErrPrint("Heap: %s\n", strerror(errno));
359 parser_unload(parser);
360 return LB_STATUS_ERROR_MEMORY;
363 str = parser_lb_group(parser);
365 info->lb.info.script.group = strdup(str);
366 if (!info->lb.info.script.group) {
367 ErrPrint("Heap: %s\n", strerror(errno));
368 DbgFree(info->lb.info.script.path);
369 parser_unload(parser);
370 return LB_STATUS_ERROR_MEMORY;
376 if (parser_text_pd(parser)) {
377 info->pd.type = PD_TYPE_TEXT;
378 } else if (parser_buffer_pd(parser)) {
379 info->pd.type = PD_TYPE_BUFFER;
381 str = parser_pd_path(parser);
383 info->pd.type = PD_TYPE_SCRIPT;
384 info->pd.info.script.path = strdup(str);
385 if (!info->pd.info.script.path) {
386 ErrPrint("Heap: %s\n", strerror(errno));
387 if (info->lb.type == LB_TYPE_SCRIPT) {
388 DbgFree(info->lb.info.script.path);
389 DbgFree(info->lb.info.script.group);
391 parser_unload(parser);
392 return LB_STATUS_ERROR_MEMORY;
395 str = parser_pd_group(parser);
397 info->pd.info.script.group = strdup(str);
398 if (!info->pd.info.script.group) {
399 ErrPrint("Heap: %s\n", strerror(errno));
400 DbgFree(info->pd.info.script.path);
401 if (info->lb.type == LB_TYPE_SCRIPT) {
402 DbgFree(info->lb.info.script.path);
403 DbgFree(info->lb.info.script.group);
405 parser_unload(parser);
406 return LB_STATUS_ERROR_MEMORY;
412 str = parser_script(parser);
413 str = str ? str : DEFAULT_SCRIPT;
414 info->script = strdup(str);
416 ErrPrint("Heap: %s\n", strerror(errno));
417 if (info->pd.type == PD_TYPE_SCRIPT) {
418 DbgFree(info->pd.info.script.path);
419 DbgFree(info->pd.info.script.group);
422 if (info->lb.type == LB_TYPE_SCRIPT) {
423 DbgFree(info->lb.info.script.path);
424 DbgFree(info->lb.info.script.group);
427 parser_unload(parser);
428 return LB_STATUS_ERROR_MEMORY;
431 str = parser_abi(parser);
432 str = str ? str : DEFAULT_ABI;
433 info->abi = strdup(str);
435 ErrPrint("Heap: %s\n", strerror(errno));
436 DbgFree(info->script);
437 if (info->pd.type == PD_TYPE_SCRIPT) {
438 DbgFree(info->pd.info.script.path);
439 DbgFree(info->pd.info.script.group);
442 if (info->lb.type == LB_TYPE_SCRIPT) {
443 DbgFree(info->lb.info.script.path);
444 DbgFree(info->lb.info.script.group);
446 parser_unload(parser);
447 return LB_STATUS_ERROR_MEMORY;
450 info->lb.timeout = parser_timeout(parser);
451 info->network = parser_network(parser);
453 info->lb.period = parser_period(parser);
454 if (info->lb.period < 0.0f) {
455 info->lb.period = 0.0f;
456 } else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD) {
457 info->lb.period = MINIMUM_PERIOD;
460 info->lb.size_list = parser_size(parser);
462 str = parser_auto_launch(parser);
463 str = str ? str : "";
464 info->lb.auto_launch = strdup(str);
465 if (!info->lb.auto_launch) {
466 ErrPrint("Heap: %s\n", strerror(errno));
468 DbgFree(info->script);
469 if (info->pd.type == PD_TYPE_SCRIPT) {
470 DbgFree(info->pd.info.script.path);
471 DbgFree(info->pd.info.script.group);
474 if (info->lb.type == LB_TYPE_SCRIPT) {
475 DbgFree(info->lb.info.script.path);
476 DbgFree(info->lb.info.script.group);
478 parser_unload(parser);
479 return LB_STATUS_ERROR_MEMORY;
482 info->secured = parser_secured(parser);
483 info->lb.pinup = parser_pinup(parser);
485 parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
487 group = parser_group_str(parser);
488 if (group && group_add_livebox(group, info->lbid) < 0) {
489 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->lbid, group);
492 parser_unload(parser);
493 return LB_STATUS_SUCCESS;
496 HAPI struct pkg_info *package_create(const char *pkgid, const char *lbid)
498 struct pkg_info *pkginfo;
500 pkginfo = calloc(1, sizeof(*pkginfo));
502 ErrPrint("Heap: %s\n", strerror(errno));
506 pkginfo->pkgid = strdup(pkgid);
507 if (!pkginfo->pkgid) {
508 ErrPrint("Heap: %s\n", strerror(errno));
513 pkginfo->lbid = io_livebox_pkgname(lbid);
514 if (!pkginfo->lbid) {
515 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
516 if (util_validate_livebox_package(lbid) < 0) {
517 ErrPrint("Invalid package name: %s\n", lbid);
518 DbgFree(pkginfo->pkgid);
523 pkginfo->lbid = strdup(lbid);
524 if (!pkginfo->lbid) {
525 ErrPrint("Heap: %s\n", strerror(errno));
526 DbgFree(pkginfo->pkgid);
532 if (io_load_package_db(pkginfo) < 0) {
533 ErrPrint("Failed to load DB, fall back to conf file loader\n");
534 if (load_conf(pkginfo) < 0) {
535 ErrPrint("Failed to initiate the conf file loader\n");
536 DbgFree(pkginfo->lbid);
537 DbgFree(pkginfo->pkgid);
543 package_ref(pkginfo);
545 s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
550 HAPI int package_destroy(struct pkg_info *info)
553 return LB_STATUS_SUCCESS;
556 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
558 return pkginfo->ctx_list;
561 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
563 pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
566 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
568 pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
571 HAPI char *package_lb_pkgname(const char *pkgname)
575 lbid = io_livebox_pkgname(pkgname);
577 if (util_validate_livebox_package(pkgname) < 0) {
581 lbid = strdup(pkgname);
583 ErrPrint("Heap: %s\n", strerror(errno));
591 HAPI int package_is_lb_pkgname(const char *pkgname)
596 lbid = package_lb_pkgname(pkgname);
603 HAPI struct pkg_info *package_find(const char *lbid)
606 struct pkg_info *info;
612 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
613 if (!strcmp(info->lbid, lbid)) {
621 HAPI struct inst_info *package_find_instance_by_id(const char *lbid, const char *id)
624 struct inst_info *inst;
625 struct pkg_info *info;
627 info = package_find(lbid);
629 ErrPrint("Package %s is not exists\n", lbid);
633 EINA_LIST_FOREACH(info->inst_list, l, inst) {
634 if (!strcmp(instance_id(inst), id)) {
642 HAPI struct inst_info *package_find_instance_by_timestamp(const char *lbid, double timestamp)
645 struct inst_info *inst;
646 struct pkg_info *info;
648 info = package_find(lbid);
650 ErrPrint("Package %s is not exists\n", lbid);
654 EINA_LIST_FOREACH(info->inst_list, l, inst) {
655 if (instance_timestamp(inst) == timestamp) {
663 HAPI int package_dump_fault_info(struct pkg_info *info)
665 if (!info->fault_info) {
666 return LB_STATUS_ERROR_NOT_EXIST;
669 CRITICAL_LOG("=============\n");
670 CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
671 CRITICAL_LOG("Package: %s\n", info->lbid);
672 CRITICAL_LOG("Function: %s\n", info->fault_info->function);
673 CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
674 return LB_STATUS_SUCCESS;
677 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
679 if (!info->fault_info) {
680 return LB_STATUS_ERROR_NOT_EXIST;
683 *timestamp = info->fault_info->timestamp;
684 *filename = info->fault_info->filename;
685 *function = info->fault_info->function;
686 return LB_STATUS_SUCCESS;
689 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
691 struct fault_info *fault;
693 package_clear_fault(info);
695 fault = calloc(1, sizeof(*fault));
697 ErrPrint("Heap: %s\n", strerror(errno));
698 return LB_STATUS_ERROR_MEMORY;
701 fault->timestamp = timestamp;
703 filename = "unknown";
706 function = "unknown";
709 fault->filename = strdup(filename);
710 if (!fault->filename) {
711 ErrPrint("Heap: %s\n", strerror(errno));
713 return LB_STATUS_ERROR_MEMORY;
716 fault->function = strdup(function);
717 if (!fault->function) {
718 ErrPrint("Heap: %s\n", strerror(errno));
719 DbgFree(fault->filename);
721 return LB_STATUS_ERROR_MEMORY;
724 info->fault_info = fault;
726 return LB_STATUS_SUCCESS;
729 HAPI int package_clear_fault(struct pkg_info *info)
731 if (!info->fault_info) {
732 return LB_STATUS_ERROR_INVALID;
735 package_dump_fault_info(info);
737 DbgFree(info->fault_info->function);
738 DbgFree(info->fault_info->filename);
739 DbgFree(info->fault_info);
740 info->fault_info = NULL;
741 return LB_STATUS_SUCCESS;
744 HAPI const int const package_is_fault(const struct pkg_info *info)
746 return !!info->fault_info;
749 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
754 HAPI const int const package_timeout(const struct pkg_info *info)
756 return info->lb.timeout;
759 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
761 info->lb.timeout = timeout;
764 HAPI const double const package_period(const struct pkg_info *info)
766 return info->lb.period;
769 HAPI void package_set_period(struct pkg_info *info, double period)
771 info->lb.period = period;
774 HAPI const int const package_secured(const struct pkg_info *info)
776 return info->secured;
779 HAPI void package_set_secured(struct pkg_info *info, int secured)
781 info->secured = secured;
784 HAPI const char * const package_script(const struct pkg_info *info)
789 HAPI int package_set_script(struct pkg_info *info, const char *script)
793 tmp = strdup(script);
795 ErrPrint("Heap: %s\n", strerror(errno));
796 return LB_STATUS_ERROR_MEMORY;
799 DbgFree(info->script);
801 return LB_STATUS_SUCCESS;
804 HAPI const char * const package_abi(const struct pkg_info *info)
809 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
814 ErrPrint("Heap: %s\n", strerror(errno));
815 return LB_STATUS_ERROR_MEMORY;
820 return LB_STATUS_SUCCESS;
823 HAPI const char * const package_lb_path(const struct pkg_info *info)
825 if (info->lb.type != LB_TYPE_SCRIPT) {
829 return info->lb.info.script.path;
832 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
836 if (info->lb.type != LB_TYPE_SCRIPT) {
837 return LB_STATUS_ERROR_INVALID;
842 ErrPrint("Heap: %s\n", strerror(errno));
843 return LB_STATUS_ERROR_MEMORY;
846 DbgFree(info->lb.info.script.path);
847 info->lb.info.script.path = tmp;
848 return LB_STATUS_SUCCESS;
851 HAPI const char * const package_lb_group(const struct pkg_info *info)
853 if (info->lb.type != LB_TYPE_SCRIPT) {
857 return info->lb.info.script.group;
860 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
864 if (info->lb.type != LB_TYPE_SCRIPT) {
865 return LB_STATUS_ERROR_INVALID;
870 ErrPrint("Heap: %s\n", strerror(errno));
871 return LB_STATUS_ERROR_MEMORY;
874 DbgFree(info->lb.info.script.group);
875 info->lb.info.script.group = tmp;
876 return LB_STATUS_SUCCESS;
879 HAPI const char * const package_pd_path(const struct pkg_info *info)
881 if (info->pd.type != PD_TYPE_SCRIPT) {
885 return info->pd.info.script.path;
888 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
892 if (info->pd.type != PD_TYPE_SCRIPT) {
893 return LB_STATUS_ERROR_INVALID;
898 ErrPrint("Heap: %s\n", strerror(errno));
899 return LB_STATUS_ERROR_MEMORY;
902 DbgFree(info->pd.info.script.path);
903 info->pd.info.script.path = tmp;
904 return LB_STATUS_SUCCESS;
907 HAPI const char * const package_pd_group(const struct pkg_info *info)
909 if (info->pd.type != PD_TYPE_SCRIPT) {
913 return info->pd.info.script.group;
916 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
920 if (info->pd.type != PD_TYPE_SCRIPT) {
921 return LB_STATUS_ERROR_INVALID;
926 ErrPrint("Heap: %s\n", strerror(errno));
927 return LB_STATUS_ERROR_MEMORY;
930 DbgFree(info->pd.info.script.group);
931 info->pd.info.script.group = tmp;
932 return LB_STATUS_SUCCESS;
935 HAPI const int const package_pinup(const struct pkg_info *info)
937 return info->lb.pinup;
940 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
942 info->lb.pinup = pinup;
945 HAPI const char * const package_auto_launch(const struct pkg_info *info)
947 return info->lb.auto_launch;
950 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
956 info->lb.auto_launch = strdup(auto_launch);
957 if (!info->lb.auto_launch) {
958 ErrPrint("Heap: %s\n", strerror(errno));
963 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
965 return info->lb.size_list;
968 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
970 info->lb.size_list = size_list;
973 HAPI const int const package_pd_width(const struct pkg_info *info)
975 return info->pd.width;
978 HAPI void package_set_pd_width(struct pkg_info *info, int width)
980 info->pd.width = width;
983 HAPI const int const package_pd_height(const struct pkg_info *info)
985 return info->pd.height;
988 HAPI void package_set_pd_height(struct pkg_info *info, int height)
990 info->pd.height = height;
993 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
999 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
1001 if (info->refcnt == 0) {
1002 ErrPrint("Invalid request\n");
1007 if (info->refcnt == 0) {
1008 destroy_package(info);
1015 HAPI const int const package_refcnt(const struct pkg_info *info)
1017 return info->refcnt;
1020 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
1022 return info->lb.type;
1025 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
1027 info->lb.type = type;
1030 HAPI const char * const package_libexec(struct pkg_info *info)
1032 return info->lb.libexec;
1035 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1039 tmp = strdup(libexec);
1041 ErrPrint("Heap: %s\n", strerror(errno));
1042 return LB_STATUS_ERROR_MEMORY;
1045 DbgFree(info->lb.libexec);
1046 info->lb.libexec = tmp;
1047 return LB_STATUS_SUCCESS;
1050 HAPI int package_network(struct pkg_info *info)
1052 return info->network;
1055 HAPI void package_set_network(struct pkg_info *info, int network)
1057 info->network = network;
1060 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
1062 return info->pd.type;
1065 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
1067 info->pd.type = type;
1072 * Add the instance to the package info.
1073 * If a package has no slave, assign a new slave.
1075 static inline int assign_new_slave(struct pkg_info *info)
1081 s_name = util_slavename();
1083 ErrPrint("Failed to get a new slave name\n");
1084 return LB_STATUS_ERROR_FAULT;
1087 tmp = abi_find_slave(info->abi);
1090 ErrPrint("Failed to find a proper pkgname of a slave\n");
1091 return LB_STATUS_ERROR_INVALID;
1094 s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->lbid);
1096 DbgPrint("Failed to get replaced string\n");
1097 s_pkgname = strdup(tmp);
1099 ErrPrint("Heap: %s\n", strerror(errno));
1101 return LB_STATUS_ERROR_MEMORY;
1105 DbgPrint("New slave[%s] is assigned for %s (using %s / abi[%s])\n", s_name, info->lbid, s_pkgname, info->abi);
1106 info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname, info->network);
1114 * package_destroy will try to remove "info" from the pkg_list.
1115 * but we didn't add this to it yet.
1116 * If the list method couldn't find an "info" from the list,
1117 * it just do nothing so I'll leave this.
1119 return LB_STATUS_ERROR_FAULT;
1123 * Slave is not activated yet.
1125 return LB_STATUS_SUCCESS;
1128 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1130 if (!info->inst_list) {
1131 info->slave = slave_find_available(info->abi, info->secured, info->network);
1136 ret = assign_new_slave(info);
1141 DbgPrint("Slave %s is used for %s\n", slave_name(info->slave), info->lbid);
1144 slave_ref(info->slave);
1145 slave_load_package(info->slave);
1146 slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1147 slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1148 slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1150 if (info->secured) {
1151 slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1152 slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1156 * In case of the slave is terminated because of expired TTL timer,
1157 * Master should freeze the all update time.
1158 * But the callback should check the slave's state to prevent from duplicated freezing.
1160 * This callback will freeze the timer only if a slave doesn't running.
1162 xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1163 xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1167 info->inst_list = eina_list_append(info->inst_list, inst);
1168 return LB_STATUS_SUCCESS;
1171 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1173 info->inst_list = eina_list_remove(info->inst_list, inst);
1175 if (info->inst_list) {
1176 return LB_STATUS_SUCCESS;
1180 slave_unload_package(info->slave);
1182 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1183 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1184 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1186 if (info->secured) {
1187 slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1188 slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1190 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1191 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1194 slave_unref(info->slave);
1198 if (info->is_uninstalled) {
1199 package_destroy(info);
1202 return LB_STATUS_SUCCESS;
1205 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1207 return info->inst_list;
1210 static int client_created_cb(struct client_node *client, void *data)
1212 struct pkg_info *info;
1215 struct inst_info *inst;
1218 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1219 if (info->fault_info) {
1220 fault_unicast_info(client, info->lbid, info->fault_info->filename, info->fault_info->function);
1224 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1225 switch (instance_state(inst)) {
1227 /* Will be send a created event after the instance gets created event */
1229 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1230 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1231 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1232 if (instance_client(inst) == client) {
1233 instance_unicast_created_event(inst, client);
1234 } else if (instance_client(inst) == NULL) {
1237 * Instances are lives in the system cluster/sub-cluster
1239 if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1240 instance_unicast_created_event(inst, client);
1241 DbgPrint("(Subscribed) Created package: %s\n", info->lbid);
1247 DbgPrint("%s(%s) is not activated (%d)\n",
1248 package_name(info), instance_id(inst), instance_state(inst));
1257 static int io_uninstall_cb(const char *pkgid, const char *lbid, int prime, void *data)
1259 struct pkg_info *info;
1262 struct inst_info *inst;
1264 DbgPrint("Package %s is uninstalled\n", lbid);
1265 info = package_find(lbid);
1267 DbgPrint("%s is not yet loaded\n", lbid);
1271 info->is_uninstalled = 1;
1275 * Don't delete an item from the inst_list.
1276 * destroy callback will use this list again.
1277 * So, Don't touch it from here.
1279 if (info->inst_list) {
1280 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1281 instance_destroy(inst, INSTANCE_DESTROY_UNINSTALL);
1284 package_destroy(info);
1290 static inline void reload_package_info(struct pkg_info *info)
1294 struct inst_info *inst;
1295 unsigned int size_type;
1299 DbgPrint("Already exists, try to update it\n");
1301 group_del_livebox(info->lbid);
1302 package_clear_fault(info);
1308 io_load_package_db(info);
1312 * Without "is_uninstalled", the package will be kept
1314 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1315 width = instance_lb_width(inst);
1316 height = instance_lb_height(inst);
1317 size_type = livebox_service_size_type(width, height);
1318 if (info->lb.size_list & size_type) {
1319 instance_reload(inst, INSTANCE_DESTROY_UPGRADE);
1321 instance_destroy(inst, INSTANCE_DESTROY_UNINSTALL);
1326 static int io_install_cb(const char *pkgid, const char *lbid, int prime, void *data)
1328 struct pkg_info *info;
1330 info = package_find(lbid);
1333 * Already exists. skip to create this.
1338 info = package_create(pkgid, lbid);
1340 ErrPrint("Failed to build an info %s\n", lbid);
1342 DbgPrint("Livebox %s is built\n", lbid);
1348 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1352 struct pkg_info *info;
1354 if (status != PKGMGR_STATUS_END) {
1358 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1359 if (!strcmp(info->pkgid, pkgname)) {
1360 io_uninstall_cb(pkgname, info->lbid, -1, NULL);
1367 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1371 struct pkg_info *info;
1373 if (status != PKGMGR_STATUS_END) {
1377 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1378 if (!strcmp(info->pkgid, pkgname)) {
1379 DbgPrint("Update lbid: %s\n", info->lbid);
1380 if (io_is_exists(info->lbid) == 1) {
1381 reload_package_info(info);
1383 io_uninstall_cb(pkgname, info->lbid, -1, NULL);
1388 (void)io_update_livebox_package(pkgname, io_install_cb, NULL);
1392 static int crawling_liveboxes(const char *pkgid, const char *lbid, int prime, void *data)
1394 if (package_find(lbid)) {
1395 ErrPrint("Information of %s is already built\n", lbid);
1397 struct pkg_info *info;
1398 info = package_create(pkgid, lbid);
1400 DbgPrint("[%s] information is built prime(%d)\n", lbid, prime);
1407 HAPI int package_init(void)
1409 client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1412 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1413 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1414 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1416 io_crawling_liveboxes(crawling_liveboxes, NULL);
1420 HAPI int package_fini(void)
1426 struct pkg_info *info;
1427 struct inst_info *inst;
1429 pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1430 pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1431 pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1433 client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1435 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
1436 EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
1437 instance_state_reset(inst);
1438 instance_destroy(inst, INSTANCE_DESTROY_TERMINATE);
1441 package_destroy(info);
1447 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1450 struct pkg_info *info;
1452 if (!slave_is_secured(slave)) {
1456 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1457 if (info->slave == slave) {
1465 HAPI const char * const package_name(const struct pkg_info *info)
1471 * del_or_creat : 1 == create, 0 == delete
1473 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1475 struct pkg_info *info;
1478 struct inst_info *inst;
1481 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1482 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1483 if (instance_client(inst)) {
1487 if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1491 switch (instance_state(inst)) {
1493 case INST_REQUEST_TO_ACTIVATE:
1494 /* Will be send a created event after the instance gets created event */
1497 if (!instance_has_client(inst, client)) {
1498 instance_add_client(inst, client);
1502 if (instance_has_client(inst, client)) {
1503 instance_del_client(inst, client);
1510 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1511 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1512 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1515 * Instances are lives in the system cluster/sub-cluster
1519 if (!instance_has_client(inst, client)) {
1520 instance_unicast_created_event(inst, client);
1521 instance_add_client(inst, client);
1522 DbgPrint("(Subscribed) Created package: %s\n", info->lbid);
1526 if (instance_has_client(inst, client)) {
1527 instance_unicast_deleted_event(inst, client);
1528 instance_del_client(inst, client);
1537 DbgPrint("%s(%s) is not activated (%d)\n",
1538 package_name(info), instance_id(inst), instance_state(inst));
1547 HAPI const Eina_List *package_list(void)
1549 return s_info.pkg_list;
1552 HAPI int const package_fault_count(struct pkg_info *info)
1554 return info ? info->fault_count : 0;
1557 HAPI int package_is_enabled(const char *appid)
1563 ret = ail_get_appinfo(appid, &ai);
1564 if (ret != AIL_ERROR_OK) {
1565 ErrPrint("Unable to get appinfo: %d\n", ret);
1569 if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK) {
1573 ail_destroy_appinfo(ai);
1575 return enabled == true;
1578 HAPI int package_faulted(struct pkg_info *pkg)
1582 struct slave_node *slave;
1583 struct inst_info *inst;
1585 slave = package_slave(pkg);
1587 ErrPrint("Package has no slave?\n");
1588 return LB_STATUS_ERROR_FAULT;
1591 /* Emulated fault routine */
1592 // (void)package_set_fault_info(pkg, util_timestamp(), slave_name(slave), __func__);
1593 fault_broadcast_info(package_name(pkg), slave_name(slave), __func__);
1595 DbgPrint("package: %s (forucely faulted %s)\n", package_name(pkg), slave_name(slave));
1596 EINA_LIST_FOREACH_SAFE(pkg->inst_list, l, n, inst) {
1597 DbgPrint("Destroy instance %p\n", inst);
1598 instance_destroy(inst, INSTANCE_DESTROY_FAULT);
1601 return LB_STATUS_SUCCESS;