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);
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);
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;
286 EINA_LIST_FREE(info->ctx_list, ctx_info) {
287 /* This items will be deleted from group_del_livebox */
290 group_del_livebox(info->lbid);
291 package_clear_fault(info);
293 s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
295 if (info->lb.type == LB_TYPE_SCRIPT) {
296 DbgFree(info->lb.info.script.path);
297 DbgFree(info->lb.info.script.group);
300 if (info->pd.type == PD_TYPE_SCRIPT) {
301 DbgFree(info->pd.info.script.path);
302 DbgFree(info->pd.info.script.group);
305 DbgFree(info->script);
308 DbgFree(info->lb.libexec);
309 DbgFree(info->lb.auto_launch);
310 DbgFree(info->pkgid);
315 static inline int load_conf(struct pkg_info *info)
317 struct parser *parser;
321 parser = parser_load(info->lbid);
323 info->lb.size_list = 0x01; /* Default */
325 info->script = strdup(DEFAULT_SCRIPT);
327 ErrPrint("Heap: %s\n", strerror(errno));
328 return LB_STATUS_ERROR_MEMORY;
331 info->abi = strdup(DEFAULT_ABI);
333 ErrPrint("Heap: %s\n", strerror(errno));
334 DbgFree(info->script);
336 return LB_STATUS_ERROR_MEMORY;
339 info->pd.width = g_conf.width;
340 info->pd.height = g_conf.height >> 2;
342 return LB_STATUS_SUCCESS;
345 info->lb.type = LB_TYPE_FILE;
346 if (parser_text_lb(parser)) {
347 info->lb.type = LB_TYPE_TEXT;
348 } else if (parser_buffer_lb(parser)) {
349 info->lb.type = LB_TYPE_BUFFER;
351 str = parser_lb_path(parser);
353 info->lb.type = LB_TYPE_SCRIPT;
355 info->lb.info.script.path = strdup(str);
356 if (!info->lb.info.script.path) {
357 ErrPrint("Heap: %s\n", strerror(errno));
358 parser_unload(parser);
359 return LB_STATUS_ERROR_MEMORY;
362 str = parser_lb_group(parser);
364 info->lb.info.script.group = strdup(str);
365 if (!info->lb.info.script.group) {
366 ErrPrint("Heap: %s\n", strerror(errno));
367 DbgFree(info->lb.info.script.path);
368 parser_unload(parser);
369 return LB_STATUS_ERROR_MEMORY;
375 if (parser_text_pd(parser)) {
376 info->pd.type = PD_TYPE_TEXT;
377 } else if (parser_buffer_pd(parser)) {
378 info->pd.type = PD_TYPE_BUFFER;
380 str = parser_pd_path(parser);
382 info->pd.type = PD_TYPE_SCRIPT;
383 info->pd.info.script.path = strdup(str);
384 if (!info->pd.info.script.path) {
385 ErrPrint("Heap: %s\n", strerror(errno));
386 if (info->lb.type == LB_TYPE_SCRIPT) {
387 DbgFree(info->lb.info.script.path);
388 DbgFree(info->lb.info.script.group);
390 parser_unload(parser);
391 return LB_STATUS_ERROR_MEMORY;
394 str = parser_pd_group(parser);
396 info->pd.info.script.group = strdup(str);
397 if (!info->pd.info.script.group) {
398 ErrPrint("Heap: %s\n", strerror(errno));
399 DbgFree(info->pd.info.script.path);
400 if (info->lb.type == LB_TYPE_SCRIPT) {
401 DbgFree(info->lb.info.script.path);
402 DbgFree(info->lb.info.script.group);
404 parser_unload(parser);
405 return LB_STATUS_ERROR_MEMORY;
411 str = parser_script(parser);
412 str = str ? str : DEFAULT_SCRIPT;
413 info->script = strdup(str);
415 ErrPrint("Heap: %s\n", strerror(errno));
416 if (info->pd.type == PD_TYPE_SCRIPT) {
417 DbgFree(info->pd.info.script.path);
418 DbgFree(info->pd.info.script.group);
421 if (info->lb.type == LB_TYPE_SCRIPT) {
422 DbgFree(info->lb.info.script.path);
423 DbgFree(info->lb.info.script.group);
426 parser_unload(parser);
427 return LB_STATUS_ERROR_MEMORY;
430 str = parser_abi(parser);
431 str = str ? str : DEFAULT_ABI;
432 info->abi = strdup(str);
434 ErrPrint("Heap: %s\n", strerror(errno));
435 DbgFree(info->script);
436 if (info->pd.type == PD_TYPE_SCRIPT) {
437 DbgFree(info->pd.info.script.path);
438 DbgFree(info->pd.info.script.group);
441 if (info->lb.type == LB_TYPE_SCRIPT) {
442 DbgFree(info->lb.info.script.path);
443 DbgFree(info->lb.info.script.group);
445 parser_unload(parser);
446 return LB_STATUS_ERROR_MEMORY;
449 info->lb.timeout = parser_timeout(parser);
450 info->network = parser_network(parser);
452 info->lb.period = parser_period(parser);
453 if (info->lb.period < 0.0f) {
454 info->lb.period = 0.0f;
455 } else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD) {
456 info->lb.period = MINIMUM_PERIOD;
459 info->lb.size_list = parser_size(parser);
461 str = parser_auto_launch(parser);
462 str = str ? str : "";
463 info->lb.auto_launch = strdup(str);
464 if (!info->lb.auto_launch) {
465 ErrPrint("Heap: %s\n", strerror(errno));
467 DbgFree(info->script);
468 if (info->pd.type == PD_TYPE_SCRIPT) {
469 DbgFree(info->pd.info.script.path);
470 DbgFree(info->pd.info.script.group);
473 if (info->lb.type == LB_TYPE_SCRIPT) {
474 DbgFree(info->lb.info.script.path);
475 DbgFree(info->lb.info.script.group);
477 parser_unload(parser);
478 return LB_STATUS_ERROR_MEMORY;
481 info->secured = parser_secured(parser);
482 info->lb.pinup = parser_pinup(parser);
484 parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
486 group = parser_group_str(parser);
487 if (group && group_add_livebox(group, info->lbid) < 0) {
488 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->lbid, group);
491 parser_unload(parser);
492 return LB_STATUS_SUCCESS;
495 HAPI struct pkg_info *package_create(const char *pkgid, const char *lbid)
497 struct pkg_info *pkginfo;
499 pkginfo = calloc(1, sizeof(*pkginfo));
501 ErrPrint("Heap: %s\n", strerror(errno));
505 pkginfo->pkgid = strdup(pkgid);
506 if (!pkginfo->pkgid) {
507 ErrPrint("Heap: %s\n", strerror(errno));
512 pkginfo->lbid = io_livebox_pkgname(lbid);
513 if (!pkginfo->lbid) {
514 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
515 if (util_validate_livebox_package(lbid) < 0) {
516 ErrPrint("Invalid package name: %s\n", lbid);
517 DbgFree(pkginfo->pkgid);
522 pkginfo->lbid = strdup(lbid);
523 if (!pkginfo->lbid) {
524 ErrPrint("Heap: %s\n", strerror(errno));
525 DbgFree(pkginfo->pkgid);
531 if (io_load_package_db(pkginfo) < 0) {
532 ErrPrint("Failed to load DB, fall back to conf file loader\n");
533 if (load_conf(pkginfo) < 0) {
534 ErrPrint("Failed to initiate the conf file loader\n");
535 DbgFree(pkginfo->lbid);
536 DbgFree(pkginfo->pkgid);
542 package_ref(pkginfo);
544 s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
549 HAPI int package_destroy(struct pkg_info *info)
552 return LB_STATUS_SUCCESS;
555 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
557 return pkginfo->ctx_list;
560 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
562 pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
565 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
567 pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
570 HAPI char *package_lb_pkgname(const char *pkgname)
574 lbid = io_livebox_pkgname(pkgname);
576 if (util_validate_livebox_package(pkgname) < 0) {
580 lbid = strdup(pkgname);
582 ErrPrint("Heap: %s\n", strerror(errno));
590 HAPI int package_is_lb_pkgname(const char *pkgname)
595 lbid = package_lb_pkgname(pkgname);
602 HAPI struct pkg_info *package_find(const char *lbid)
605 struct pkg_info *info;
611 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
612 if (!strcmp(info->lbid, lbid)) {
620 HAPI struct inst_info *package_find_instance_by_id(const char *lbid, const char *id)
623 struct inst_info *inst;
624 struct pkg_info *info;
626 info = package_find(lbid);
628 ErrPrint("Package %s is not exists\n", lbid);
632 EINA_LIST_FOREACH(info->inst_list, l, inst) {
633 if (!strcmp(instance_id(inst), id)) {
641 HAPI struct inst_info *package_find_instance_by_timestamp(const char *lbid, double timestamp)
644 struct inst_info *inst;
645 struct pkg_info *info;
647 info = package_find(lbid);
649 ErrPrint("Package %s is not exists\n", lbid);
653 EINA_LIST_FOREACH(info->inst_list, l, inst) {
654 if (instance_timestamp(inst) == timestamp) {
662 HAPI int package_dump_fault_info(struct pkg_info *info)
664 if (!info->fault_info) {
665 return LB_STATUS_ERROR_NOT_EXIST;
668 CRITICAL_LOG("=============\n");
669 CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
670 CRITICAL_LOG("Package: %s\n", info->lbid);
671 CRITICAL_LOG("Function: %s\n", info->fault_info->function);
672 CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
673 return LB_STATUS_SUCCESS;
676 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
678 if (!info->fault_info) {
679 return LB_STATUS_ERROR_NOT_EXIST;
682 *timestamp = info->fault_info->timestamp;
683 *filename = info->fault_info->filename;
684 *function = info->fault_info->function;
685 return LB_STATUS_SUCCESS;
688 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
690 struct fault_info *fault;
692 package_clear_fault(info);
694 fault = calloc(1, sizeof(*fault));
696 ErrPrint("Heap: %s\n", strerror(errno));
697 return LB_STATUS_ERROR_MEMORY;
700 fault->timestamp = timestamp;
702 filename = "unknown";
705 function = "unknown";
708 fault->filename = strdup(filename);
709 if (!fault->filename) {
710 ErrPrint("Heap: %s\n", strerror(errno));
712 return LB_STATUS_ERROR_MEMORY;
715 fault->function = strdup(function);
716 if (!fault->function) {
717 ErrPrint("Heap: %s\n", strerror(errno));
718 DbgFree(fault->filename);
720 return LB_STATUS_ERROR_MEMORY;
723 info->fault_info = fault;
725 return LB_STATUS_SUCCESS;
728 HAPI int package_clear_fault(struct pkg_info *info)
730 if (!info->fault_info) {
731 return LB_STATUS_ERROR_INVALID;
734 package_dump_fault_info(info);
736 DbgFree(info->fault_info->function);
737 DbgFree(info->fault_info->filename);
738 DbgFree(info->fault_info);
739 info->fault_info = NULL;
740 return LB_STATUS_SUCCESS;
743 HAPI const int const package_is_fault(const struct pkg_info *info)
745 return !!info->fault_info;
748 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
753 HAPI const int const package_timeout(const struct pkg_info *info)
755 return info->lb.timeout;
758 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
760 info->lb.timeout = timeout;
763 HAPI const double const package_period(const struct pkg_info *info)
765 return info->lb.period;
768 HAPI void package_set_period(struct pkg_info *info, double period)
770 info->lb.period = period;
773 HAPI const int const package_secured(const struct pkg_info *info)
775 return info->secured;
778 HAPI void package_set_secured(struct pkg_info *info, int secured)
780 info->secured = secured;
783 HAPI const char * const package_script(const struct pkg_info *info)
788 HAPI int package_set_script(struct pkg_info *info, const char *script)
792 tmp = strdup(script);
794 ErrPrint("Heap: %s\n", strerror(errno));
795 return LB_STATUS_ERROR_MEMORY;
798 DbgFree(info->script);
800 return LB_STATUS_SUCCESS;
803 HAPI const char * const package_abi(const struct pkg_info *info)
808 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
813 ErrPrint("Heap: %s\n", strerror(errno));
814 return LB_STATUS_ERROR_MEMORY;
819 return LB_STATUS_SUCCESS;
822 HAPI const char * const package_lb_path(const struct pkg_info *info)
824 if (info->lb.type != LB_TYPE_SCRIPT) {
828 return info->lb.info.script.path;
831 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
835 if (info->lb.type != LB_TYPE_SCRIPT) {
836 return LB_STATUS_ERROR_INVALID;
841 ErrPrint("Heap: %s\n", strerror(errno));
842 return LB_STATUS_ERROR_MEMORY;
845 DbgFree(info->lb.info.script.path);
846 info->lb.info.script.path = tmp;
847 return LB_STATUS_SUCCESS;
850 HAPI const char * const package_lb_group(const struct pkg_info *info)
852 if (info->lb.type != LB_TYPE_SCRIPT) {
856 return info->lb.info.script.group;
859 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
863 if (info->lb.type != LB_TYPE_SCRIPT) {
864 return LB_STATUS_ERROR_INVALID;
869 ErrPrint("Heap: %s\n", strerror(errno));
870 return LB_STATUS_ERROR_MEMORY;
873 DbgFree(info->lb.info.script.group);
874 info->lb.info.script.group = tmp;
875 return LB_STATUS_SUCCESS;
878 HAPI const char * const package_pd_path(const struct pkg_info *info)
880 if (info->pd.type != PD_TYPE_SCRIPT) {
884 return info->pd.info.script.path;
887 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
891 if (info->pd.type != PD_TYPE_SCRIPT) {
892 return LB_STATUS_ERROR_INVALID;
897 ErrPrint("Heap: %s\n", strerror(errno));
898 return LB_STATUS_ERROR_MEMORY;
901 DbgFree(info->pd.info.script.path);
902 info->pd.info.script.path = tmp;
903 return LB_STATUS_SUCCESS;
906 HAPI const char * const package_pd_group(const struct pkg_info *info)
908 if (info->pd.type != PD_TYPE_SCRIPT) {
912 return info->pd.info.script.group;
915 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
919 if (info->pd.type != PD_TYPE_SCRIPT) {
920 return LB_STATUS_ERROR_INVALID;
925 ErrPrint("Heap: %s\n", strerror(errno));
926 return LB_STATUS_ERROR_MEMORY;
929 DbgFree(info->pd.info.script.group);
930 info->pd.info.script.group = tmp;
931 return LB_STATUS_SUCCESS;
934 HAPI const int const package_pinup(const struct pkg_info *info)
936 return info->lb.pinup;
939 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
941 info->lb.pinup = pinup;
944 HAPI const char * const package_auto_launch(const struct pkg_info *info)
946 return info->lb.auto_launch;
949 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
955 info->lb.auto_launch = strdup(auto_launch);
956 if (!info->lb.auto_launch) {
957 ErrPrint("Heap: %s\n", strerror(errno));
962 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
964 return info->lb.size_list;
967 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
969 info->lb.size_list = size_list;
972 HAPI const int const package_pd_width(const struct pkg_info *info)
974 return info->pd.width;
977 HAPI void package_set_pd_width(struct pkg_info *info, int width)
979 info->pd.width = width;
982 HAPI const int const package_pd_height(const struct pkg_info *info)
984 return info->pd.height;
987 HAPI void package_set_pd_height(struct pkg_info *info, int height)
989 info->pd.height = height;
992 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
998 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
1000 if (info->refcnt == 0) {
1001 ErrPrint("Invalid request\n");
1006 if (info->refcnt == 0) {
1007 destroy_package(info);
1014 HAPI const int const package_refcnt(const struct pkg_info *info)
1016 return info->refcnt;
1019 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
1021 return info->lb.type;
1024 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
1026 info->lb.type = type;
1029 HAPI const char * const package_libexec(struct pkg_info *info)
1031 return info->lb.libexec;
1034 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1038 tmp = strdup(libexec);
1040 ErrPrint("Heap: %s\n", strerror(errno));
1041 return LB_STATUS_ERROR_MEMORY;
1044 DbgFree(info->lb.libexec);
1045 info->lb.libexec = tmp;
1046 return LB_STATUS_SUCCESS;
1049 HAPI int package_network(struct pkg_info *info)
1051 return info->network;
1054 HAPI void package_set_network(struct pkg_info *info, int network)
1056 info->network = network;
1059 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
1061 return info->pd.type;
1064 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
1066 info->pd.type = type;
1071 * Add the instance to the package info.
1072 * If a package has no slave, assign a new slave.
1074 static inline int assign_new_slave(struct pkg_info *info)
1080 s_name = util_slavename();
1082 ErrPrint("Failed to get a new slave name\n");
1083 return LB_STATUS_ERROR_FAULT;
1086 tmp = abi_find_slave(info->abi);
1089 ErrPrint("Failed to find a proper pkgname of a slave\n");
1090 return LB_STATUS_ERROR_INVALID;
1093 s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->lbid);
1095 DbgPrint("Failed to get replaced string\n");
1096 s_pkgname = strdup(tmp);
1098 ErrPrint("Heap: %s\n", strerror(errno));
1100 return LB_STATUS_ERROR_MEMORY;
1104 DbgPrint("New slave[%s] is assigned for %s (using %s / abi[%s])\n", s_name, info->lbid, s_pkgname, info->abi);
1105 info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname, info->network);
1113 * package_destroy will try to remove "info" from the pkg_list.
1114 * but we didn't add this to it yet.
1115 * If the list method couldn't find an "info" from the list,
1116 * it just do nothing so I'll leave this.
1118 return LB_STATUS_ERROR_FAULT;
1122 * Slave is not activated yet.
1124 return LB_STATUS_SUCCESS;
1127 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1129 if (!info->inst_list) {
1130 info->slave = slave_find_available(info->abi, info->secured, info->network);
1135 ret = assign_new_slave(info);
1140 DbgPrint("Slave %s is used for %s\n", slave_name(info->slave), info->lbid);
1143 slave_ref(info->slave);
1144 slave_load_package(info->slave);
1145 slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1146 slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1147 slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1149 if (info->secured) {
1150 slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1151 slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1155 * In case of the slave is terminated because of expired TTL timer,
1156 * Master should freeze the all update time.
1157 * But the callback should check the slave's state to prevent from duplicated freezing.
1159 * This callback will freeze the timer only if a slave doesn't running.
1161 xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1162 xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1166 info->inst_list = eina_list_append(info->inst_list, inst);
1167 return LB_STATUS_SUCCESS;
1170 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1172 info->inst_list = eina_list_remove(info->inst_list, inst);
1174 if (info->inst_list) {
1175 return LB_STATUS_SUCCESS;
1179 slave_unload_package(info->slave);
1181 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1182 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1183 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1185 if (info->secured) {
1186 slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1187 slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1189 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1190 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1193 slave_unref(info->slave);
1197 if (info->is_uninstalled) {
1198 package_destroy(info);
1201 return LB_STATUS_SUCCESS;
1204 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1206 return info->inst_list;
1209 static int client_created_cb(struct client_node *client, void *data)
1211 struct pkg_info *info;
1214 struct inst_info *inst;
1217 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1218 if (info->fault_info) {
1219 fault_unicast_info(client, info->lbid, info->fault_info->filename, info->fault_info->function);
1223 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1224 switch (instance_state(inst)) {
1226 /* Will be send a created event after the instance gets created event */
1228 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1229 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1230 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1231 if (instance_client(inst) == client) {
1232 instance_unicast_created_event(inst, client);
1233 } else if (instance_client(inst) == NULL) {
1236 * Instances are lives in the system cluster/sub-cluster
1238 if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1239 instance_unicast_created_event(inst, client);
1240 DbgPrint("(Subscribed) Created package: %s\n", info->lbid);
1246 DbgPrint("%s(%s) is not activated (%d)\n",
1247 package_name(info), instance_id(inst), instance_state(inst));
1256 static int io_uninstall_cb(const char *pkgid, const char *lbid, int prime, void *data)
1258 struct pkg_info *info;
1261 struct inst_info *inst;
1263 DbgPrint("Package %s is uninstalled\n", lbid);
1264 info = package_find(lbid);
1266 DbgPrint("%s is not yet loaded\n", lbid);
1270 info->is_uninstalled = 1;
1274 * Don't delete an item from the inst_list.
1275 * destroy callback will use this list again.
1276 * So, Don't touch it from here.
1278 if (info->inst_list) {
1279 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1280 instance_destroy(inst, INSTANCE_DESTROY_PKGMGR);
1283 package_destroy(info);
1289 static inline void reload_package_info(struct pkg_info *info)
1293 struct inst_info *inst;
1294 unsigned int size_type;
1298 DbgPrint("Already exists, try to update it\n");
1300 group_del_livebox(info->lbid);
1301 package_clear_fault(info);
1307 io_load_package_db(info);
1311 * Without "is_uninstalled", the package will be kept
1313 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1314 width = instance_lb_width(inst);
1315 height = instance_lb_height(inst);
1316 size_type = livebox_service_size_type(width, height);
1317 if (info->lb.size_list & size_type) {
1318 instance_reload(inst, INSTANCE_DESTROY_PKGMGR);
1320 instance_destroy(inst, INSTANCE_DESTROY_PKGMGR);
1325 static int io_install_cb(const char *pkgid, const char *lbid, int prime, void *data)
1327 struct pkg_info *info;
1329 info = package_find(lbid);
1332 * Already exists. skip to create this.
1337 info = package_create(pkgid, lbid);
1339 ErrPrint("Failed to build an info %s\n", lbid);
1341 DbgPrint("Livebox %s is built\n", lbid);
1347 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1351 struct pkg_info *info;
1353 if (status != PKGMGR_STATUS_END) {
1357 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1358 if (!strcmp(info->pkgid, pkgname)) {
1359 io_uninstall_cb(pkgname, info->lbid, -1, NULL);
1366 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1370 struct pkg_info *info;
1372 if (status != PKGMGR_STATUS_END) {
1376 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1377 if (!strcmp(info->pkgid, pkgname)) {
1378 DbgPrint("Update lbid: %s\n", info->lbid);
1379 if (io_is_exists(info->lbid) == 1) {
1380 reload_package_info(info);
1382 io_uninstall_cb(pkgname, info->lbid, -1, NULL);
1387 (void)io_update_livebox_package(pkgname, io_install_cb, NULL);
1391 static int crawling_liveboxes(const char *pkgid, const char *lbid, int prime, void *data)
1393 if (package_find(lbid)) {
1394 ErrPrint("Information of %s is already built\n", lbid);
1396 struct pkg_info *info;
1397 info = package_create(pkgid, lbid);
1399 DbgPrint("[%s] information is built prime(%d)\n", lbid, prime);
1406 HAPI int package_init(void)
1408 client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1411 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1412 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1413 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1415 io_crawling_liveboxes(crawling_liveboxes, NULL);
1419 HAPI int package_fini(void)
1425 struct pkg_info *info;
1426 struct inst_info *inst;
1428 pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1429 pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1430 pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1432 client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1434 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
1435 EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
1436 instance_state_reset(inst);
1437 instance_destroy(inst, INSTANCE_DESTROY_TERMINATE);
1440 package_destroy(info);
1446 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1449 struct pkg_info *info;
1451 if (!slave_is_secured(slave)) {
1455 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1456 if (info->slave == slave) {
1464 HAPI const char * const package_name(const struct pkg_info *info)
1470 * del_or_creat : 1 == create, 0 == delete
1472 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1474 struct pkg_info *info;
1477 struct inst_info *inst;
1480 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1481 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1482 if (instance_client(inst)) {
1486 if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1490 switch (instance_state(inst)) {
1492 case INST_REQUEST_TO_ACTIVATE:
1493 /* Will be send a created event after the instance gets created event */
1496 if (!instance_has_client(inst, client)) {
1497 instance_add_client(inst, client);
1501 if (instance_has_client(inst, client)) {
1502 instance_del_client(inst, client);
1509 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1510 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1511 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1514 * Instances are lives in the system cluster/sub-cluster
1518 if (!instance_has_client(inst, client)) {
1519 instance_unicast_created_event(inst, client);
1520 instance_add_client(inst, client);
1521 DbgPrint("(Subscribed) Created package: %s\n", info->lbid);
1525 if (instance_has_client(inst, client)) {
1526 instance_unicast_deleted_event(inst, client);
1527 instance_del_client(inst, client);
1536 DbgPrint("%s(%s) is not activated (%d)\n",
1537 package_name(info), instance_id(inst), instance_state(inst));
1546 HAPI const Eina_List *package_list(void)
1548 return s_info.pkg_list;
1551 HAPI int const package_fault_count(struct pkg_info *info)
1553 return info ? info->fault_count : 0;
1556 HAPI int package_is_enabled(const char *appid)
1562 ret = ail_get_appinfo(appid, &ai);
1563 if (ret != AIL_ERROR_OK) {
1564 ErrPrint("Unable to get appinfo: %d\n", ret);
1568 if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK) {
1572 ail_destroy_appinfo(ai);
1574 return enabled == true;