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>
30 #include "critical_log.h"
35 #include "slave_life.h"
36 #include "slave_rpc.h"
37 #include "client_life.h"
39 #include "fault_manager.h"
41 #include "script_handler.h"
57 * pkg_info describes the loaded package.
73 /*!< Reserved for future use */
77 /*!< Reserved for future use */
81 /*!< Reserved for future use */
85 unsigned int size_list;
103 /*!< Reserved for future use */
107 /*!< Reserved for future use */
117 char *script; /* script type: edje, ... */
121 struct fault_info *fault_info;
123 struct slave_node *slave;
126 Eina_List *inst_list;
138 static int slave_activated_cb(struct slave_node *slave, void *data)
140 struct pkg_info *info = data;
141 struct inst_info *inst;
147 if (!slave_need_to_reactivate_instances(slave)) {
148 DbgPrint("Do not need to reactivate instances\n");
153 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
154 ret = instance_recover_state(inst);
158 instance_thaw_updator(inst);
162 DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
166 static int slave_fault_cb(struct slave_node *slave, void *data)
170 struct inst_info *inst;
171 struct pkg_info *info = (struct pkg_info *)data;
173 if (package_is_fault(info)) {
174 ErrPrint("Already faulted package: %s\n", package_name(info));
178 (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
179 fault_broadcast_info(package_name(info), slave_name(slave), __func__);
181 DbgPrint("Slave critical fault - package: %s (by slave fault %s\n", package_name(info), slave_name(slave));
182 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
183 DbgPrint("Destroy instance %p\n", inst);
184 instance_destroyed(inst);
190 static int slave_deactivated_cb(struct slave_node *slave, void *data)
192 struct pkg_info *info = data;
193 struct inst_info *inst;
198 if (info->fault_info) {
199 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
200 instance_destroyed(inst);
203 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
204 cnt += instance_need_slave(inst);
206 * instance_deactivated will call the slave_unload_instance.
207 * if the loaded instance counter meets 0,
208 * the slave will be deactivated.
209 * so we should not call the instance activate function
212 * activate slave when the slave is reactivated
217 return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
220 static int xmonitor_paused_cb(void *data)
222 struct pkg_info *info = (struct pkg_info *)data;
223 struct inst_info *inst;
226 if (slave_state(info->slave) != SLAVE_TERMINATED) {
227 DbgPrint("Skip this\n");
231 EINA_LIST_FOREACH(info->inst_list, l, inst) {
232 instance_freeze_updator(inst);
238 static int xmonitor_resumed_cb(void *data)
240 struct pkg_info *info = data;
241 struct inst_info *inst;
244 if (slave_state(info->slave) != SLAVE_TERMINATED) {
245 DbgPrint("Skip this\n");
249 EINA_LIST_FOREACH(info->inst_list, l, inst) {
250 instance_thaw_updator(inst);
256 static int slave_paused_cb(struct slave_node *slave, void *data)
258 struct pkg_info *info = (struct pkg_info *)data;
259 struct inst_info *inst;
262 EINA_LIST_FOREACH(info->inst_list, l, inst) {
263 instance_freeze_updator(inst);
269 static int slave_resumed_cb(struct slave_node *slave, void *data)
271 struct pkg_info *info = (struct pkg_info *)data;
272 struct inst_info *inst;
275 EINA_LIST_FOREACH(info->inst_list, l, inst) {
276 instance_thaw_updator(inst);
282 static inline void destroy_package(struct pkg_info *info)
284 struct context_info *ctx_info;
285 EINA_LIST_FREE(info->ctx_list, ctx_info) {
286 /* This items will be deleted from group_del_livebox */
289 group_del_livebox(info->pkgname);
290 package_clear_fault(info);
292 s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
294 if (info->lb.type == LB_TYPE_SCRIPT) {
295 DbgFree(info->lb.info.script.path);
296 DbgFree(info->lb.info.script.group);
299 if (info->pd.type == PD_TYPE_SCRIPT) {
300 DbgFree(info->pd.info.script.path);
301 DbgFree(info->pd.info.script.group);
304 DbgFree(info->script);
306 DbgFree(info->pkgname);
307 DbgFree(info->lb.libexec);
308 DbgFree(info->lb.auto_launch);
313 static inline int load_conf(struct pkg_info *info)
315 struct parser *parser;
319 parser = parser_load(info->pkgname);
321 info->lb.size_list = 0x01; /* Default */
323 info->script = strdup(DEFAULT_SCRIPT);
325 ErrPrint("Heap: %s\n", strerror(errno));
326 return LB_STATUS_ERROR_MEMORY;
329 info->abi = strdup(DEFAULT_ABI);
331 ErrPrint("Heap: %s\n", strerror(errno));
332 DbgFree(info->script);
334 return LB_STATUS_ERROR_MEMORY;
337 info->pd.width = g_conf.width;
338 info->pd.height = g_conf.height >> 2;
340 return LB_STATUS_SUCCESS;
343 info->lb.type = LB_TYPE_FILE;
344 if (parser_text_lb(parser)) {
345 info->lb.type = LB_TYPE_TEXT;
346 } else if (parser_buffer_lb(parser)) {
347 info->lb.type = LB_TYPE_BUFFER;
349 str = parser_lb_path(parser);
351 info->lb.type = LB_TYPE_SCRIPT;
353 info->lb.info.script.path = strdup(str);
354 if (!info->lb.info.script.path) {
355 ErrPrint("Heap: %s\n", strerror(errno));
356 parser_unload(parser);
357 return LB_STATUS_ERROR_MEMORY;
360 str = parser_lb_group(parser);
362 info->lb.info.script.group = strdup(str);
363 if (!info->lb.info.script.group) {
364 ErrPrint("Heap: %s\n", strerror(errno));
365 DbgFree(info->lb.info.script.path);
366 parser_unload(parser);
367 return LB_STATUS_ERROR_MEMORY;
373 if (parser_text_pd(parser)) {
374 info->pd.type = PD_TYPE_TEXT;
375 } else if (parser_buffer_pd(parser)) {
376 info->pd.type = PD_TYPE_BUFFER;
378 str = parser_pd_path(parser);
380 info->pd.type = PD_TYPE_SCRIPT;
381 info->pd.info.script.path = strdup(str);
382 if (!info->pd.info.script.path) {
383 ErrPrint("Heap: %s\n", strerror(errno));
384 if (info->lb.type == LB_TYPE_SCRIPT) {
385 DbgFree(info->lb.info.script.path);
386 DbgFree(info->lb.info.script.group);
388 parser_unload(parser);
389 return LB_STATUS_ERROR_MEMORY;
392 str = parser_pd_group(parser);
394 info->pd.info.script.group = strdup(str);
395 if (!info->pd.info.script.group) {
396 ErrPrint("Heap: %s\n", strerror(errno));
397 DbgFree(info->pd.info.script.path);
398 if (info->lb.type == LB_TYPE_SCRIPT) {
399 DbgFree(info->lb.info.script.path);
400 DbgFree(info->lb.info.script.group);
402 parser_unload(parser);
403 return LB_STATUS_ERROR_MEMORY;
409 str = parser_script(parser);
410 str = str ? str : DEFAULT_SCRIPT;
411 info->script = strdup(str);
413 ErrPrint("Heap: %s\n", strerror(errno));
414 if (info->pd.type == PD_TYPE_SCRIPT) {
415 DbgFree(info->pd.info.script.path);
416 DbgFree(info->pd.info.script.group);
419 if (info->lb.type == LB_TYPE_SCRIPT) {
420 DbgFree(info->lb.info.script.path);
421 DbgFree(info->lb.info.script.group);
424 parser_unload(parser);
425 return LB_STATUS_ERROR_MEMORY;
428 str = parser_abi(parser);
429 str = str ? str : DEFAULT_ABI;
430 info->abi = strdup(str);
432 ErrPrint("Heap: %s\n", strerror(errno));
433 DbgFree(info->script);
434 if (info->pd.type == PD_TYPE_SCRIPT) {
435 DbgFree(info->pd.info.script.path);
436 DbgFree(info->pd.info.script.group);
439 if (info->lb.type == LB_TYPE_SCRIPT) {
440 DbgFree(info->lb.info.script.path);
441 DbgFree(info->lb.info.script.group);
443 parser_unload(parser);
444 return LB_STATUS_ERROR_MEMORY;
447 info->lb.timeout = parser_timeout(parser);
448 info->network = parser_network(parser);
450 info->lb.period = parser_period(parser);
451 if (info->lb.period < 0.0f)
452 info->lb.period = 0.0f;
453 else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD)
454 info->lb.period = MINIMUM_PERIOD;
456 info->lb.size_list = parser_size(parser);
458 str = parser_auto_launch(parser);
459 str = str ? str : "";
460 info->lb.auto_launch = strdup(str);
461 if (!info->lb.auto_launch) {
462 ErrPrint("Heap: %s\n", strerror(errno));
464 DbgFree(info->script);
465 if (info->pd.type == PD_TYPE_SCRIPT) {
466 DbgFree(info->pd.info.script.path);
467 DbgFree(info->pd.info.script.group);
470 if (info->lb.type == LB_TYPE_SCRIPT) {
471 DbgFree(info->lb.info.script.path);
472 DbgFree(info->lb.info.script.group);
474 parser_unload(parser);
475 return LB_STATUS_ERROR_MEMORY;
478 info->secured = parser_secured(parser);
479 info->lb.pinup = parser_pinup(parser);
481 parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
483 group = parser_group_str(parser);
484 if (group && group_add_livebox(group, info->pkgname) < 0)
485 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->pkgname, group);
487 parser_unload(parser);
488 return LB_STATUS_SUCCESS;
491 HAPI struct pkg_info *package_create(const char *pkgname)
493 struct pkg_info *pkginfo;
495 pkginfo = calloc(1, sizeof(*pkginfo));
497 ErrPrint("Heap: %s\n", strerror(errno));
501 pkginfo->pkgname = io_livebox_pkgname(pkgname);
502 if (!pkginfo->pkgname) {
503 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
504 if (util_validate_livebox_package(pkgname) < 0) {
505 ErrPrint("Invalid package name: %s\n", pkgname);
510 pkginfo->pkgname = strdup(pkgname);
511 if (!pkginfo->pkgname) {
512 ErrPrint("Heap: %s\n", strerror(errno));
518 if (io_load_package_db(pkginfo) < 0) {
519 ErrPrint("Failed to load DB, fall back to conf file loader\n");
520 if (load_conf(pkginfo) < 0) {
521 ErrPrint("Failed to initiate the conf file loader\n");
522 DbgFree(pkginfo->pkgname);
528 package_ref(pkginfo);
530 s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
535 HAPI int package_destroy(struct pkg_info *info)
538 return LB_STATUS_SUCCESS;
541 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
543 return pkginfo->ctx_list;
546 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
548 pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
551 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
553 pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
556 HAPI char *package_lb_pkgname(const char *pkgname)
560 lb_pkgname = io_livebox_pkgname(pkgname);
562 if (util_validate_livebox_package(pkgname) < 0)
565 lb_pkgname = strdup(pkgname);
567 ErrPrint("Heap: %s\n", strerror(errno));
575 HAPI int package_is_lb_pkgname(const char *pkgname)
580 lb_pkgname = package_lb_pkgname(pkgname);
587 HAPI struct pkg_info *package_find(const char *pkgname)
590 struct pkg_info *info;
595 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
596 if (!strcmp(info->pkgname, pkgname))
603 HAPI struct inst_info *package_find_instance_by_id(const char *pkgname, const char *id)
606 struct inst_info *inst;
607 struct pkg_info *info;
609 info = package_find(pkgname);
611 ErrPrint("Package %s is not exists\n", pkgname);
615 EINA_LIST_FOREACH(info->inst_list, l, inst) {
616 if (!strcmp(instance_id(inst), id))
623 HAPI struct inst_info *package_find_instance_by_timestamp(const char *pkgname, double timestamp)
626 struct inst_info *inst;
627 struct pkg_info *info;
629 info = package_find(pkgname);
631 ErrPrint("Package %s is not exists\n", pkgname);
635 EINA_LIST_FOREACH(info->inst_list, l, inst) {
636 if (instance_timestamp(inst) == timestamp)
643 HAPI int package_dump_fault_info(struct pkg_info *info)
645 if (!info->fault_info)
646 return LB_STATUS_ERROR_NOT_EXIST;
648 CRITICAL_LOG("=============\n");
649 CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
650 CRITICAL_LOG("Package: %s\n", info->pkgname);
651 CRITICAL_LOG("Function: %s\n", info->fault_info->function);
652 CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
653 return LB_STATUS_SUCCESS;
656 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
658 if (!info->fault_info)
659 return LB_STATUS_ERROR_NOT_EXIST;
661 *timestamp = info->fault_info->timestamp;
662 *filename = info->fault_info->filename;
663 *function = info->fault_info->function;
664 return LB_STATUS_SUCCESS;
667 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
669 struct fault_info *fault;
671 package_clear_fault(info);
673 fault = calloc(1, sizeof(*fault));
675 ErrPrint("Heap: %s\n", strerror(errno));
676 return LB_STATUS_ERROR_MEMORY;
679 fault->timestamp = timestamp;
681 filename = "unknown";
683 function = "unknown";
685 fault->filename = strdup(filename);
686 if (!fault->filename) {
687 ErrPrint("Heap: %s\n", strerror(errno));
689 return LB_STATUS_ERROR_MEMORY;
692 fault->function = strdup(function);
693 if (!fault->function) {
694 ErrPrint("Heap: %s\n", strerror(errno));
695 DbgFree(fault->filename);
697 return LB_STATUS_ERROR_MEMORY;
700 info->fault_info = fault;
702 return LB_STATUS_SUCCESS;
705 HAPI int package_clear_fault(struct pkg_info *info)
707 if (!info->fault_info)
708 return LB_STATUS_ERROR_INVALID;
710 package_dump_fault_info(info);
712 DbgFree(info->fault_info->function);
713 DbgFree(info->fault_info->filename);
714 DbgFree(info->fault_info);
715 info->fault_info = NULL;
716 return LB_STATUS_SUCCESS;
719 HAPI const int const package_is_fault(const struct pkg_info *info)
721 return !!info->fault_info;
724 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
729 HAPI const int const package_timeout(const struct pkg_info *info)
731 return info->lb.timeout;
734 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
736 info->lb.timeout = timeout;
739 HAPI const double const package_period(const struct pkg_info *info)
741 return info->lb.period;
744 HAPI void package_set_period(struct pkg_info *info, double period)
746 info->lb.period = period;
749 HAPI const int const package_secured(const struct pkg_info *info)
751 return info->secured;
754 HAPI void package_set_secured(struct pkg_info *info, int secured)
756 info->secured = secured;
759 HAPI const char * const package_script(const struct pkg_info *info)
764 HAPI int package_set_script(struct pkg_info *info, const char *script)
768 tmp = strdup(script);
770 ErrPrint("Heap: %s\n", strerror(errno));
771 return LB_STATUS_ERROR_MEMORY;
774 DbgFree(info->script);
776 return LB_STATUS_SUCCESS;
779 HAPI const char * const package_abi(const struct pkg_info *info)
784 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
789 ErrPrint("Heap: %s\n", strerror(errno));
790 return LB_STATUS_ERROR_MEMORY;
795 return LB_STATUS_SUCCESS;
798 HAPI const char * const package_lb_path(const struct pkg_info *info)
800 if (info->lb.type != LB_TYPE_SCRIPT)
803 return info->lb.info.script.path;
806 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
810 if (info->lb.type != LB_TYPE_SCRIPT)
811 return LB_STATUS_ERROR_INVALID;
815 ErrPrint("Heap: %s\n", strerror(errno));
816 return LB_STATUS_ERROR_MEMORY;
819 DbgFree(info->lb.info.script.path);
820 info->lb.info.script.path = tmp;
821 return LB_STATUS_SUCCESS;
824 HAPI const char * const package_lb_group(const struct pkg_info *info)
826 if (info->lb.type != LB_TYPE_SCRIPT)
829 return info->lb.info.script.group;
832 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
836 if (info->lb.type != LB_TYPE_SCRIPT)
837 return LB_STATUS_ERROR_INVALID;
841 ErrPrint("Heap: %s\n", strerror(errno));
842 return LB_STATUS_ERROR_MEMORY;
845 DbgFree(info->lb.info.script.group);
846 info->lb.info.script.group = tmp;
847 return LB_STATUS_SUCCESS;
850 HAPI const char * const package_pd_path(const struct pkg_info *info)
852 if (info->pd.type != PD_TYPE_SCRIPT)
855 return info->pd.info.script.path;
858 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
862 if (info->pd.type != PD_TYPE_SCRIPT)
863 return LB_STATUS_ERROR_INVALID;
867 ErrPrint("Heap: %s\n", strerror(errno));
868 return LB_STATUS_ERROR_MEMORY;
871 DbgFree(info->pd.info.script.path);
872 info->pd.info.script.path = tmp;
873 return LB_STATUS_SUCCESS;
876 HAPI const char * const package_pd_group(const struct pkg_info *info)
878 if (info->pd.type != PD_TYPE_SCRIPT)
881 return info->pd.info.script.group;
884 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
888 if (info->pd.type != PD_TYPE_SCRIPT)
889 return LB_STATUS_ERROR_INVALID;
893 ErrPrint("Heap: %s\n", strerror(errno));
894 return LB_STATUS_ERROR_MEMORY;
897 DbgFree(info->pd.info.script.group);
898 info->pd.info.script.group = tmp;
899 return LB_STATUS_SUCCESS;
902 HAPI const int const package_pinup(const struct pkg_info *info)
904 return info->lb.pinup;
907 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
909 info->lb.pinup = pinup;
912 HAPI const char * const package_auto_launch(const struct pkg_info *info)
914 return info->lb.auto_launch;
917 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
922 info->lb.auto_launch = strdup(auto_launch);
923 if (!info->lb.auto_launch) {
924 ErrPrint("Heap: %s\n", strerror(errno));
929 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
931 return info->lb.size_list;
934 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
936 info->lb.size_list = size_list;
939 HAPI const int const package_pd_width(const struct pkg_info *info)
941 return info->pd.width;
944 HAPI void package_set_pd_width(struct pkg_info *info, int width)
946 info->pd.width = width;
949 HAPI const int const package_pd_height(const struct pkg_info *info)
951 return info->pd.height;
954 HAPI void package_set_pd_height(struct pkg_info *info, int height)
956 info->pd.height = height;
959 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
965 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
967 if (info->refcnt == 0) {
968 ErrPrint("Invalid request\n");
973 if (info->refcnt == 0) {
974 destroy_package(info);
981 HAPI const int const package_refcnt(const struct pkg_info *info)
986 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
988 return info->lb.type;
991 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
993 info->lb.type = type;
996 HAPI const char * const package_libexec(struct pkg_info *info)
998 return info->lb.libexec;
1001 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1005 tmp = strdup(libexec);
1007 ErrPrint("Heap: %s\n", strerror(errno));
1008 return LB_STATUS_ERROR_MEMORY;
1011 DbgFree(info->lb.libexec);
1012 info->lb.libexec = tmp;
1013 return LB_STATUS_SUCCESS;
1016 HAPI int package_network(struct pkg_info *info)
1018 return info->network;
1021 HAPI void package_set_network(struct pkg_info *info, int network)
1023 info->network = network;
1026 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
1028 return info->pd.type;
1031 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
1033 info->pd.type = type;
1038 * Add the instance to the package info.
1039 * If a package has no slave, assign a new slave.
1041 static inline int assign_new_slave(struct pkg_info *info)
1047 s_name = util_slavename();
1049 ErrPrint("Failed to get a new slave name\n");
1050 return LB_STATUS_ERROR_FAULT;
1053 tmp = abi_find_slave(info->abi);
1056 ErrPrint("Failed to find a proper pkgname of a slave\n");
1057 return LB_STATUS_ERROR_INVALID;
1060 DbgPrint("Slave package: \"%s\" (abi: %s)\n", tmp, info->abi);
1061 s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->pkgname);
1063 DbgPrint("Failed to get replaced string\n");
1064 s_pkgname = strdup(tmp);
1066 ErrPrint("Heap: %s\n", strerror(errno));
1068 return LB_STATUS_ERROR_MEMORY;
1072 DbgPrint("New slave name is %s, it is assigned for livebox %s (using %s)\n", s_name, info->pkgname, s_pkgname);
1073 info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname, info->network);
1081 * package_destroy will try to remove "info" from the pkg_list.
1082 * but we didn't add this to it yet.
1083 * If the list method couldn't find an "info" from the list,
1084 * it just do nothing so I'll leave this.
1086 return LB_STATUS_ERROR_FAULT;
1090 * Slave is not activated yet.
1092 return LB_STATUS_SUCCESS;
1095 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1097 if (!info->inst_list) {
1098 info->slave = slave_find_available(info->abi, info->secured, info->network);
1103 ret = assign_new_slave(info);
1107 DbgPrint("Slave %s is assigned for %s\n", slave_name(info->slave), info->pkgname);
1110 slave_ref(info->slave);
1111 slave_load_package(info->slave);
1112 slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1113 slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1114 slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1116 if (info->secured) {
1117 slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1118 slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1122 * In case of the slave is terminated because of expired TTL timer,
1123 * Master should freeze the all update time.
1124 * But the callback should check the slave's state to prevent from duplicated freezing.
1126 * This callback will freeze the timer only if a slave doesn't running.
1128 xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1129 xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1133 info->inst_list = eina_list_append(info->inst_list, inst);
1134 return LB_STATUS_SUCCESS;
1137 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1139 info->inst_list = eina_list_remove(info->inst_list, inst);
1141 if (info->inst_list)
1142 return LB_STATUS_SUCCESS;
1145 slave_unload_package(info->slave);
1147 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1148 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1149 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1151 if (info->secured) {
1152 slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1153 slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1155 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1156 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1159 slave_unref(info->slave);
1163 if (info->is_uninstalled)
1164 package_destroy(info);
1166 return LB_STATUS_SUCCESS;
1169 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1171 return info->inst_list;
1174 static int client_created_cb(struct client_node *client, void *data)
1176 struct pkg_info *info;
1179 struct inst_info *inst;
1182 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1183 if (info->fault_info) {
1184 fault_unicast_info(client, info->pkgname, info->fault_info->filename, info->fault_info->function);
1188 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1189 switch (instance_state(inst)) {
1191 /* Will be send a created event after the instance gets created event */
1193 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1194 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1195 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1196 if (instance_client(inst) == client) {
1197 instance_unicast_created_event(inst, client);
1198 } else if (instance_client(inst) == NULL) {
1201 * Instances are lives in the system cluster/sub-cluster
1203 if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1204 instance_unicast_created_event(inst, client);
1205 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1211 DbgPrint("%s(%s) is not activated (%d)\n",
1212 package_name(info), instance_id(inst), instance_state(inst));
1221 static int io_uninstall_cb(const char *pkgname, int prime, void *data)
1223 struct pkg_info *info;
1226 struct inst_info *inst;
1228 DbgPrint("Livebox package %s is uninstalled\n", pkgname);
1229 info = package_find(pkgname);
1231 DbgPrint("%s is not yet loaded\n", pkgname);
1235 info->is_uninstalled = 1;
1239 * Don't delete an item from the inst_list.
1240 * destroy callback will use this list again.
1241 * So, Don't touch it from here.
1243 if (info->inst_list) {
1244 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1245 instance_destroy(inst);
1248 package_destroy(info);
1254 static inline void reload_package_info(struct pkg_info *info)
1258 struct inst_info *inst;
1260 DbgPrint("Already exists, try to update it\n");
1263 * Without "is_uninstalled", the package will be kept
1265 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1266 instance_destroy(inst);
1269 group_del_livebox(info->pkgname);
1270 package_clear_fault(info);
1276 io_load_package_db(info);
1279 static int io_install_cb(const char *pkgname, int prime, void *data)
1281 struct pkg_info *info;
1283 DbgPrint("Livebox package %s is installed\n", pkgname);
1284 info = package_find(pkgname);
1286 reload_package_info(info);
1288 info = package_create(pkgname);
1289 DbgPrint("Package %s is%sbuilt\n", pkgname, info ? " " : " not ");
1295 static int install_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1299 if (status != PKGMGR_STATUS_END)
1302 ret = io_update_livebox_package(pkgname, io_install_cb, NULL);
1303 DbgPrint("Processed %d packages\n", ret);
1307 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1311 if (status == PKGMGR_STATUS_START) {
1312 ret = io_update_livebox_package(pkgname, io_uninstall_cb, NULL);
1313 DbgPrint("Processed %d packages\n", ret);
1315 /*! for keeping the old style */
1316 (void)io_uninstall_cb(pkgname, -1, NULL);
1323 static int io_update_cb(const char *pkgname, int prime, void *data)
1325 struct pkg_info *info;
1327 DbgPrint("Livebox package %s is updated\n", pkgname);
1328 info = package_find(pkgname);
1332 reload_package_info(info);
1336 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1339 if (status != PKGMGR_STATUS_END)
1342 ret = io_update_livebox_package(pkgname, io_update_cb, NULL);
1343 DbgPrint("Processed %d packages\n", ret);
1347 static int crawling_liveboxes(const char *pkgname, int prime, void *data)
1349 if (package_find(pkgname)) {
1350 ErrPrint("Information of %s is already built\n", pkgname);
1352 struct pkg_info *info;
1353 info = package_create(pkgname);
1355 DbgPrint("[%s] information is built prime(%d)\n", pkgname, prime);
1361 HAPI int package_init(void)
1363 client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1366 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1367 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1368 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1370 io_crawling_liveboxes(crawling_liveboxes, NULL);
1374 HAPI int package_fini(void)
1380 struct pkg_info *info;
1381 struct inst_info *inst;
1383 pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1384 pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1385 pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1387 client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1389 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
1390 EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
1391 instance_state_reset(inst);
1392 instance_destroy(inst);
1395 package_destroy(info);
1401 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1404 struct pkg_info *info;
1406 if (!slave_is_secured(slave))
1409 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1410 if (info->slave == slave)
1411 return info->pkgname;
1417 HAPI const char * const package_name(const struct pkg_info *info)
1419 return info->pkgname;
1423 * del_or_creat : 1 == create, 0 == delete
1425 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1427 struct pkg_info *info;
1430 struct inst_info *inst;
1433 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1434 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1435 if (instance_client(inst))
1438 if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst)))
1441 switch (instance_state(inst)) {
1443 case INST_REQUEST_TO_ACTIVATE:
1444 /* Will be send a created event after the instance gets created event */
1447 if (!instance_has_client(inst, client)) {
1448 instance_add_client(inst, client);
1452 if (instance_has_client(inst, client)) {
1453 instance_del_client(inst, client);
1460 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1461 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1462 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1465 * Instances are lives in the system cluster/sub-cluster
1469 if (!instance_has_client(inst, client)) {
1470 instance_unicast_created_event(inst, client);
1471 instance_add_client(inst, client);
1472 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1476 if (instance_has_client(inst, client)) {
1477 instance_unicast_deleted_event(inst, client);
1478 instance_del_client(inst, client);
1487 DbgPrint("%s(%s) is not activated (%d)\n",
1488 package_name(info), instance_id(inst), instance_state(inst));
1497 HAPI const Eina_List *package_list(void)
1499 return s_info.pkg_list;
1502 HAPI int const package_fault_count(struct pkg_info *info)
1504 return info ? info->fault_count : 0;
1507 HAPI int package_is_enabled(const char *appid)
1513 ret = ail_get_appinfo(appid, &ai);
1514 if (ret != AIL_ERROR_OK) {
1515 ErrPrint("Unable to get appinfo: %d\n", ret);
1519 if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK)
1522 ail_destroy_appinfo(ai);
1524 return enabled == true;