Initialize the project.
[apps/livebox/data-provider-master.git] / src / package.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (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://www.tizenopensource.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 #include <Ecore_Evas.h>
25
26 #include <packet.h>
27
28 #include "debug.h"
29 #include "util.h"
30 #include "parser.h"
31 #include "conf.h"
32 #include "slave_life.h"
33 #include "slave_rpc.h"
34 #include "client_life.h"
35 #include "package.h"
36 #include "fault_manager.h"
37 #include "instance.h"
38 #include "script_handler.h"
39 #include "group.h"
40 #include "abi.h"
41 #include "io.h"
42 #include "pkgmgr.h"
43 #include "ctx_client.h"
44 #include "xmonitor.h"
45
46 int errno;
47
48 struct fault_info {
49         double timestamp;
50         char *filename;
51         char *function;
52 };
53
54 /*!
55  * pkg_info describes the loaded package.
56  */
57
58 struct pkg_info {
59         char *pkgname;
60
61         struct {
62                 enum lb_type type;
63
64                 union {
65                         struct {
66                                 char *path;
67                                 char *group;
68                         } script;
69
70                         struct {
71                                 /*!< Reserved for future use */
72                         } file;
73
74                         struct {
75                                 /*!< Reserved for future use */
76                         } text;
77
78                         struct {
79                                 /*!< Reserved for future use */
80                         } buffer;
81                 } info;
82
83                 unsigned int size_list;
84                 int auto_launch;
85                 int pinup;
86         } lb;
87
88         struct {
89                 enum pd_type type;
90
91                 union {
92                         struct {
93                                 char *path;
94                                 char *group;
95                         } script;
96
97                         struct {
98                                 /*!< Reserved for future use */
99                         } text;
100
101                         struct {
102                                 /*!< Reserved for future use */
103                         } buffer;
104                 } info;
105
106                 unsigned int width;
107                 unsigned int height;
108         } pd;
109
110         int network;
111         int timeout;
112         double period;
113         int secured;
114         char *script; /* script type: edje, ... */
115         char *abi;
116         char *libexec;
117
118         int fault_count;
119         struct fault_info *fault_info;
120
121         struct slave_node *slave;
122         int refcnt;
123
124         Eina_List *inst_list;
125         Eina_List *ctx_list;
126
127         int is_uninstalled;
128 };
129
130 static struct {
131         Eina_List *pkg_list;
132 } s_info = {
133         .pkg_list = NULL,
134 };
135
136 static int slave_activated_cb(struct slave_node *slave, void *data)
137 {
138         struct pkg_info *info = data;
139         struct inst_info *inst;
140         Eina_List *l;
141         Eina_List *n;
142         int cnt;
143         int ret;
144
145         if (!slave_need_to_reactivate_instances(slave)) {
146                 DbgPrint("Do not need to reactivate instances\n");
147                 return 0;
148         }
149
150         cnt = 0;
151         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
152                 ret = instance_recover_state(inst);
153                 if (!ret)
154                         continue;
155
156                 instance_thaw_updator(inst);
157                 cnt++;
158         }
159
160         DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
161         return 0;
162 }
163
164 static int slave_fault_cb(struct slave_node *slave, void *data)
165 {
166         Eina_List *l;
167         Eina_List *n;
168         struct inst_info *inst;
169         struct pkg_info *info = (struct pkg_info *)data;
170
171         DbgPrint("Slave %s has critical fault. destroy all instances\n", slave_name(slave));
172         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
173                 DbgPrint("Destroy instance %p\n", inst);
174                 instance_destroyed(inst);
175         }
176
177         return 0;
178 }
179
180 static int slave_deactivated_cb(struct slave_node *slave, void *data)
181 {
182         struct pkg_info *info = data;
183         struct inst_info *inst;
184         Eina_List *l;
185         Eina_List *n;
186         int cnt = 0;
187
188         if (info->fault_info) {
189                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
190                         instance_destroyed(inst);
191                 }
192         } else {
193                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
194                         cnt += instance_need_slave(inst);
195                         /*!
196                          * instance_deactivated will call the slave_unload_instance.
197                          * if the loaded instance counter meets 0,
198                          * the slave will be deactivated.
199                          * so we should not call the instance activate function
200                          * from here.
201                          *
202                          * activate slave when the slave is reactivated
203                          */
204                 }
205         }
206
207         return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
208 }
209
210 static int xmonitor_paused_cb(void *data)
211 {
212         struct pkg_info *info = (struct pkg_info *)data;
213         struct inst_info *inst;
214         Eina_List *l;
215
216         if (slave_state(info->slave) != SLAVE_TERMINATED) {
217                 DbgPrint("Skip this\n");
218                 return 0;
219         }
220
221         EINA_LIST_FOREACH(info->inst_list, l, inst) {
222                 instance_freeze_updator(inst);
223         }
224
225         return 0;
226 }
227
228 static int xmonitor_resumed_cb(void *data)
229 {
230         struct pkg_info *info = data;
231         struct inst_info *inst;
232         Eina_List *l;
233
234         if (slave_state(info->slave) != SLAVE_TERMINATED) {
235                 DbgPrint("Skip this\n");
236                 return 0;
237         }
238
239         EINA_LIST_FOREACH(info->inst_list, l, inst) {
240                 instance_thaw_updator(inst);
241         }
242
243         return 0;
244 }
245
246 static int slave_paused_cb(struct slave_node *slave, void *data)
247 {
248         struct pkg_info *info = (struct pkg_info *)data;
249         struct inst_info *inst;
250         Eina_List *l;
251
252         EINA_LIST_FOREACH(info->inst_list, l, inst) {
253                 instance_freeze_updator(inst);
254         }
255
256         return 0;
257 }
258
259 static int slave_resumed_cb(struct slave_node *slave, void *data)
260 {
261         struct pkg_info *info = (struct pkg_info *)data;
262         struct inst_info *inst;
263         Eina_List *l;
264
265         EINA_LIST_FOREACH(info->inst_list, l, inst) {
266                 instance_thaw_updator(inst);
267         }
268
269         return 0;
270 }
271
272 static inline void destroy_package(struct pkg_info *info)
273 {
274         struct context_info *ctx_info;
275
276         EINA_LIST_FREE(info->ctx_list, ctx_info) {
277                 ctx_disable_event_handler(ctx_info);
278         }
279
280         group_del_livebox(info->pkgname);
281         package_clear_fault(info);
282
283         s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
284
285         if (info->lb.type == LB_TYPE_SCRIPT) {
286                 DbgFree(info->lb.info.script.path);
287                 DbgFree(info->lb.info.script.group);
288         }
289
290         if (info->pd.type == PD_TYPE_SCRIPT) {
291                 DbgFree(info->pd.info.script.path);
292                 DbgFree(info->pd.info.script.group);
293         }
294
295         DbgFree(info->script);
296         DbgFree(info->abi);
297         DbgFree(info->pkgname);
298         DbgFree(info->libexec);
299
300         DbgFree(info);
301 }
302
303 static inline int load_conf(struct pkg_info *info)
304 {
305         struct parser *parser;
306         const char *str;
307         const char *group;
308
309         parser = parser_load(info->pkgname);
310         if (!parser) {
311                 info->lb.size_list = 0x01; /* Default */
312
313                 info->script = strdup(DEFAULT_SCRIPT);
314                 if (!info->script) {
315                         ErrPrint("Heap: %s\n", strerror(errno));
316                         return -ENOMEM;
317                 }
318
319                 info->abi = strdup(DEFAULT_ABI);
320                 if (!info->abi) {
321                         ErrPrint("Heap: %s\n", strerror(errno));
322                         DbgFree(info->script);
323                         info->script = NULL;
324                         return -ENOMEM;
325                 }
326
327                 info->pd.width = g_conf.width;
328                 info->pd.height = g_conf.height >> 2;
329                 info->lb.pinup = 1;
330                 return 0;
331         }
332
333         info->lb.type = LB_TYPE_FILE;
334         if (parser_text_lb(parser)) {
335                 info->lb.type = LB_TYPE_TEXT;
336         } else if (parser_buffer_lb(parser)) {
337                 info->lb.type = LB_TYPE_BUFFER;
338         } else {
339                 str = parser_lb_path(parser);
340                 if (str) {
341                         info->lb.type = LB_TYPE_SCRIPT;
342
343                         info->lb.info.script.path = strdup(str);
344                         if (!info->lb.info.script.path) {
345                                 ErrPrint("Heap: %s\n", strerror(errno));
346                                 parser_unload(parser);
347                                 return -ENOMEM;
348                         }
349
350                         str = parser_lb_group(parser);
351                         if (str) {
352                                 info->lb.info.script.group = strdup(str);
353                                 if (!info->lb.info.script.group) {
354                                         ErrPrint("Heap: %s\n", strerror(errno));
355                                         DbgFree(info->lb.info.script.path);
356                                         parser_unload(parser);
357                                         return -ENOMEM;
358                                 }
359                         }
360                 }
361         }
362
363         if (parser_text_pd(parser)) {
364                 info->pd.type = PD_TYPE_TEXT;
365         } else if (parser_buffer_pd(parser)) {
366                 info->pd.type = PD_TYPE_BUFFER;
367         } else {
368                 str = parser_pd_path(parser);
369                 if (str) {
370                         info->pd.type = PD_TYPE_SCRIPT;
371                         info->pd.info.script.path = strdup(str);
372                         if (!info->pd.info.script.path) {
373                                 ErrPrint("Heap: %s\n", strerror(errno));
374                                 if (info->lb.type == LB_TYPE_SCRIPT) {
375                                         DbgFree(info->lb.info.script.path);
376                                         DbgFree(info->lb.info.script.group);
377                                 }
378                                 parser_unload(parser);
379                                 return -ENOMEM;
380                         }
381
382                         str = parser_pd_group(parser);
383                         if (str) {
384                                 info->pd.info.script.group = strdup(str);
385                                 if (!info->pd.info.script.group) {
386                                         ErrPrint("Heap: %s\n", strerror(errno));
387                                         DbgFree(info->pd.info.script.path);
388                                         if (info->lb.type == LB_TYPE_SCRIPT) {
389                                                 DbgFree(info->lb.info.script.path);
390                                                 DbgFree(info->lb.info.script.group);
391                                         }
392                                         parser_unload(parser);
393                                         return -ENOMEM;
394                                 }
395                         }
396                 }
397         }
398
399         str = parser_script(parser);
400         str = str ? str : DEFAULT_SCRIPT;
401         info->script = strdup(str);
402         if (!info->script) {
403                 ErrPrint("Heap: %s\n", strerror(errno));
404                 if (info->pd.type == PD_TYPE_SCRIPT) {
405                         DbgFree(info->pd.info.script.path);
406                         DbgFree(info->pd.info.script.group);
407                 }
408
409                 if (info->lb.type == LB_TYPE_SCRIPT) {
410                         DbgFree(info->lb.info.script.path);
411                         DbgFree(info->lb.info.script.group);
412                 }
413
414                 parser_unload(parser);
415                 return -ENOMEM;
416         }
417
418         str = parser_abi(parser);
419         str = str ? str : DEFAULT_ABI;
420         info->abi = strdup(str);
421         if (!info->abi) {
422                 ErrPrint("Heap: %s\n", strerror(errno));
423                 DbgFree(info->script);
424                 if (info->pd.type == PD_TYPE_SCRIPT) {
425                         DbgFree(info->pd.info.script.path);
426                         DbgFree(info->pd.info.script.group);
427                 }
428
429                 if (info->lb.type == LB_TYPE_SCRIPT) {
430                         DbgFree(info->lb.info.script.path);
431                         DbgFree(info->lb.info.script.group);
432                 }
433                 parser_unload(parser);
434                 return -ENOMEM;
435         }
436
437         info->timeout = parser_timeout(parser);
438         info->network = parser_network(parser);
439
440         info->period = parser_period(parser);
441         if (info->period < 0.0f)
442                 info->period = 0.0f;
443         else if (info->period > 0.0f && info->period < MINIMUM_PERIOD)
444                 info->period = MINIMUM_PERIOD;
445
446         info->lb.size_list = parser_size(parser);
447         info->lb.auto_launch = parser_auto_launch(parser);
448         info->secured = parser_secured(parser);
449         info->lb.pinup = parser_pinup(parser);
450
451         parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
452
453         group = parser_group_str(parser);
454         if (group && group_add_livebox(group, info->pkgname) < 0)
455                 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->pkgname, group);
456
457         parser_unload(parser);
458         return 0;
459 }
460
461 HAPI struct pkg_info *package_create(const char *pkgname)
462 {
463         struct pkg_info *pkginfo;
464         Eina_List *l;
465         struct context_info *ctx_info;
466
467         pkginfo = calloc(1, sizeof(*pkginfo));
468         if (!pkginfo) {
469                 ErrPrint("Heap: %s\n", strerror(errno));
470                 return NULL;
471         }
472
473         pkginfo->pkgname = io_livebox_pkgname(pkgname);
474         if (!pkginfo->pkgname) {
475                 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
476                 if (util_validate_livebox_package(pkgname) < 0) {
477                         ErrPrint("Invalid package name: %s\n", pkgname);
478                         DbgFree(pkginfo);
479                         return NULL;
480                 }
481
482                 pkginfo->pkgname = strdup(pkgname);
483                 if (!pkginfo->pkgname) {
484                         ErrPrint("Heap: %s\n", strerror(errno));
485                         DbgFree(pkginfo);
486                         return NULL;
487                 }
488         }
489
490         if (io_load_package_db(pkginfo) < 0) {
491                 ErrPrint("Failed to load DB, fall back to conf file loader\n");
492                 if (load_conf(pkginfo) < 0) {
493                         ErrPrint("Failed to initiate the conf file loader\n");
494                         DbgFree(pkginfo->pkgname);
495                         DbgFree(pkginfo);
496                         return NULL;
497                 }
498         }
499
500         package_ref(pkginfo);
501
502         s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
503
504         EINA_LIST_FOREACH(pkginfo->ctx_list, l, ctx_info) {
505                 ctx_enable_event_handler(ctx_info);
506         }
507
508         return pkginfo;
509 }
510
511 HAPI int package_destroy(struct pkg_info *info)
512 {
513         package_unref(info);
514         return 0;
515 }
516
517 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
518 {
519         return pkginfo->ctx_list;
520 }
521
522 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
523 {
524         pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
525 }
526
527 HAPI char *package_lb_pkgname(const char *pkgname)
528 {
529         char *lb_pkgname;
530
531         lb_pkgname = io_livebox_pkgname(pkgname);
532         if (!lb_pkgname) {
533                 if (util_validate_livebox_package(pkgname) < 0)
534                         return NULL;
535
536                 lb_pkgname = strdup(pkgname);
537                 if (!lb_pkgname) {
538                         ErrPrint("Heap: %s\n", strerror(errno));
539                         return NULL;
540                 }
541         }
542
543         return lb_pkgname;
544 }
545
546 HAPI int package_is_lb_pkgname(const char *pkgname)
547 {
548         char *lb_pkgname;
549         int ret;
550
551         lb_pkgname = package_lb_pkgname(pkgname);
552         ret = !!lb_pkgname;
553         DbgFree(lb_pkgname);
554
555         return ret;
556 }
557
558 HAPI struct pkg_info *package_find(const char *pkgname)
559 {
560         Eina_List *l;
561         struct pkg_info *info;
562
563         if (!pkgname)
564                 return NULL;
565
566         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
567                 if (!strcmp(info->pkgname, pkgname))
568                         return info;
569         }
570
571         return NULL;
572 }
573
574 HAPI struct inst_info *package_find_instance_by_id(const char *pkgname, const char *id)
575 {
576         Eina_List *l;
577         struct inst_info *inst;
578         struct pkg_info *info;
579
580         info = package_find(pkgname);
581         if (!info) {
582                 ErrPrint("Package %s is not exists\n", pkgname);
583                 return NULL;
584         }
585
586         EINA_LIST_FOREACH(info->inst_list, l, inst) {
587                 if (!strcmp(instance_id(inst), id))
588                         return inst;
589         }
590
591         return NULL;
592 }
593
594 HAPI struct inst_info *package_find_instance_by_timestamp(const char *pkgname, double timestamp)
595 {
596         Eina_List *l;
597         struct inst_info *inst;
598         struct pkg_info *info;
599
600         info = package_find(pkgname);
601         if (!info) {
602                 ErrPrint("Package %s is not exists\n", pkgname);
603                 return NULL;
604         }
605
606         EINA_LIST_FOREACH(info->inst_list, l, inst) {
607                 if (instance_timestamp(inst) == timestamp)
608                         return inst;
609         }
610
611         return NULL;
612 }
613
614 HAPI int package_dump_fault_info(struct pkg_info *info)
615 {
616         if (!info->fault_info)
617                 return -ENOENT;
618
619         ErrPrint("=============\n");
620         ErrPrint("faulted at %lf\n", info->fault_info->timestamp);
621         ErrPrint("Package: %s\n", info->pkgname);
622         ErrPrint("Function: %s\n", info->fault_info->function);
623         ErrPrint("InstanceID: %s\n", info->fault_info->filename);
624         return 0;
625 }
626
627 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
628 {
629         if (!info->fault_info)
630                 return -ENOENT;
631
632         *timestamp = info->fault_info->timestamp;
633         *filename = info->fault_info->filename;
634         *function = info->fault_info->function;
635         return 0;
636 }
637
638 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
639 {
640         struct fault_info *fault;
641
642         package_clear_fault(info);
643
644         fault = calloc(1, sizeof(*fault));
645         if (!fault) {
646                 ErrPrint("Heap: %s\n", strerror(errno));
647                 return -ENOMEM;
648         }
649
650         fault->timestamp = timestamp;
651         if (!filename)
652                 filename = "unknown";
653         if (!function)
654                 function = "unknown";
655
656         fault->filename = strdup(filename);
657         if (!fault->filename) {
658                 ErrPrint("Heap: %s\n", strerror(errno));
659                 DbgFree(fault);
660                 return -ENOMEM;
661         }
662
663         fault->function = strdup(function);
664         if (!fault->function) {
665                 ErrPrint("Heap: %s\n", strerror(errno));
666                 DbgFree(fault->filename);
667                 DbgFree(fault);
668                 return -ENOMEM;
669         }
670
671         info->fault_info = fault;
672         info->fault_count++;
673         return 0;
674 }
675
676 HAPI int package_clear_fault(struct pkg_info *info)
677 {
678         if (!info->fault_info)
679                 return -EINVAL;
680         
681         package_dump_fault_info(info);
682
683         DbgFree(info->fault_info->function);
684         DbgFree(info->fault_info->filename);
685         DbgFree(info->fault_info);
686         info->fault_info = NULL;
687         return 0;
688 }
689
690 HAPI const int const package_is_fault(const struct pkg_info *info)
691 {
692         return !!info->fault_info;
693 }
694
695 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
696 {
697         return info->slave;
698 }
699
700 HAPI const int const package_timeout(const struct pkg_info *info)
701 {
702         return info->timeout;
703 }
704
705 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
706 {
707         info->timeout = timeout;
708 }
709
710 HAPI const double const package_period(const struct pkg_info *info)
711 {
712         return info->period;
713 }
714
715 HAPI void package_set_period(struct pkg_info *info, double period)
716 {
717         info->period = period;
718 }
719
720 HAPI const int const package_secured(const struct pkg_info *info)
721 {
722         return info->secured;
723 }
724
725 HAPI void package_set_secured(struct pkg_info *info, int secured)
726 {
727         info->secured = secured;
728 }
729
730 HAPI const char * const package_script(const struct pkg_info *info)
731 {
732         return info->script;
733 }
734
735 HAPI int package_set_script(struct pkg_info *info, const char *script)
736 {
737         char *tmp;
738
739         tmp = strdup(script);
740         if (!tmp) {
741                 ErrPrint("Heap: %s\n", strerror(errno));
742                 return -ENOMEM;
743         }
744
745         DbgFree(info->script);
746         info->script = tmp;
747         return 0;
748 }
749
750 HAPI const char * const package_abi(const struct pkg_info *info)
751 {
752         return info->abi;
753 }
754
755 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
756 {
757         char *tmp;
758         tmp = strdup(abi);
759         if (!tmp) {
760                 ErrPrint("Heap: %s\n", strerror(errno));
761                 return -ENOMEM;
762         }
763
764         DbgFree(info->abi);
765         info->abi = tmp;
766         return 0;
767 }
768
769 HAPI const char * const package_lb_path(const struct pkg_info *info)
770 {
771         if (info->lb.type != LB_TYPE_SCRIPT)
772                 return NULL;
773
774         return info->lb.info.script.path;
775 }
776
777 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
778 {
779         char *tmp;
780
781         if (info->lb.type != LB_TYPE_SCRIPT)
782                 return -EINVAL;
783
784         tmp = strdup(path);
785         if (!tmp) {
786                 ErrPrint("Heap: %s\n", strerror(errno));
787                 return -ENOMEM;
788         }
789
790         DbgFree(info->lb.info.script.path);
791         info->lb.info.script.path = tmp;
792         return 0;
793 }
794
795 HAPI const char * const package_lb_group(const struct pkg_info *info)
796 {
797         if (info->lb.type != LB_TYPE_SCRIPT)
798                 return NULL;
799
800         return info->lb.info.script.group;
801 }
802
803 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
804 {
805         char *tmp;
806
807         if (info->lb.type != LB_TYPE_SCRIPT)
808                 return -EINVAL;
809
810         tmp = strdup(group);
811         if (!tmp) {
812                 ErrPrint("Heap: %s\n", strerror(errno));
813                 return -ENOMEM;
814         }
815
816         DbgFree(info->lb.info.script.group);
817         info->lb.info.script.group = tmp;
818         return 0;
819 }
820
821 HAPI const char * const package_pd_path(const struct pkg_info *info)
822 {
823         if (info->pd.type != PD_TYPE_SCRIPT)
824                 return NULL;
825
826         return info->pd.info.script.path;
827 }
828
829 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
830 {
831         char *tmp;
832
833         if (info->pd.type != PD_TYPE_SCRIPT)
834                 return -EINVAL;
835
836         tmp = strdup(path);
837         if (!tmp) {
838                 ErrPrint("Heap: %s\n", strerror(errno));
839                 return -ENOMEM;
840         }
841
842         DbgFree(info->pd.info.script.path);
843         info->pd.info.script.path = tmp;
844         return 0;
845 }
846
847 HAPI const char * const package_pd_group(const struct pkg_info *info)
848 {
849         if (info->pd.type != PD_TYPE_SCRIPT)
850                 return NULL;
851
852         return info->pd.info.script.group;
853 }
854
855 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
856 {
857         char *tmp;
858
859         if (info->pd.type != PD_TYPE_SCRIPT)
860                 return -EINVAL;
861
862         tmp = strdup(group);
863         if (!tmp) {
864                 ErrPrint("Heap: %s\n", strerror(errno));
865                 return -ENOMEM;
866         }
867
868         DbgFree(info->pd.info.script.group);
869         info->pd.info.script.group = tmp;
870         return 0;
871 }
872
873 HAPI const int const package_pinup(const struct pkg_info *info)
874 {
875         return info->lb.pinup;
876 }
877
878 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
879 {
880         info->lb.pinup = pinup;
881 }
882
883 HAPI const int const package_auto_launch(const struct pkg_info *info)
884 {
885         return info->lb.auto_launch;
886 }
887
888 HAPI void package_set_auto_launch(struct pkg_info *info, int auto_launch)
889 {
890         info->lb.auto_launch = auto_launch;
891 }
892
893 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
894 {
895         return info->lb.size_list;
896 }
897
898 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
899 {
900         info->lb.size_list = size_list;
901 }
902
903 HAPI const int const package_pd_width(const struct pkg_info *info)
904 {
905         return info->pd.width;
906 }
907
908 HAPI void package_set_pd_width(struct pkg_info *info, int width)
909 {
910         info->pd.width = width;
911 }
912
913 HAPI const int const package_pd_height(const struct pkg_info *info)
914 {
915         return info->pd.height;
916 }
917
918 HAPI void package_set_pd_height(struct pkg_info *info, int height)
919 {
920         info->pd.height = height;
921 }
922
923 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
924 {
925         info->refcnt++;
926         return info;
927 }
928
929 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
930 {
931         if (info->refcnt == 0) {
932                 ErrPrint("Invalid request\n");
933                 return NULL;
934         }
935
936         info->refcnt--;
937         if (info->refcnt == 0) {
938                 destroy_package(info);
939                 info = NULL;
940         }
941
942         return info;
943 }
944
945 HAPI const int const package_refcnt(const struct pkg_info *info)
946 {
947         return info->refcnt;
948 }
949
950 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
951 {
952         return info->lb.type;
953 }
954
955 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
956 {
957         info->lb.type = type;
958 }
959
960 HAPI const char * const package_libexec(struct pkg_info *info)
961 {
962         return info->libexec;
963 }
964
965 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
966 {
967         char *tmp;
968
969         tmp = strdup(libexec);
970         if (!tmp) {
971                 ErrPrint("Heap: %s\n", strerror(errno));
972                 return -ENOMEM;
973         }
974
975         DbgFree(info->libexec);
976         info->libexec = tmp;
977         return 0;
978 }
979
980 HAPI int package_network(struct pkg_info *info)
981 {
982         return info->network;
983 }
984
985 HAPI void package_set_network(struct pkg_info *info, int network)
986 {
987         info->network = network;
988 }
989
990 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
991 {
992         return info->pd.type;
993 }
994
995 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
996 {
997         info->pd.type = type;
998 }
999
1000 /*!
1001  * \note
1002  * Add the instance to the package info.
1003  * If a package has no slave, assign a new slave.
1004  */
1005 static inline int assign_new_slave(struct pkg_info *info)
1006 {
1007         char *s_name;
1008         char *s_pkgname;
1009         const char *tmp;
1010
1011         s_name = util_slavename();
1012         if (!s_name) {
1013                 ErrPrint("Failed to get a new slave name\n");
1014                 return -EFAULT;
1015         }
1016
1017         tmp = abi_find_slave(info->abi);
1018         if (!tmp) {
1019                 DbgFree(s_name);
1020                 ErrPrint("Failed to find a proper pkgname of a slave\n");
1021                 return -EINVAL;
1022         }
1023
1024         DbgPrint("Slave package: \"%s\" (abi: %s)\n", tmp, info->abi);
1025         s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->pkgname);
1026         if (!s_pkgname) {
1027                 s_pkgname = strdup(tmp);
1028                 if (!s_pkgname) {
1029                         ErrPrint("Heap: %s\n", strerror(errno));
1030                         DbgFree(s_name);
1031                         return -ENOMEM;
1032                 }
1033         } else if (!info->secured) {
1034                 DbgPrint("Slave package name is specified but the livebox is not secured\n");
1035                 DbgPrint("Forcely set secured flag for livebox %s\n", info->pkgname);
1036                 info->secured = 1;
1037         }
1038
1039         DbgPrint("New slave name is %s, it is assigned for livebox %s (using %s)\n", s_name, info->pkgname, s_pkgname);
1040         info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname);
1041
1042         DbgFree(s_name);
1043         DbgFree(s_pkgname);
1044
1045         if (!info->slave) {
1046                 /*!
1047                  * \note
1048                  * package_destroy will try to remove "info" from the pkg_list.
1049                  * but we didn't add this to it yet.
1050                  * If the list method couldn't find an "info" from the list,
1051                  * it just do nothing so I'll leave this.
1052                  */
1053                 return -EFAULT;
1054         }
1055         /*!
1056          * \note
1057          * Slave is not activated yet.
1058          */
1059         return 0;
1060 }
1061
1062 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1063 {
1064         if (!info->inst_list) {
1065                 info->slave = slave_find_available(info->abi, info->secured);
1066
1067                 if (!info->slave) {
1068                         int ret;
1069
1070                         ret = assign_new_slave(info);
1071                         if (ret < 0)
1072                                 return ret;
1073                 } else {
1074                         DbgPrint("Slave %s is assigned for %s\n", slave_name(info->slave), info->pkgname);
1075                 }
1076
1077                 slave_ref(info->slave);
1078                 slave_load_package(info->slave);
1079                 slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1080                 slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1081                 slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1082
1083                 if (info->secured) {
1084                         slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1085                         slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1086
1087                         /*!
1088                          * \note
1089                          * In case of the slave is terminated because of expired TTL timer,
1090                          * Master should freeze the all update time.
1091                          * But the callback should check the slave's state to prevent from duplicated freezing.
1092                          *
1093                          * This callback will freeze the timer only if a slave doesn't running.
1094                          */
1095                         xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1096                         xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1097                 }
1098         }
1099
1100         info->inst_list = eina_list_append(info->inst_list, inst);
1101         return 0;
1102 }
1103
1104 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1105 {
1106         info->inst_list = eina_list_remove(info->inst_list, inst);
1107
1108         if (info->inst_list)
1109                 return 0;
1110
1111         if (info->slave) {
1112                 slave_unload_package(info->slave);
1113
1114                 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1115                 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1116                 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1117
1118                 if (info->secured) {
1119                         slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1120                         slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1121
1122                         xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1123                         xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1124                 }
1125
1126                 slave_unref(info->slave);
1127                 info->slave = NULL;
1128         }
1129
1130         if (info->is_uninstalled)
1131                 package_destroy(info);
1132
1133         return 0;
1134 }
1135
1136 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1137 {
1138         return info->inst_list;
1139 }
1140
1141 static int client_created_cb(struct client_node *client, void *data)
1142 {
1143         struct pkg_info *info;
1144         Eina_List *l;
1145
1146         struct inst_info *inst;
1147         Eina_List *i_l;
1148
1149         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1150                 if (info->fault_info) {
1151                         fault_unicast_info(client, info->pkgname, info->fault_info->filename, info->fault_info->function);
1152                         continue;
1153                 }
1154
1155                 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1156                         switch (instance_state(inst)) {
1157                         case INST_INIT:
1158                                 /* Will be send a created event after the instance gets created event */
1159                                 break;
1160                         case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1161                         case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1162                         case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1163                                 if (instance_client(inst) == client) {
1164                                         instance_unicast_created_event(inst, client);
1165                                 } else if (instance_client(inst) == NULL) {
1166                                         /*!
1167                                          * \note
1168                                          * Instances are lives in the system cluster/sub-cluster
1169                                          */
1170                                         if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1171                                                 instance_unicast_created_event(inst, client);
1172                                                 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1173                                         }
1174                                 }
1175
1176                                 break;
1177                         default:
1178                                 DbgPrint("%s(%s) is not activated (%d)\n",
1179                                                 package_name(info), instance_id(inst), instance_state(inst));
1180                                 break;
1181                         }
1182                 }
1183         }
1184
1185         return 0;
1186 }
1187
1188 static int io_uninstall_cb(const char *pkgname, int prime, void *data)
1189 {
1190         struct pkg_info *info;
1191         Eina_List *l;
1192         Eina_List *n;
1193         struct inst_info *inst;
1194
1195         DbgPrint("Livebox package %s is uninstalled\n", pkgname);
1196         info = package_find(pkgname);
1197         if (!info) {
1198                 DbgPrint("%s is not yet loaded\n", pkgname);
1199                 return 0;
1200         }
1201
1202         info->is_uninstalled = 1;
1203
1204         /*!
1205          * \NOTE
1206          * Don't delete an item from the inst_list.
1207          * destroy callback will use this list again.
1208          * So, Don't touch it from here.
1209          */
1210         if (info->inst_list) {
1211                 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1212                         instance_destroy(inst);
1213                 }
1214         } else {
1215                 package_destroy(info);
1216         }
1217
1218         return 0;
1219 }
1220
1221 static inline void reload_package_info(struct pkg_info *info)
1222 {
1223         struct context_info *ctx_info;
1224         Eina_List *l;
1225         Eina_List *n;
1226         struct inst_info *inst;
1227
1228         DbgPrint("Already exists, try to update it\n");
1229         EINA_LIST_FREE(info->ctx_list, ctx_info) {
1230                 ctx_disable_event_handler(ctx_info);
1231         }
1232
1233         /*!
1234          * \note
1235          * Without "is_uninstalled", the package will be kept
1236          */
1237         EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1238                 instance_destroy(inst);
1239         }
1240
1241         group_del_livebox(info->pkgname);
1242         package_clear_fault(info);
1243
1244         /*!
1245          * \NOTE:
1246          * Nested DB I/O
1247          */
1248         io_load_package_db(info);
1249
1250         EINA_LIST_FOREACH(info->ctx_list, l, ctx_info) {
1251                 ctx_enable_event_handler(ctx_info);
1252         }
1253 }
1254
1255 static int io_install_cb(const char *pkgname, int prime, void *data)
1256 {
1257         struct pkg_info *info;
1258
1259         DbgPrint("Livebox package %s is installed\n", pkgname);
1260         info = package_find(pkgname);
1261         if (info) {
1262                 reload_package_info(info);
1263         } else {
1264                 info = package_create(pkgname);
1265                 DbgPrint("Package %s is%sbuilt\n", pkgname, info ? " " : " not ");
1266         }
1267
1268         return 0;
1269 }
1270
1271 static int install_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1272 {
1273         int ret;
1274
1275         if (status != PKGMGR_STATUS_END)
1276                 return 0;
1277
1278         ret = io_update_livebox_package(pkgname, io_install_cb, NULL);
1279         DbgPrint("Processed %d packages\n", ret);
1280         return 0;
1281 }
1282
1283 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1284 {
1285         int ret;
1286
1287         if (status == PKGMGR_STATUS_START) {
1288                 ret = io_update_livebox_package(pkgname, io_uninstall_cb, NULL);
1289                 DbgPrint("Processed %d packages\n", ret);
1290                 if (ret == 0) {
1291                         /*! for keeping the old style */
1292                         (void)io_uninstall_cb(pkgname, -1, NULL);
1293                 }
1294         }
1295
1296         return 0;
1297 }
1298
1299 static int io_update_cb(const char *pkgname, int prime, void *data)
1300 {
1301         struct pkg_info *info;
1302
1303         DbgPrint("Livebox package %s is updated\n", pkgname);
1304         info = package_find(pkgname);
1305         if (!info)
1306                 return 0;
1307
1308         reload_package_info(info);
1309         return 0;
1310 }
1311
1312 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1313 {
1314         int ret;
1315         if (status != PKGMGR_STATUS_END)
1316                 return 0;
1317
1318         ret = io_update_livebox_package(pkgname, io_update_cb, NULL);
1319         DbgPrint("Processed %d packages\n", ret);
1320         return 0;
1321 }
1322
1323 static int crawling_liveboxes(const char *pkgname, int prime, void *data)
1324 {
1325         if (package_find(pkgname)) {
1326                 ErrPrint("Information of %s is already built\n", pkgname);
1327         } else {
1328                 struct pkg_info *info;
1329                 info = package_create(pkgname);
1330                 if (info)
1331                         DbgPrint("[%s] information is built prime(%d)\n", pkgname, prime);
1332         }
1333
1334         return 0;
1335 }
1336
1337 HAPI int package_init(void)
1338 {
1339         client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1340         pkgmgr_init();
1341
1342         pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1343         pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1344         pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1345
1346         io_crawling_liveboxes(crawling_liveboxes, NULL);
1347         return 0;
1348 }
1349
1350 HAPI int package_fini(void)
1351 {
1352         pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1353         pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1354         pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1355         pkgmgr_fini();
1356         client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1357         return 0;
1358 }
1359
1360 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1361 {
1362         Eina_List *l;
1363         struct pkg_info *info;
1364
1365         if (!slave_is_secured(slave))
1366                 return NULL;
1367
1368         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1369                 if (info->slave == slave)
1370                         return info->pkgname;
1371         }
1372
1373         return NULL;
1374 }
1375
1376 HAPI const char * const package_name(const struct pkg_info *info)
1377 {
1378         return info->pkgname;
1379 }
1380
1381 /*!
1382  * del_or_creat : 1 == create, 0 == delete
1383  */
1384 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1385 {
1386         struct pkg_info *info;
1387         Eina_List *l;
1388
1389         struct inst_info *inst;
1390         Eina_List *i_l;
1391
1392         EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1393                 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1394                         if (instance_client(inst))
1395                                 continue;
1396
1397                         if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst)))
1398                                 continue;
1399
1400                         switch (instance_state(inst)) {
1401                         case INST_INIT:
1402                         case INST_REQUEST_TO_ACTIVATE:
1403                                 /* Will be send a created event after the instance gets created event */
1404                                 switch (alter) {
1405                                 case ALTER_CREATE:
1406                                         if (!instance_has_client(inst, client)) {
1407                                                 instance_add_client(inst, client);
1408                                         }
1409                                         break;
1410                                 case ALTER_DESTROY:
1411                                         if (instance_has_client(inst, client)) {
1412                                                 instance_del_client(inst, client);
1413                                         }
1414                                         break;
1415                                 default:
1416                                         break;
1417                                 }
1418                                 break;
1419                         case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1420                         case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1421                         case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1422                                 /*!
1423                                  * \note
1424                                  * Instances are lives in the system cluster/sub-cluster
1425                                  */
1426                                 switch (alter) {
1427                                 case ALTER_CREATE:
1428                                         if (!instance_has_client(inst, client)) {
1429                                                 instance_unicast_created_event(inst, client);
1430                                                 instance_add_client(inst, client);
1431                                                 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1432                                         }
1433                                         break;
1434                                 case ALTER_DESTROY:
1435                                         if (instance_has_client(inst, client)) {
1436                                                 instance_unicast_deleted_event(inst, client);
1437                                                 instance_del_client(inst, client);
1438                                         }
1439                                         break;
1440                                 default:
1441                                         break;
1442                                 }
1443
1444                                 break;
1445                         default:
1446                                 DbgPrint("%s(%s) is not activated (%d)\n",
1447                                                 package_name(info), instance_id(inst), instance_state(inst));
1448                                 break;
1449                         }
1450                 }
1451         }
1452
1453         return 0;
1454 }
1455
1456 HAPI const Eina_List *package_list(void)
1457 {
1458         return s_info.pkg_list;
1459 }
1460
1461 HAPI int const package_fault_count(struct pkg_info *info)
1462 {
1463         return info ? info->fault_count : 0;
1464 }
1465
1466 /* End of a file */