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 */
26 #include <dynamicbox_errno.h>
27 #include <dynamicbox_service.h>
28 #include <dynamicbox_conf.h>
29 #include <pkgmgr-info.h>
32 #include "critical_log.h"
37 #include "slave_life.h"
38 #include "slave_rpc.h"
39 #include "client_life.h"
41 #include "fault_manager.h"
43 #include "script_handler.h"
59 * pkg_info describes the loaded package.
67 enum dynamicbox_dbox_type type;
76 /*!< Reserved for future use */
80 /*!< Reserved for future use */
84 /*!< Reserved for future use */
88 unsigned int size_list;
97 enum dynamicbox_gbar_type type;
106 /*!< Reserved for future use */
110 /*!< Reserved for future use */
121 char *script; /* script type: edje, ... */
123 char *hw_acceleration;
126 struct fault_info *fault_info;
128 struct slave_node *slave;
131 Eina_List *inst_list;
143 static int slave_activated_cb(struct slave_node *slave, void *data)
145 struct pkg_info *info = data;
146 struct inst_info *inst;
152 if (!slave_need_to_reactivate_instances(slave)) {
153 DbgPrint("Do not need to reactivate instances\n");
158 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
159 ret = instance_recover_state(inst);
164 instance_thaw_updator(inst);
168 DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
172 static int slave_fault_cb(struct slave_node *slave, void *data)
176 struct inst_info *inst;
177 struct pkg_info *info = (struct pkg_info *)data;
179 if (package_is_fault(info)) {
180 ErrPrint("Already faulted package: %s\n", package_name(info));
184 (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
185 fault_broadcast_info(package_name(info), slave_name(slave), __func__);
187 DbgPrint("Slave critical fault - package: %s (by slave fault %s\n", package_name(info), slave_name(slave));
188 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
189 DbgPrint("Destroy instance %p\n", inst);
190 instance_destroyed(inst, DBOX_STATUS_ERROR_FAULT);
196 static int slave_deactivated_cb(struct slave_node *slave, void *data)
198 struct pkg_info *info = data;
199 struct inst_info *inst;
204 if (info->fault_info) {
205 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
206 instance_destroyed(inst, DBOX_STATUS_ERROR_FAULT);
209 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
210 cnt += instance_need_slave(inst);
212 * instance_deactivated will call the slave_unload_instance.
213 * if the loaded instance counter meets 0,
214 * the slave will be deactivated.
215 * so we should not call the instance activate function
218 * activate slave when the slave is reactivated
223 return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
226 static int xmonitor_paused_cb(void *data)
228 struct pkg_info *info = (struct pkg_info *)data;
229 struct inst_info *inst;
232 if (slave_state(info->slave) != SLAVE_TERMINATED) {
236 EINA_LIST_FOREACH(info->inst_list, l, inst) {
237 instance_freeze_updator(inst);
243 static int xmonitor_resumed_cb(void *data)
245 struct pkg_info *info = data;
246 struct inst_info *inst;
249 if (slave_state(info->slave) != SLAVE_TERMINATED) {
253 EINA_LIST_FOREACH(info->inst_list, l, inst) {
254 instance_thaw_updator(inst);
260 static int slave_paused_cb(struct slave_node *slave, void *data)
262 struct pkg_info *info = (struct pkg_info *)data;
263 struct inst_info *inst;
266 EINA_LIST_FOREACH(info->inst_list, l, inst) {
267 instance_freeze_updator(inst);
273 static int slave_resumed_cb(struct slave_node *slave, void *data)
275 struct pkg_info *info = (struct pkg_info *)data;
276 struct inst_info *inst;
279 EINA_LIST_FOREACH(info->inst_list, l, inst) {
280 instance_thaw_updator(inst);
286 static inline void destroy_package(struct pkg_info *info)
288 eina_list_free(info->ctx_list);
289 /* This items will be deleted from group_del_dynamicbox */
290 info->ctx_list = NULL;
292 group_del_dynamicbox(info->dbox_id);
293 package_clear_fault(info);
295 s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
297 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
298 DbgFree(info->dbox.info.script.path);
299 DbgFree(info->dbox.info.script.group);
302 if (info->gbar.type == GBAR_TYPE_SCRIPT) {
303 DbgFree(info->gbar.info.script.path);
304 DbgFree(info->gbar.info.script.group);
307 DbgFree(info->script);
309 DbgFree(info->dbox_id);
310 DbgFree(info->dbox.libexec);
311 DbgFree(info->dbox.auto_launch);
312 DbgFree(info->pkgid);
313 DbgFree(info->hw_acceleration);
318 static inline int load_conf(struct pkg_info *info)
320 struct parser *parser;
324 parser = parser_load(info->dbox_id);
326 info->dbox.size_list = 0x01; /* Default */
328 info->script = strdup(DYNAMICBOX_CONF_DEFAULT_SCRIPT);
330 ErrPrint("Heap: %s\n", strerror(errno));
331 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
334 info->abi = strdup(DYNAMICBOX_CONF_DEFAULT_ABI);
336 ErrPrint("Heap: %s\n", strerror(errno));
337 DbgFree(info->script);
339 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
342 info->gbar.width = DYNAMICBOX_CONF_BASE_W;
343 info->gbar.height = DYNAMICBOX_CONF_BASE_H >> 2;
344 info->dbox.pinup = 1;
345 return DBOX_STATUS_ERROR_NONE;
348 info->dbox.type = DBOX_TYPE_FILE;
349 if (parser_text_dbox(parser)) {
350 info->dbox.type = DBOX_TYPE_TEXT;
351 } else if (parser_buffer_dbox(parser)) {
352 info->dbox.type = DBOX_TYPE_BUFFER;
354 str = parser_dbox_path(parser);
356 info->dbox.type = DBOX_TYPE_SCRIPT;
358 info->dbox.info.script.path = strdup(str);
359 if (!info->dbox.info.script.path) {
360 ErrPrint("Heap: %s\n", strerror(errno));
361 parser_unload(parser);
362 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
365 str = parser_dbox_group(parser);
367 info->dbox.info.script.group = strdup(str);
368 if (!info->dbox.info.script.group) {
369 ErrPrint("Heap: %s\n", strerror(errno));
370 DbgFree(info->dbox.info.script.path);
371 parser_unload(parser);
372 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
378 if (parser_text_gbar(parser)) {
379 info->gbar.type = GBAR_TYPE_TEXT;
380 } else if (parser_buffer_gbar(parser)) {
381 info->gbar.type = GBAR_TYPE_BUFFER;
383 str = parser_gbar_path(parser);
385 info->gbar.type = GBAR_TYPE_SCRIPT;
386 info->gbar.info.script.path = strdup(str);
387 if (!info->gbar.info.script.path) {
388 ErrPrint("Heap: %s\n", strerror(errno));
389 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
390 DbgFree(info->dbox.info.script.path);
391 DbgFree(info->dbox.info.script.group);
393 parser_unload(parser);
394 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
397 str = parser_gbar_group(parser);
399 info->gbar.info.script.group = strdup(str);
400 if (!info->gbar.info.script.group) {
401 ErrPrint("Heap: %s\n", strerror(errno));
402 DbgFree(info->gbar.info.script.path);
403 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
404 DbgFree(info->dbox.info.script.path);
405 DbgFree(info->dbox.info.script.group);
407 parser_unload(parser);
408 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
414 str = parser_script(parser);
415 str = str ? str : DYNAMICBOX_CONF_DEFAULT_SCRIPT;
416 info->script = strdup(str);
418 ErrPrint("Heap: %s\n", strerror(errno));
419 if (info->gbar.type == GBAR_TYPE_SCRIPT) {
420 DbgFree(info->gbar.info.script.path);
421 DbgFree(info->gbar.info.script.group);
424 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
425 DbgFree(info->dbox.info.script.path);
426 DbgFree(info->dbox.info.script.group);
429 parser_unload(parser);
430 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
433 str = parser_abi(parser);
434 str = str ? str : DYNAMICBOX_CONF_DEFAULT_ABI;
435 info->abi = strdup(str);
437 ErrPrint("Heap: %s\n", strerror(errno));
438 DbgFree(info->script);
439 if (info->gbar.type == GBAR_TYPE_SCRIPT) {
440 DbgFree(info->gbar.info.script.path);
441 DbgFree(info->gbar.info.script.group);
444 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
445 DbgFree(info->dbox.info.script.path);
446 DbgFree(info->dbox.info.script.group);
448 parser_unload(parser);
449 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
452 info->dbox.timeout = parser_timeout(parser);
453 info->network = parser_network(parser);
455 info->dbox.period = parser_period(parser);
456 if (info->dbox.period < 0.0f) {
457 info->dbox.period = 0.0f;
458 } else if (info->dbox.period > 0.0f && info->dbox.period < DYNAMICBOX_CONF_MINIMUM_PERIOD) {
459 info->dbox.period = DYNAMICBOX_CONF_MINIMUM_PERIOD;
462 info->dbox.size_list = parser_size(parser);
464 str = parser_auto_launch(parser);
465 str = str ? str : "";
466 info->dbox.auto_launch = strdup(str);
467 if (!info->dbox.auto_launch) {
468 ErrPrint("Heap: %s\n", strerror(errno));
470 DbgFree(info->script);
471 if (info->gbar.type == GBAR_TYPE_SCRIPT) {
472 DbgFree(info->gbar.info.script.path);
473 DbgFree(info->gbar.info.script.group);
476 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
477 DbgFree(info->dbox.info.script.path);
478 DbgFree(info->dbox.info.script.group);
480 parser_unload(parser);
481 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
484 info->secured = parser_secured(parser);
485 info->dbox.pinup = parser_pinup(parser);
487 parser_get_gbar_size(parser, &info->gbar.width, &info->gbar.height);
489 group = parser_group_str(parser);
490 if (group && group_add_dynamicbox(group, info->dbox_id) < 0) {
491 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->dbox_id, group);
494 parser_unload(parser);
495 return DBOX_STATUS_ERROR_NONE;
498 HAPI struct pkg_info *package_create(const char *pkgid, const char *dbox_id)
500 struct pkg_info *pkginfo;
502 pkginfo = calloc(1, sizeof(*pkginfo));
504 ErrPrint("Heap: %s\n", strerror(errno));
508 pkginfo->pkgid = strdup(pkgid);
509 if (!pkginfo->pkgid) {
510 ErrPrint("Heap: %s\n", strerror(errno));
515 pkginfo->dbox_id = io_dynamicbox_pkgname(dbox_id);
516 if (!pkginfo->dbox_id) {
517 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
518 pkginfo->dbox_id = strdup(dbox_id);
519 if (!pkginfo->dbox_id) {
520 ErrPrint("Heap: %s\n", strerror(errno));
521 DbgFree(pkginfo->pkgid);
527 if (io_load_package_db(pkginfo) < 0) {
528 ErrPrint("Failed to load DB, fall back to conf file loader\n");
529 if (load_conf(pkginfo) < 0) {
530 ErrPrint("Failed to initiate the conf file loader\n");
531 DbgFree(pkginfo->dbox_id);
532 DbgFree(pkginfo->pkgid);
538 package_ref(pkginfo);
540 s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
545 HAPI int package_destroy(struct pkg_info *info)
548 return DBOX_STATUS_ERROR_NONE;
551 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
553 return pkginfo->ctx_list;
556 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
558 pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
561 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
563 pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
566 HAPI char *package_dbox_pkgname(const char *pkgname)
570 dbox_id = io_dynamicbox_pkgname(pkgname);
572 dbox_id = strdup(pkgname);
574 ErrPrint("Heap: %s\n", strerror(errno));
582 HAPI int package_is_dbox_pkgname(const char *pkgname)
587 dbox_id = package_dbox_pkgname(pkgname);
594 HAPI struct pkg_info *package_find(const char *dbox_id)
597 struct pkg_info *info;
603 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
604 if (!strcmp(info->dbox_id, dbox_id)) {
612 HAPI struct inst_info *package_find_instance_by_id(const char *dbox_id, const char *id)
615 struct inst_info *inst;
616 struct pkg_info *info;
618 info = package_find(dbox_id);
620 ErrPrint("Package %s is not exists\n", dbox_id);
624 EINA_LIST_FOREACH(info->inst_list, l, inst) {
625 if (!strcmp(instance_id(inst), id)) {
633 HAPI struct inst_info *package_find_instance_by_timestamp(const char *dbox_id, double timestamp)
636 struct inst_info *inst;
637 struct pkg_info *info;
639 info = package_find(dbox_id);
641 ErrPrint("Package %s is not exists\n", dbox_id);
645 EINA_LIST_FOREACH(info->inst_list, l, inst) {
646 if (instance_timestamp(inst) == timestamp) {
654 HAPI int package_dump_fault_info(struct pkg_info *info)
656 if (!info->fault_info) {
657 return DBOX_STATUS_ERROR_NOT_EXIST;
660 CRITICAL_LOG("=============\n");
661 CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
662 CRITICAL_LOG("Package: %s\n", info->dbox_id);
663 CRITICAL_LOG("Function: %s\n", info->fault_info->function);
664 CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
665 return DBOX_STATUS_ERROR_NONE;
668 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
670 if (!info->fault_info) {
671 return DBOX_STATUS_ERROR_NOT_EXIST;
674 *timestamp = info->fault_info->timestamp;
675 *filename = info->fault_info->filename;
676 *function = info->fault_info->function;
677 return DBOX_STATUS_ERROR_NONE;
680 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
682 struct fault_info *fault;
684 package_clear_fault(info);
686 fault = calloc(1, sizeof(*fault));
688 ErrPrint("Heap: %s\n", strerror(errno));
689 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
692 fault->timestamp = timestamp;
694 filename = "unknown";
697 function = "unknown";
700 fault->filename = strdup(filename);
701 if (!fault->filename) {
702 ErrPrint("Heap: %s\n", strerror(errno));
704 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
707 fault->function = strdup(function);
708 if (!fault->function) {
709 ErrPrint("Heap: %s\n", strerror(errno));
710 DbgFree(fault->filename);
712 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
715 info->fault_info = fault;
717 return DBOX_STATUS_ERROR_NONE;
720 HAPI int package_clear_fault(struct pkg_info *info)
722 if (!info->fault_info) {
723 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
726 package_dump_fault_info(info);
728 DbgFree(info->fault_info->function);
729 DbgFree(info->fault_info->filename);
730 DbgFree(info->fault_info);
731 info->fault_info = NULL;
732 return DBOX_STATUS_ERROR_NONE;
735 HAPI const int const package_is_fault(const struct pkg_info *info)
737 return !!info->fault_info;
740 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
745 HAPI const int const package_timeout(const struct pkg_info *info)
747 return info->dbox.timeout;
750 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
752 info->dbox.timeout = timeout;
755 HAPI const double const package_period(const struct pkg_info *info)
757 return info->dbox.period;
760 HAPI void package_set_period(struct pkg_info *info, double period)
762 info->dbox.period = period;
765 HAPI const int const package_secured(const struct pkg_info *info)
767 return info->secured;
770 HAPI void package_set_secured(struct pkg_info *info, int secured)
772 info->secured = secured;
775 HAPI const char * const package_script(const struct pkg_info *info)
780 HAPI int package_set_script(struct pkg_info *info, const char *script)
784 tmp = strdup(script);
786 ErrPrint("Heap: %s\n", strerror(errno));
787 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
790 DbgFree(info->script);
792 return DBOX_STATUS_ERROR_NONE;
795 HAPI const char * const package_abi(const struct pkg_info *info)
800 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
805 ErrPrint("Heap: %s\n", strerror(errno));
806 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
811 return DBOX_STATUS_ERROR_NONE;
814 HAPI const char * const package_dbox_path(const struct pkg_info *info)
816 if (info->dbox.type != DBOX_TYPE_SCRIPT) {
820 return info->dbox.info.script.path;
823 HAPI int package_set_dbox_path(struct pkg_info *info, const char *path)
827 if (info->dbox.type != DBOX_TYPE_SCRIPT) {
828 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
833 ErrPrint("Heap: %s\n", strerror(errno));
834 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
837 DbgFree(info->dbox.info.script.path);
838 info->dbox.info.script.path = tmp;
839 return DBOX_STATUS_ERROR_NONE;
842 HAPI const char * const package_dbox_group(const struct pkg_info *info)
844 if (info->dbox.type != DBOX_TYPE_SCRIPT) {
848 return info->dbox.info.script.group;
851 HAPI int package_set_dbox_group(struct pkg_info *info, const char *group)
855 if (info->dbox.type != DBOX_TYPE_SCRIPT) {
856 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
861 ErrPrint("Heap: %s\n", strerror(errno));
862 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
865 DbgFree(info->dbox.info.script.group);
866 info->dbox.info.script.group = tmp;
867 return DBOX_STATUS_ERROR_NONE;
870 HAPI const char * const package_gbar_path(const struct pkg_info *info)
872 if (info->gbar.type != GBAR_TYPE_SCRIPT) {
876 return info->gbar.info.script.path;
879 HAPI int package_set_gbar_path(struct pkg_info *info, const char *path)
883 if (info->gbar.type != GBAR_TYPE_SCRIPT) {
884 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
889 ErrPrint("Heap: %s\n", strerror(errno));
890 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
893 DbgFree(info->gbar.info.script.path);
894 info->gbar.info.script.path = tmp;
895 return DBOX_STATUS_ERROR_NONE;
898 HAPI const char * const package_gbar_group(const struct pkg_info *info)
900 if (info->gbar.type != GBAR_TYPE_SCRIPT) {
904 return info->gbar.info.script.group;
907 HAPI int package_set_gbar_group(struct pkg_info *info, const char *group)
911 if (info->gbar.type != GBAR_TYPE_SCRIPT) {
912 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
917 ErrPrint("Heap: %s\n", strerror(errno));
918 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
921 DbgFree(info->gbar.info.script.group);
922 info->gbar.info.script.group = tmp;
923 return DBOX_STATUS_ERROR_NONE;
926 HAPI const int const package_pinup(const struct pkg_info *info)
928 return info->dbox.pinup;
931 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
933 info->dbox.pinup = pinup;
936 HAPI const char * const package_auto_launch(const struct pkg_info *info)
938 return info->dbox.auto_launch;
941 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
947 info->dbox.auto_launch = strdup(auto_launch);
948 if (!info->dbox.auto_launch) {
949 ErrPrint("Heap: %s\n", strerror(errno));
954 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
956 return info->dbox.size_list;
959 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
961 info->dbox.size_list = size_list;
964 HAPI const int const package_gbar_width(const struct pkg_info *info)
966 return info->gbar.width;
969 HAPI void package_set_gbar_width(struct pkg_info *info, int width)
971 info->gbar.width = width;
974 HAPI const int const package_gbar_height(const struct pkg_info *info)
976 return info->gbar.height;
979 HAPI void package_set_gbar_height(struct pkg_info *info, int height)
981 info->gbar.height = height;
984 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
990 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
992 if (info->refcnt == 0) {
993 ErrPrint("Invalid request\n");
998 if (info->refcnt == 0) {
999 destroy_package(info);
1006 HAPI const int const package_refcnt(const struct pkg_info *info)
1008 return info->refcnt;
1011 HAPI const enum dynamicbox_dbox_type package_dbox_type(const struct pkg_info *info)
1013 return info ? info->dbox.type : DBOX_TYPE_NONE;
1016 HAPI void package_set_dbox_type(struct pkg_info *info, enum dynamicbox_dbox_type type)
1018 info->dbox.type = type;
1021 HAPI const char * const package_libexec(struct pkg_info *info)
1023 return info->dbox.libexec;
1026 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1030 tmp = strdup(libexec);
1032 ErrPrint("Heap: %s\n", strerror(errno));
1033 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1036 DbgFree(info->dbox.libexec);
1037 info->dbox.libexec = tmp;
1038 return DBOX_STATUS_ERROR_NONE;
1041 HAPI int package_network(struct pkg_info *info)
1043 return info->network;
1046 HAPI void package_set_network(struct pkg_info *info, int network)
1048 info->network = network;
1051 HAPI void package_set_direct_input(struct pkg_info *info, int direct_input)
1053 info->direct_input = direct_input;
1056 HAPI int package_direct_input(const struct pkg_info *info)
1058 return info->direct_input;
1061 HAPI const enum dynamicbox_gbar_type const package_gbar_type(const struct pkg_info *info)
1063 return info ? info->gbar.type : GBAR_TYPE_NONE;
1066 HAPI void package_set_gbar_type(struct pkg_info *info, enum dynamicbox_gbar_type type)
1068 info->gbar.type = type;
1071 HAPI const char *package_hw_acceleration(struct pkg_info *info)
1073 return info->hw_acceleration;
1076 HAPI int package_set_hw_acceleration(struct pkg_info *info, const char *hw_acceleration)
1080 if (!hw_acceleration || !info) {
1081 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1084 tmp = strdup(hw_acceleration);
1086 ErrPrint("strdup: %s\n", strerror(errno));
1087 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1090 DbgFree(info->hw_acceleration);
1091 info->hw_acceleration = tmp;
1092 return DBOX_STATUS_ERROR_NONE;
1097 * Add the instance to the package info.
1098 * If a package has no slave, assign a new slave.
1100 static inline int assign_new_slave(const char *slave_pkgname, struct pkg_info *info)
1104 s_name = util_slavename();
1106 ErrPrint("Failed to get a new slave name\n");
1107 return DBOX_STATUS_ERROR_FAULT;
1110 DbgPrint("New slave[%s] is assigned for %s (using %s / abi[%s] / accel[%s])\n", s_name, info->dbox_id, slave_pkgname, info->abi, info->hw_acceleration);
1111 info->slave = slave_create(s_name, info->secured, info->abi, slave_pkgname, info->network, info->hw_acceleration);
1118 * package_destroy will try to remove "info" from the pkg_list.
1119 * but we didn't add this to it yet.
1120 * If the list method couldn't find an "info" from the list,
1121 * it just do nothing so I'll leave this.
1123 return DBOX_STATUS_ERROR_FAULT;
1127 * Slave is not activated yet.
1129 return DBOX_STATUS_ERROR_NONE;
1132 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1134 if (!info->inst_list) {
1135 char *slave_pkgname;
1137 slave_pkgname = slave_package_name(info->abi, info->dbox_id);
1138 if (!slave_pkgname) {
1139 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1142 info->slave = slave_find_available(slave_pkgname, info->abi, info->secured, info->network, info->hw_acceleration);
1146 ret = assign_new_slave(slave_pkgname, info);
1147 DbgFree(slave_pkgname);
1152 DbgFree(slave_pkgname);
1153 DbgPrint("Slave %s is used for %s\n", slave_name(info->slave), info->dbox_id);
1156 (void)slave_ref(info->slave);
1157 slave_load_package(info->slave);
1158 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1159 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1160 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1162 if (info->secured || (DBOX_IS_INHOUSE(package_abi(info)) && DYNAMICBOX_CONF_SLAVE_LIMIT_TO_TTL)) {
1163 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1164 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1168 * In case of the slave is terminated because of expired TTL timer,
1169 * Master should freeze the all update time.
1170 * But the callback should check the slave's state to prevent from duplicated freezing.
1172 * This callback will freeze the timer only if a slave doesn't running.
1174 (void)xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1175 (void)xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1179 info->inst_list = eina_list_append(info->inst_list, inst);
1180 return DBOX_STATUS_ERROR_NONE;
1183 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1185 info->inst_list = eina_list_remove(info->inst_list, inst);
1187 if (info->inst_list) {
1188 return DBOX_STATUS_ERROR_NONE;
1192 slave_unload_package(info->slave);
1194 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1195 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1196 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1198 if (info->secured || (DBOX_IS_INHOUSE(package_abi(info)) && DYNAMICBOX_CONF_SLAVE_LIMIT_TO_TTL)) {
1199 slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1200 slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1202 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1203 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1206 slave_unref(info->slave);
1210 if (info->is_uninstalled) {
1211 package_destroy(info);
1214 return DBOX_STATUS_ERROR_NONE;
1217 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1219 return info->inst_list;
1222 static int client_created_cb(struct client_node *client, void *data)
1224 struct pkg_info *info;
1227 struct inst_info *inst;
1230 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1231 if (info->fault_info) {
1232 fault_unicast_info(client, info->dbox_id, info->fault_info->filename, info->fault_info->function);
1236 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1237 switch (instance_state(inst)) {
1239 /* Will be send a created event after the instance gets created event */
1241 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1242 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1243 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1244 if (instance_client(inst) == client) {
1245 instance_unicast_created_event(inst, client);
1246 } else if (instance_client(inst) == NULL) {
1249 * Instances are lives in the system cluster/sub-cluster
1251 if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1252 instance_unicast_created_event(inst, client);
1253 DbgPrint("(Subscribed) Created package: %s\n", info->dbox_id);
1259 DbgPrint("%s(%s) is not activated (%d)\n",
1260 package_name(info), instance_id(inst), instance_state(inst));
1269 static int io_uninstall_cb(const char *pkgid, const char *dbox_id, int prime, void *data)
1271 struct pkg_info *info;
1274 struct inst_info *inst;
1276 DbgPrint("Package %s is uninstalled\n", dbox_id);
1277 info = package_find(dbox_id);
1279 DbgPrint("%s is not yet loaded\n", dbox_id);
1283 info->is_uninstalled = 1;
1287 * Don't delete an item from the inst_list.
1288 * destroy callback will use this list again.
1289 * So, Don't touch it from here.
1291 if (info->inst_list) {
1292 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1293 instance_destroy(inst, DBOX_DESTROY_TYPE_UNINSTALL);
1296 package_destroy(info);
1302 static inline void reload_package_info(struct pkg_info *info)
1306 struct inst_info *inst;
1307 unsigned int size_type;
1312 DbgPrint("Already exists, try to update it\n");
1314 old_period = info->dbox.period;
1316 group_del_dynamicbox(info->dbox_id);
1317 package_clear_fault(info);
1323 io_load_package_db(info);
1327 * Without "is_uninstalled", the package will be kept
1329 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1330 width = instance_dbox_width(inst);
1331 height = instance_dbox_height(inst);
1332 size_type = dynamicbox_service_size_type(width, height);
1333 if (info->dbox.size_list & size_type) {
1334 if (instance_period(inst) == old_period) {
1335 instance_reload_period(inst, package_period(info));
1337 instance_reload(inst, DBOX_DESTROY_TYPE_UPGRADE);
1339 instance_destroy(inst, DBOX_DESTROY_TYPE_UNINSTALL);
1344 static int io_install_cb(const char *pkgid, const char *dbox_id, int prime, void *data)
1346 struct pkg_info *info;
1348 info = package_find(dbox_id);
1351 * Already exists. skip to create this.
1356 info = package_create(pkgid, dbox_id);
1358 ErrPrint("Failed to build an info %s\n", dbox_id);
1360 DbgPrint("Dynamicbox %s is built\n", dbox_id);
1366 static int uninstall_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 io_uninstall_cb(pkgname, info->dbox_id, -1, NULL);
1385 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1389 struct pkg_info *info;
1391 if (status != PKGMGR_STATUS_END) {
1395 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1396 if (!strcmp(info->pkgid, pkgname)) {
1397 DbgPrint("Update dbox_id: %s\n", info->dbox_id);
1398 if (io_is_exists(info->dbox_id) == 1) {
1399 reload_package_info(info);
1401 io_uninstall_cb(pkgname, info->dbox_id, -1, NULL);
1406 (void)io_update_dynamicbox_package(pkgname, io_install_cb, NULL);
1410 static int crawling_dynamicboxes(const char *pkgid, const char *dbox_id, int prime, void *data)
1412 if (package_find(dbox_id)) {
1413 ErrPrint("Information of %s is already built\n", dbox_id);
1415 struct pkg_info *info;
1416 info = package_create(pkgid, dbox_id);
1418 DbgPrint("[%s] information is built prime(%d)\n", dbox_id, prime);
1425 HAPI int package_init(void)
1427 client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1430 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1431 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1432 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1434 io_crawling_dynamicboxes(crawling_dynamicboxes, NULL);
1438 HAPI int package_fini(void)
1444 struct pkg_info *info;
1445 struct inst_info *inst;
1447 pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1448 pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1449 pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1451 client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1453 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
1454 EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
1455 instance_state_reset(inst);
1456 instance_destroy(inst, DBOX_DESTROY_TYPE_TERMINATE);
1459 package_destroy(info);
1465 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1468 struct pkg_info *info;
1470 if (!slave_is_secured(slave)) {
1474 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1475 if (info->slave == slave) {
1476 return info->dbox_id;
1483 HAPI const char * const package_name(const struct pkg_info *info)
1485 return info->dbox_id;
1489 * del_or_creat : 1 == create, 0 == delete
1491 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1493 struct pkg_info *info;
1496 struct inst_info *inst;
1499 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1500 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1501 if (instance_client(inst)) {
1505 if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1509 switch (instance_state(inst)) {
1511 case INST_REQUEST_TO_ACTIVATE:
1512 /* Will be send a created event after the instance gets created event */
1515 if (!instance_has_client(inst, client)) {
1516 instance_add_client(inst, client);
1520 if (instance_has_client(inst, client)) {
1521 instance_del_client(inst, client);
1528 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1529 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1530 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1533 * Instances are lives in the system cluster/sub-cluster
1537 if (!instance_has_client(inst, client)) {
1538 instance_unicast_created_event(inst, client);
1539 instance_add_client(inst, client);
1540 DbgPrint("(Subscribed) Created package: %s\n", info->dbox_id);
1544 if (instance_has_client(inst, client)) {
1545 instance_unicast_deleted_event(inst, client, DBOX_STATUS_ERROR_NONE);
1546 instance_del_client(inst, client);
1555 DbgPrint("%s(%s) is not activated (%d)\n",
1556 package_name(info), instance_id(inst), instance_state(inst));
1565 HAPI const Eina_List *package_list(void)
1567 return s_info.pkg_list;
1570 HAPI int const package_fault_count(struct pkg_info *info)
1572 return info ? info->fault_count : 0;
1575 HAPI int package_is_enabled(const char *appid)
1577 pkgmgrinfo_appinfo_h handle;
1581 ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
1582 if (ret != PMINFO_R_OK) {
1583 ErrPrint("Failed to get info\n");
1587 ret = pkgmgrinfo_appinfo_is_enabled(handle, &enabled);
1588 if (ret != PMINFO_R_OK) {
1589 ErrPrint("Failed to get info\n");
1593 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1594 return enabled == true;
1597 HAPI int package_faulted(struct pkg_info *pkg, int broadcast)
1601 struct slave_node *slave;
1602 struct inst_info *inst;
1604 slave = package_slave(pkg);
1606 ErrPrint("Package has no slave?\n");
1607 return DBOX_STATUS_ERROR_FAULT;
1610 /* Emulated fault routine */
1611 // (void)package_set_fault_info(pkg, util_timestamp(), slave_name(slave), __func__);
1613 fault_broadcast_info(package_name(pkg), slave_name(slave), __func__);
1616 DbgPrint("package: %s (forucely faulted %s)\n", package_name(pkg), slave_name(slave));
1617 EINA_LIST_FOREACH_SAFE(pkg->inst_list, l, n, inst) {
1618 DbgPrint("Destroy instance %p\n", inst);
1619 instance_destroy(inst, DBOX_DESTROY_TYPE_FAULT);
1622 return DBOX_STATUS_ERROR_NONE;