tizen 2.3 release
[apps/livebox/data-provider-master.git] / src / package.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
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
7  *
8  * http://floralicense.org/license/
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <string.h> /* strcmp */
20 #include <stdlib.h> /* free */
21
22 #include <dlog.h>
23 #include <Eina.h>
24
25 #include <packet.h>
26 #include <dynamicbox_errno.h>
27 #include <dynamicbox_service.h>
28 #include <dynamicbox_conf.h>
29 #include <pkgmgr-info.h>
30 #include <ail.h>
31
32 #include "critical_log.h"
33 #include "debug.h"
34 #include "util.h"
35 #include "parser.h"
36 #include "conf.h"
37 #include "slave_life.h"
38 #include "slave_rpc.h"
39 #include "client_life.h"
40 #include "package.h"
41 #include "fault_manager.h"
42 #include "instance.h"
43 #include "script_handler.h"
44 #include "group.h"
45 #include "abi.h"
46 #include "io.h"
47 #include "pkgmgr.h"
48 #include "xmonitor.h"
49
50 int errno;
51
52 struct fault_info {
53         double timestamp;
54         char *filename;
55         char *function;
56 };
57
58 /*!
59  * pkg_info describes the loaded package.
60  */
61
62 struct pkg_info {
63         char *pkgid;
64         char *dbox_id;
65
66         struct {
67                 enum dynamicbox_dbox_type type;
68
69                 union {
70                         struct {
71                                 char *path;
72                                 char *group;
73                         } script;
74
75                         struct {
76                                 /*!< Reserved for future use */
77                         } file;
78
79                         struct {
80                                 /*!< Reserved for future use */
81                         } text;
82
83                         struct {
84                                 /*!< Reserved for future use */
85                         } buffer;
86                 } info;
87
88                 unsigned int size_list;
89                 char *auto_launch;
90                 int pinup;
91                 int timeout;
92                 double period;
93                 char *libexec;
94         } dbox;
95
96         struct {
97                 enum dynamicbox_gbar_type type;
98
99                 union {
100                         struct {
101                                 char *path;
102                                 char *group;
103                         } script;
104
105                         struct {
106                                 /*!< Reserved for future use */
107                         } text;
108
109                         struct {
110                                 /*!< Reserved for future use */
111                         } buffer;
112                 } info;
113
114                 unsigned int width;
115                 unsigned int height;
116         } gbar;
117
118         int network;
119         int secured;
120         int direct_input;
121         char *script; /* script type: edje, ... */
122         char *abi;
123         char *hw_acceleration;
124
125         int fault_count;
126         struct fault_info *fault_info;
127
128         struct slave_node *slave;
129         int refcnt;
130
131         Eina_List *inst_list;
132         Eina_List *ctx_list;
133
134         int is_uninstalled;
135 };
136
137 static struct {
138         Eina_List *pkg_list;
139 } s_info = {
140         .pkg_list = NULL,
141 };
142
143 static int slave_activated_cb(struct slave_node *slave, void *data)
144 {
145         struct pkg_info *info = data;
146         struct inst_info *inst;
147         Eina_List *l;
148         Eina_List *n;
149         int cnt;
150         int ret;
151
152         if (!slave_need_to_reactivate_instances(slave)) {
153                 DbgPrint("Do not need to reactivate instances\n");
154                 return 0;
155         }
156
157         cnt = 0;
158         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
159                 ret = instance_recover_state(inst);
160                 if (!ret) {
161                         continue;
162                 }
163
164                 instance_thaw_updator(inst);
165                 cnt++;
166         }
167
168         DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
169         return 0;
170 }
171
172 static int slave_fault_cb(struct slave_node *slave, void *data)
173 {
174         Eina_List *l;
175         Eina_List *n;
176         struct inst_info *inst;
177         struct pkg_info *info = (struct pkg_info *)data;
178
179         if (package_is_fault(info)) {
180                 ErrPrint("Already faulted package: %s\n", package_name(info));
181                 return 0;
182         }
183
184         (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
185         fault_broadcast_info(package_name(info), slave_name(slave), __func__);
186
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);
191         }
192
193         return 0;
194 }
195
196 static int slave_deactivated_cb(struct slave_node *slave, void *data)
197 {
198         struct pkg_info *info = data;
199         struct inst_info *inst;
200         Eina_List *l;
201         Eina_List *n;
202         int cnt = 0;
203
204         if (info->fault_info) {
205                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
206                         instance_destroyed(inst, DBOX_STATUS_ERROR_FAULT);
207                 }
208         } else {
209                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
210                         cnt += instance_need_slave(inst);
211                         /*!
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
216                          * from here.
217                          *
218                          * activate slave when the slave is reactivated
219                          */
220                 }
221         }
222
223         return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
224 }
225
226 static int xmonitor_paused_cb(void *data)
227 {
228         struct pkg_info *info = (struct pkg_info *)data;
229         struct inst_info *inst;
230         Eina_List *l;
231
232         if (slave_state(info->slave) != SLAVE_TERMINATED) {
233                 return 0;
234         }
235
236         EINA_LIST_FOREACH(info->inst_list, l, inst) {
237                 instance_freeze_updator(inst);
238         }
239
240         return 0;
241 }
242
243 static int xmonitor_resumed_cb(void *data)
244 {
245         struct pkg_info *info = data;
246         struct inst_info *inst;
247         Eina_List *l;
248
249         if (slave_state(info->slave) != SLAVE_TERMINATED) {
250                 return 0;
251         }
252
253         EINA_LIST_FOREACH(info->inst_list, l, inst) {
254                 instance_thaw_updator(inst);
255         }
256
257         return 0;
258 }
259
260 static int slave_paused_cb(struct slave_node *slave, void *data)
261 {
262         struct pkg_info *info = (struct pkg_info *)data;
263         struct inst_info *inst;
264         Eina_List *l;
265
266         EINA_LIST_FOREACH(info->inst_list, l, inst) {
267                 instance_freeze_updator(inst);
268         }
269
270         return 0;
271 }
272
273 static int slave_resumed_cb(struct slave_node *slave, void *data)
274 {
275         struct pkg_info *info = (struct pkg_info *)data;
276         struct inst_info *inst;
277         Eina_List *l;
278
279         EINA_LIST_FOREACH(info->inst_list, l, inst) {
280                 instance_thaw_updator(inst);
281         }
282
283         return 0;
284 }
285
286 static inline void destroy_package(struct pkg_info *info)
287 {
288         eina_list_free(info->ctx_list);
289         /* This items will be deleted from group_del_dynamicbox */
290         info->ctx_list = NULL;
291
292         group_del_dynamicbox(info->dbox_id);
293         package_clear_fault(info);
294
295         s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
296
297         if (info->dbox.type == DBOX_TYPE_SCRIPT) {
298                 DbgFree(info->dbox.info.script.path);
299                 DbgFree(info->dbox.info.script.group);
300         }
301
302         if (info->gbar.type == GBAR_TYPE_SCRIPT) {
303                 DbgFree(info->gbar.info.script.path);
304                 DbgFree(info->gbar.info.script.group);
305         }
306
307         DbgFree(info->script);
308         DbgFree(info->abi);
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);
314
315         DbgFree(info);
316 }
317
318 static inline int load_conf(struct pkg_info *info)
319 {
320         struct parser *parser;
321         const char *str;
322         const char *group;
323
324         parser = parser_load(info->dbox_id);
325         if (!parser) {
326                 info->dbox.size_list = 0x01; /* Default */
327
328                 info->script = strdup(DYNAMICBOX_CONF_DEFAULT_SCRIPT);
329                 if (!info->script) {
330                         ErrPrint("Heap: %s\n", strerror(errno));
331                         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
332                 }
333
334                 info->abi = strdup(DYNAMICBOX_CONF_DEFAULT_ABI);
335                 if (!info->abi) {
336                         ErrPrint("Heap: %s\n", strerror(errno));
337                         DbgFree(info->script);
338                         info->script = NULL;
339                         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
340                 }
341
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;
346         }
347
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;
353         } else {
354                 str = parser_dbox_path(parser);
355                 if (str) {
356                         info->dbox.type = DBOX_TYPE_SCRIPT;
357
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;
363                         }
364
365                         str = parser_dbox_group(parser);
366                         if (str) {
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;
373                                 }
374                         }
375                 }
376         }
377
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;
382         } else {
383                 str = parser_gbar_path(parser);
384                 if (str) {
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);
392                                 }
393                                 parser_unload(parser);
394                                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
395                         }
396
397                         str = parser_gbar_group(parser);
398                         if (str) {
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);
406                                         }
407                                         parser_unload(parser);
408                                         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
409                                 }
410                         }
411                 }
412         }
413
414         str = parser_script(parser);
415         str = str ? str : DYNAMICBOX_CONF_DEFAULT_SCRIPT;
416         info->script = strdup(str);
417         if (!info->script) {
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);
422                 }
423
424                 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
425                         DbgFree(info->dbox.info.script.path);
426                         DbgFree(info->dbox.info.script.group);
427                 }
428
429                 parser_unload(parser);
430                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
431         }
432
433         str = parser_abi(parser);
434         str = str ? str : DYNAMICBOX_CONF_DEFAULT_ABI;
435         info->abi = strdup(str);
436         if (!info->abi) {
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);
442                 }
443
444                 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
445                         DbgFree(info->dbox.info.script.path);
446                         DbgFree(info->dbox.info.script.group);
447                 }
448                 parser_unload(parser);
449                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
450         }
451
452         info->dbox.timeout = parser_timeout(parser);
453         info->network = parser_network(parser);
454
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;
460         }
461
462         info->dbox.size_list = parser_size(parser);
463
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));
469                 DbgFree(info->abi);
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);
474                 }
475
476                 if (info->dbox.type == DBOX_TYPE_SCRIPT) {
477                         DbgFree(info->dbox.info.script.path);
478                         DbgFree(info->dbox.info.script.group);
479                 }
480                 parser_unload(parser);
481                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
482         }
483
484         info->secured = parser_secured(parser);
485         info->dbox.pinup = parser_pinup(parser);
486
487         parser_get_gbar_size(parser, &info->gbar.width, &info->gbar.height);
488
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);
492         }
493
494         parser_unload(parser);
495         return DBOX_STATUS_ERROR_NONE;
496 }
497
498 HAPI struct pkg_info *package_create(const char *pkgid, const char *dbox_id)
499 {
500         struct pkg_info *pkginfo;
501
502         pkginfo = calloc(1, sizeof(*pkginfo));
503         if (!pkginfo) {
504                 ErrPrint("Heap: %s\n", strerror(errno));
505                 return NULL;
506         }
507
508         pkginfo->pkgid = strdup(pkgid);
509         if (!pkginfo->pkgid) {
510                 ErrPrint("Heap: %s\n", strerror(errno));
511                 DbgFree(pkginfo);
512                 return NULL;
513         }
514
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);
522                         DbgFree(pkginfo);
523                         return NULL;
524                 }
525         }
526
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);
533                         DbgFree(pkginfo);
534                         return NULL;
535                 }
536         }
537
538         package_ref(pkginfo);
539
540         s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
541
542         return pkginfo;
543 }
544
545 HAPI int package_destroy(struct pkg_info *info)
546 {
547         package_unref(info);
548         return DBOX_STATUS_ERROR_NONE;
549 }
550
551 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
552 {
553         return pkginfo->ctx_list;
554 }
555
556 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
557 {
558         pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
559 }
560
561 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
562 {
563         pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
564 }
565
566 HAPI char *package_dbox_pkgname(const char *pkgname)
567 {
568         char *dbox_id;
569
570         dbox_id = io_dynamicbox_pkgname(pkgname);
571         if (!dbox_id) {
572                 dbox_id = strdup(pkgname);
573                 if (!dbox_id) {
574                         ErrPrint("Heap: %s\n", strerror(errno));
575                         return NULL;
576                 }
577         }
578
579         return dbox_id;
580 }
581
582 HAPI int package_is_dbox_pkgname(const char *pkgname)
583 {
584         char *dbox_id;
585         int ret;
586
587         dbox_id = package_dbox_pkgname(pkgname);
588         ret = !!dbox_id;
589         DbgFree(dbox_id);
590
591         return ret;
592 }
593
594 HAPI struct pkg_info *package_find(const char *dbox_id)
595 {
596         Eina_List *l;
597         struct pkg_info *info;
598
599         if (!dbox_id) {
600                 return NULL;
601         }
602
603         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
604                 if (!strcmp(info->dbox_id, dbox_id)) {
605                         return info;
606                 }
607         }
608
609         return NULL;
610 }
611
612 HAPI struct inst_info *package_find_instance_by_id(const char *dbox_id, const char *id)
613 {
614         Eina_List *l;
615         struct inst_info *inst;
616         struct pkg_info *info;
617
618         info = package_find(dbox_id);
619         if (!info) {
620                 ErrPrint("Package %s is not exists\n", dbox_id);
621                 return NULL;
622         }
623
624         EINA_LIST_FOREACH(info->inst_list, l, inst) {
625                 if (!strcmp(instance_id(inst), id)) {
626                         return inst;
627                 }
628         }
629
630         return NULL;
631 }
632
633 HAPI struct inst_info *package_find_instance_by_timestamp(const char *dbox_id, double timestamp)
634 {
635         Eina_List *l;
636         struct inst_info *inst;
637         struct pkg_info *info;
638
639         info = package_find(dbox_id);
640         if (!info) {
641                 ErrPrint("Package %s is not exists\n", dbox_id);
642                 return NULL;
643         }
644
645         EINA_LIST_FOREACH(info->inst_list, l, inst) {
646                 if (instance_timestamp(inst) == timestamp) {
647                         return inst;
648                 }
649         }
650
651         return NULL;
652 }
653
654 HAPI int package_dump_fault_info(struct pkg_info *info)
655 {
656         if (!info->fault_info) {
657                 return DBOX_STATUS_ERROR_NOT_EXIST;
658         }
659
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;
666 }
667
668 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
669 {
670         if (!info->fault_info) {
671                 return DBOX_STATUS_ERROR_NOT_EXIST;
672         }
673
674         *timestamp = info->fault_info->timestamp;
675         *filename = info->fault_info->filename;
676         *function = info->fault_info->function;
677         return DBOX_STATUS_ERROR_NONE;
678 }
679
680 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
681 {
682         struct fault_info *fault;
683
684         package_clear_fault(info);
685
686         fault = calloc(1, sizeof(*fault));
687         if (!fault) {
688                 ErrPrint("Heap: %s\n", strerror(errno));
689                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
690         }
691
692         fault->timestamp = timestamp;
693         if (!filename) {
694                 filename = "unknown";
695         }
696         if (!function) {
697                 function = "unknown";
698         }
699
700         fault->filename = strdup(filename);
701         if (!fault->filename) {
702                 ErrPrint("Heap: %s\n", strerror(errno));
703                 DbgFree(fault);
704                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
705         }
706
707         fault->function = strdup(function);
708         if (!fault->function) {
709                 ErrPrint("Heap: %s\n", strerror(errno));
710                 DbgFree(fault->filename);
711                 DbgFree(fault);
712                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
713         }
714
715         info->fault_info = fault;
716         info->fault_count++;
717         return DBOX_STATUS_ERROR_NONE;
718 }
719
720 HAPI int package_clear_fault(struct pkg_info *info)
721 {
722         if (!info->fault_info) {
723                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
724         }
725
726         package_dump_fault_info(info);
727
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;
733 }
734
735 HAPI const int const package_is_fault(const struct pkg_info *info)
736 {
737         return !!info->fault_info;
738 }
739
740 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
741 {
742         return info->slave;
743 }
744
745 HAPI const int const package_timeout(const struct pkg_info *info)
746 {
747         return info->dbox.timeout;
748 }
749
750 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
751 {
752         info->dbox.timeout = timeout;
753 }
754
755 HAPI const double const package_period(const struct pkg_info *info)
756 {
757         return info->dbox.period;
758 }
759
760 HAPI void package_set_period(struct pkg_info *info, double period)
761 {
762         info->dbox.period = period;
763 }
764
765 HAPI const int const package_secured(const struct pkg_info *info)
766 {
767         return info->secured;
768 }
769
770 HAPI void package_set_secured(struct pkg_info *info, int secured)
771 {
772         info->secured = secured;
773 }
774
775 HAPI const char * const package_script(const struct pkg_info *info)
776 {
777         return info->script;
778 }
779
780 HAPI int package_set_script(struct pkg_info *info, const char *script)
781 {
782         char *tmp;
783
784         tmp = strdup(script);
785         if (!tmp) {
786                 ErrPrint("Heap: %s\n", strerror(errno));
787                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
788         }
789
790         DbgFree(info->script);
791         info->script = tmp;
792         return DBOX_STATUS_ERROR_NONE;
793 }
794
795 HAPI const char * const package_abi(const struct pkg_info *info)
796 {
797         return info->abi;
798 }
799
800 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
801 {
802         char *tmp;
803         tmp = strdup(abi);
804         if (!tmp) {
805                 ErrPrint("Heap: %s\n", strerror(errno));
806                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
807         }
808
809         DbgFree(info->abi);
810         info->abi = tmp;
811         return DBOX_STATUS_ERROR_NONE;
812 }
813
814 HAPI const char * const package_dbox_path(const struct pkg_info *info)
815 {
816         if (info->dbox.type != DBOX_TYPE_SCRIPT) {
817                 return NULL;
818         }
819
820         return info->dbox.info.script.path;
821 }
822
823 HAPI int package_set_dbox_path(struct pkg_info *info, const char *path)
824 {
825         char *tmp;
826
827         if (info->dbox.type != DBOX_TYPE_SCRIPT) {
828                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
829         }
830
831         tmp = strdup(path);
832         if (!tmp) {
833                 ErrPrint("Heap: %s\n", strerror(errno));
834                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
835         }
836
837         DbgFree(info->dbox.info.script.path);
838         info->dbox.info.script.path = tmp;
839         return DBOX_STATUS_ERROR_NONE;
840 }
841
842 HAPI const char * const package_dbox_group(const struct pkg_info *info)
843 {
844         if (info->dbox.type != DBOX_TYPE_SCRIPT) {
845                 return NULL;
846         }
847
848         return info->dbox.info.script.group;
849 }
850
851 HAPI int package_set_dbox_group(struct pkg_info *info, const char *group)
852 {
853         char *tmp;
854
855         if (info->dbox.type != DBOX_TYPE_SCRIPT) {
856                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
857         }
858
859         tmp = strdup(group);
860         if (!tmp) {
861                 ErrPrint("Heap: %s\n", strerror(errno));
862                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
863         }
864
865         DbgFree(info->dbox.info.script.group);
866         info->dbox.info.script.group = tmp;
867         return DBOX_STATUS_ERROR_NONE;
868 }
869
870 HAPI const char * const package_gbar_path(const struct pkg_info *info)
871 {
872         if (info->gbar.type != GBAR_TYPE_SCRIPT) {
873                 return NULL;
874         }
875
876         return info->gbar.info.script.path;
877 }
878
879 HAPI int package_set_gbar_path(struct pkg_info *info, const char *path)
880 {
881         char *tmp;
882
883         if (info->gbar.type != GBAR_TYPE_SCRIPT) {
884                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
885         }
886
887         tmp = strdup(path);
888         if (!tmp) {
889                 ErrPrint("Heap: %s\n", strerror(errno));
890                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
891         }
892
893         DbgFree(info->gbar.info.script.path);
894         info->gbar.info.script.path = tmp;
895         return DBOX_STATUS_ERROR_NONE;
896 }
897
898 HAPI const char * const package_gbar_group(const struct pkg_info *info)
899 {
900         if (info->gbar.type != GBAR_TYPE_SCRIPT) {
901                 return NULL;
902         }
903
904         return info->gbar.info.script.group;
905 }
906
907 HAPI int package_set_gbar_group(struct pkg_info *info, const char *group)
908 {
909         char *tmp;
910
911         if (info->gbar.type != GBAR_TYPE_SCRIPT) {
912                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
913         }
914
915         tmp = strdup(group);
916         if (!tmp) {
917                 ErrPrint("Heap: %s\n", strerror(errno));
918                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
919         }
920
921         DbgFree(info->gbar.info.script.group);
922         info->gbar.info.script.group = tmp;
923         return DBOX_STATUS_ERROR_NONE;
924 }
925
926 HAPI const int const package_pinup(const struct pkg_info *info)
927 {
928         return info->dbox.pinup;
929 }
930
931 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
932 {
933         info->dbox.pinup = pinup;
934 }
935
936 HAPI const char * const package_auto_launch(const struct pkg_info *info)
937 {
938         return info->dbox.auto_launch;
939 }
940
941 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
942 {
943         if (!auto_launch) {
944                 auto_launch = "";
945         }
946
947         info->dbox.auto_launch = strdup(auto_launch);
948         if (!info->dbox.auto_launch) {
949                 ErrPrint("Heap: %s\n", strerror(errno));
950                 return;
951         }
952 }
953
954 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
955 {
956         return info->dbox.size_list;
957 }
958
959 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
960 {
961         info->dbox.size_list = size_list;
962 }
963
964 HAPI const int const package_gbar_width(const struct pkg_info *info)
965 {
966         return info->gbar.width;
967 }
968
969 HAPI void package_set_gbar_width(struct pkg_info *info, int width)
970 {
971         info->gbar.width = width;
972 }
973
974 HAPI const int const package_gbar_height(const struct pkg_info *info)
975 {
976         return info->gbar.height;
977 }
978
979 HAPI void package_set_gbar_height(struct pkg_info *info, int height)
980 {
981         info->gbar.height = height;
982 }
983
984 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
985 {
986         info->refcnt++;
987         return info;
988 }
989
990 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
991 {
992         if (info->refcnt == 0) {
993                 ErrPrint("Invalid request\n");
994                 return NULL;
995         }
996
997         info->refcnt--;
998         if (info->refcnt == 0) {
999                 destroy_package(info);
1000                 info = NULL;
1001         }
1002
1003         return info;
1004 }
1005
1006 HAPI const int const package_refcnt(const struct pkg_info *info)
1007 {
1008         return info->refcnt;
1009 }
1010
1011 HAPI const enum dynamicbox_dbox_type package_dbox_type(const struct pkg_info *info)
1012 {
1013         return info ? info->dbox.type : DBOX_TYPE_NONE;
1014 }
1015
1016 HAPI void package_set_dbox_type(struct pkg_info *info, enum dynamicbox_dbox_type type)
1017 {
1018         info->dbox.type = type;
1019 }
1020
1021 HAPI const char * const package_libexec(struct pkg_info *info)
1022 {
1023         return info->dbox.libexec;
1024 }
1025
1026 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1027 {
1028         char *tmp;
1029
1030         tmp = strdup(libexec);
1031         if (!tmp) {
1032                 ErrPrint("Heap: %s\n", strerror(errno));
1033                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1034         }
1035
1036         DbgFree(info->dbox.libexec);
1037         info->dbox.libexec = tmp;
1038         return DBOX_STATUS_ERROR_NONE;
1039 }
1040
1041 HAPI int package_network(struct pkg_info *info)
1042 {
1043         return info->network;
1044 }
1045
1046 HAPI void package_set_network(struct pkg_info *info, int network)
1047 {
1048         info->network = network;
1049 }
1050
1051 HAPI void package_set_direct_input(struct pkg_info *info, int direct_input)
1052 {
1053         info->direct_input = direct_input;
1054 }
1055
1056 HAPI int package_direct_input(const struct pkg_info *info)
1057 {
1058         return info->direct_input;
1059 }
1060
1061 HAPI const enum dynamicbox_gbar_type const package_gbar_type(const struct pkg_info *info)
1062 {
1063         return info ? info->gbar.type : GBAR_TYPE_NONE;
1064 }
1065
1066 HAPI void package_set_gbar_type(struct pkg_info *info, enum dynamicbox_gbar_type type)
1067 {
1068         info->gbar.type = type;
1069 }
1070
1071 HAPI const char *package_hw_acceleration(struct pkg_info *info)
1072 {
1073         return info->hw_acceleration;
1074 }
1075
1076 HAPI int package_set_hw_acceleration(struct pkg_info *info, const char *hw_acceleration)
1077 {
1078         char *tmp;
1079
1080         if (!hw_acceleration || !info) {
1081                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1082         }
1083
1084         tmp = strdup(hw_acceleration);
1085         if (!tmp) {
1086                 ErrPrint("strdup: %s\n", strerror(errno));
1087                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1088         }
1089
1090         DbgFree(info->hw_acceleration);
1091         info->hw_acceleration = tmp;
1092         return DBOX_STATUS_ERROR_NONE;
1093 }
1094
1095 /*!
1096  * \note
1097  * Add the instance to the package info.
1098  * If a package has no slave, assign a new slave.
1099  */
1100 static inline int assign_new_slave(const char *slave_pkgname, struct pkg_info *info)
1101 {
1102         char *s_name;
1103
1104         s_name = util_slavename();
1105         if (!s_name) {
1106                 ErrPrint("Failed to get a new slave name\n");
1107                 return DBOX_STATUS_ERROR_FAULT;
1108         }
1109
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);
1112
1113         DbgFree(s_name);
1114
1115         if (!info->slave) {
1116                 /*!
1117                  * \note
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.
1122                  */
1123                 return DBOX_STATUS_ERROR_FAULT;
1124         }
1125         /*!
1126          * \note
1127          * Slave is not activated yet.
1128          */
1129         return DBOX_STATUS_ERROR_NONE;
1130 }
1131
1132 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1133 {
1134         if (!info->inst_list) {
1135                 char *slave_pkgname;
1136
1137                 slave_pkgname = slave_package_name(info->abi, info->dbox_id);
1138                 if (!slave_pkgname) {
1139                         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1140                 }
1141
1142                 info->slave = slave_find_available(slave_pkgname, info->abi, info->secured, info->network, info->hw_acceleration);
1143                 if (!info->slave) {
1144                         int ret;
1145
1146                         ret = assign_new_slave(slave_pkgname, info);
1147                         DbgFree(slave_pkgname);
1148                         if (ret < 0) {
1149                                 return ret;
1150                         }
1151                 } else {
1152                         DbgFree(slave_pkgname);
1153                         DbgPrint("Slave %s is used for %s\n", slave_name(info->slave), info->dbox_id);
1154                 }
1155
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);
1161
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);
1165
1166                         /*!
1167                          * \note
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.
1171                          *
1172                          * This callback will freeze the timer only if a slave doesn't running.
1173                          */
1174                         (void)xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1175                         (void)xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1176                 }
1177         }
1178
1179         info->inst_list = eina_list_append(info->inst_list, inst);
1180         return DBOX_STATUS_ERROR_NONE;
1181 }
1182
1183 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1184 {
1185         info->inst_list = eina_list_remove(info->inst_list, inst);
1186
1187         if (info->inst_list) {
1188                 return DBOX_STATUS_ERROR_NONE;
1189         }
1190
1191         if (info->slave) {
1192                 slave_unload_package(info->slave);
1193
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);
1197
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);
1201
1202                         xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1203                         xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1204                 }
1205
1206                 slave_unref(info->slave);
1207                 info->slave = NULL;
1208         }
1209
1210         if (info->is_uninstalled) {
1211                 package_destroy(info);
1212         }
1213
1214         return DBOX_STATUS_ERROR_NONE;
1215 }
1216
1217 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1218 {
1219         return info->inst_list;
1220 }
1221
1222 static int client_created_cb(struct client_node *client, void *data)
1223 {
1224         struct pkg_info *info;
1225         Eina_List *l;
1226
1227         struct inst_info *inst;
1228         Eina_List *i_l;
1229
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);
1233                         continue;
1234                 }
1235
1236                 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1237                         switch (instance_state(inst)) {
1238                         case INST_INIT:
1239                                 /* Will be send a created event after the instance gets created event */
1240                                 break;
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) {
1247                                         /*!
1248                                          * \note
1249                                          * Instances are lives in the system cluster/sub-cluster
1250                                          */
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);
1254                                         }
1255                                 }
1256
1257                                 break;
1258                         default:
1259                                 DbgPrint("%s(%s) is not activated (%d)\n",
1260                                                 package_name(info), instance_id(inst), instance_state(inst));
1261                                 break;
1262                         }
1263                 }
1264         }
1265
1266         return 0;
1267 }
1268
1269 static int io_uninstall_cb(const char *pkgid, const char *dbox_id, int prime, void *data)
1270 {
1271         struct pkg_info *info;
1272         Eina_List *l;
1273         Eina_List *n;
1274         struct inst_info *inst;
1275
1276         DbgPrint("Package %s is uninstalled\n", dbox_id);
1277         info = package_find(dbox_id);
1278         if (!info) {
1279                 DbgPrint("%s is not yet loaded\n", dbox_id);
1280                 return 0;
1281         }
1282
1283         info->is_uninstalled = 1;
1284
1285         /*!
1286          * \NOTE
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.
1290          */
1291         if (info->inst_list) {
1292                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1293                         instance_destroy(inst, DBOX_DESTROY_TYPE_UNINSTALL);
1294                 }
1295         } else {
1296                 package_destroy(info);
1297         }
1298
1299         return 0;
1300 }
1301
1302 static inline void reload_package_info(struct pkg_info *info)
1303 {
1304         Eina_List *l;
1305         Eina_List *n;
1306         struct inst_info *inst;
1307         unsigned int size_type;
1308         int width;
1309         int height;
1310         double old_period;
1311
1312         DbgPrint("Already exists, try to update it\n");
1313
1314         old_period = info->dbox.period;
1315
1316         group_del_dynamicbox(info->dbox_id);
1317         package_clear_fault(info);
1318
1319         /*!
1320          * \NOTE:
1321          * Nested DB I/O
1322          */
1323         io_load_package_db(info);
1324
1325         /*!
1326          * \note
1327          * Without "is_uninstalled", the package will be kept
1328          */
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));
1336                         }
1337                         instance_reload(inst, DBOX_DESTROY_TYPE_UPGRADE);
1338                 } else {
1339                         instance_destroy(inst, DBOX_DESTROY_TYPE_UNINSTALL);
1340                 }
1341         }
1342 }
1343
1344 static int io_install_cb(const char *pkgid, const char *dbox_id, int prime, void *data)
1345 {
1346         struct pkg_info *info;
1347
1348         info = package_find(dbox_id);
1349         if (info) {
1350                 /*!
1351                  * Already exists. skip to create this.
1352                  */
1353                 return 0;
1354         }
1355
1356         info = package_create(pkgid, dbox_id);
1357         if (!info) {
1358                 ErrPrint("Failed to build an info %s\n", dbox_id);
1359         } else {
1360                 DbgPrint("Dynamicbox %s is built\n", dbox_id);
1361         }
1362
1363         return 0;
1364 }
1365
1366 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1367 {
1368         Eina_List *l;
1369         Eina_List *n;
1370         struct pkg_info *info;
1371
1372         if (status != PKGMGR_STATUS_END) {
1373                 return 0;
1374         }
1375
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);
1379                 }
1380         }
1381
1382         return 0;
1383 }
1384
1385 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1386 {
1387         Eina_List *l;
1388         Eina_List *n;
1389         struct pkg_info *info;
1390
1391         if (status != PKGMGR_STATUS_END) {
1392                 return 0;
1393         }
1394
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);
1400                         } else {
1401                                 io_uninstall_cb(pkgname, info->dbox_id, -1, NULL);
1402                         }
1403                 }
1404         }
1405
1406         (void)io_update_dynamicbox_package(pkgname, io_install_cb, NULL);
1407         return 0;
1408 }
1409
1410 static int crawling_dynamicboxes(const char *pkgid, const char *dbox_id, int prime, void *data)
1411 {
1412         if (package_find(dbox_id)) {
1413                 ErrPrint("Information of %s is already built\n", dbox_id);
1414         } else {
1415                 struct pkg_info *info;
1416                 info = package_create(pkgid, dbox_id);
1417                 if (info) {
1418                         DbgPrint("[%s] information is built prime(%d)\n", dbox_id, prime);
1419                 }
1420         }
1421
1422         return 0;
1423 }
1424
1425 HAPI int package_init(void)
1426 {
1427         client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1428         pkgmgr_init();
1429
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);
1433
1434         io_crawling_dynamicboxes(crawling_dynamicboxes, NULL);
1435         return 0;
1436 }
1437
1438 HAPI int package_fini(void)
1439 {
1440         Eina_List *p_l;
1441         Eina_List *p_n;
1442         Eina_List *i_l;
1443         Eina_List *i_n;
1444         struct pkg_info *info;
1445         struct inst_info *inst;
1446
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);
1450         pkgmgr_fini();
1451         client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1452
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);
1457                 }
1458
1459                 package_destroy(info);
1460         }
1461
1462         return 0;
1463 }
1464
1465 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1466 {
1467         Eina_List *l;
1468         struct pkg_info *info;
1469
1470         if (!slave_is_secured(slave)) {
1471                 return NULL;
1472         }
1473
1474         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1475                 if (info->slave == slave) {
1476                         return info->dbox_id;
1477                 }
1478         }
1479
1480         return NULL;
1481 }
1482
1483 HAPI const char * const package_name(const struct pkg_info *info)
1484 {
1485         return info->dbox_id;
1486 }
1487
1488 /*!
1489  * del_or_creat : 1 == create, 0 == delete
1490  */
1491 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1492 {
1493         struct pkg_info *info;
1494         Eina_List *l;
1495
1496         struct inst_info *inst;
1497         Eina_List *i_l;
1498
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)) {
1502                                 continue;
1503                         }
1504
1505                         if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1506                                 continue;
1507                         }
1508
1509                         switch (instance_state(inst)) {
1510                         case INST_INIT:
1511                         case INST_REQUEST_TO_ACTIVATE:
1512                                 /* Will be send a created event after the instance gets created event */
1513                                 switch (alter) {
1514                                 case ALTER_CREATE:
1515                                         if (!instance_has_client(inst, client)) {
1516                                                 instance_add_client(inst, client);
1517                                         }
1518                                         break;
1519                                 case ALTER_DESTROY:
1520                                         if (instance_has_client(inst, client)) {
1521                                                 instance_del_client(inst, client);
1522                                         }
1523                                         break;
1524                                 default:
1525                                         break;
1526                                 }
1527                                 break;
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 */
1531                                 /*!
1532                                  * \note
1533                                  * Instances are lives in the system cluster/sub-cluster
1534                                  */
1535                                 switch (alter) {
1536                                 case ALTER_CREATE:
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);
1541                                         }
1542                                         break;
1543                                 case ALTER_DESTROY:
1544                                         if (instance_has_client(inst, client)) {
1545                                                 instance_unicast_deleted_event(inst, client, DBOX_STATUS_ERROR_NONE);
1546                                                 instance_del_client(inst, client);
1547                                         }
1548                                         break;
1549                                 default:
1550                                         break;
1551                                 }
1552
1553                                 break;
1554                         default:
1555                                 DbgPrint("%s(%s) is not activated (%d)\n",
1556                                                 package_name(info), instance_id(inst), instance_state(inst));
1557                                 break;
1558                         }
1559                 }
1560         }
1561
1562         return 0;
1563 }
1564
1565 HAPI const Eina_List *package_list(void)
1566 {
1567         return s_info.pkg_list;
1568 }
1569
1570 HAPI int const package_fault_count(struct pkg_info *info)
1571 {
1572         return info ? info->fault_count : 0;
1573 }
1574
1575 HAPI int package_is_enabled(const char *appid)
1576 {
1577         pkgmgrinfo_appinfo_h handle;
1578         bool enabled;
1579         int ret;
1580
1581         ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
1582         if (ret != PMINFO_R_OK) {
1583                 ErrPrint("Failed to get info\n");
1584                 return 0;
1585         }
1586
1587         ret = pkgmgrinfo_appinfo_is_enabled(handle, &enabled);
1588         if (ret != PMINFO_R_OK) {
1589                 ErrPrint("Failed to get info\n");
1590                 enabled = false;
1591         }
1592
1593         pkgmgrinfo_appinfo_destroy_appinfo(handle);
1594         return enabled == true;
1595 }
1596
1597 HAPI int package_faulted(struct pkg_info *pkg, int broadcast)
1598 {
1599         Eina_List *l;
1600         Eina_List *n;
1601         struct slave_node *slave;
1602         struct inst_info *inst;
1603
1604         slave = package_slave(pkg);
1605         if (!slave) {
1606                 ErrPrint("Package has no slave?\n");
1607                 return DBOX_STATUS_ERROR_FAULT;
1608         }
1609
1610         /* Emulated fault routine */
1611         // (void)package_set_fault_info(pkg, util_timestamp(), slave_name(slave), __func__);
1612         if (broadcast) {
1613                 fault_broadcast_info(package_name(pkg), slave_name(slave), __func__);
1614         }
1615
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);
1620         }
1621
1622         return DBOX_STATUS_ERROR_NONE;
1623 }
1624
1625 /* End of a file */