sycn with master
[platform/framework/web/data-provider-slave.git] / src / so_handler.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 <dlfcn.h> /* dlopen */
20 #include <stdlib.h> /* malloc, free */
21 #include <string.h> /* strcmp */
22
23 #include <dlog.h>
24 #include <Eina.h>
25 #include <provider.h>
26 #include <heap-monitor.h>
27 #include <livebox-service.h>
28
29 #include "main.h"
30 #include "critical_log.h"
31 #include "debug.h"
32 #include "so_handler.h"
33 #include "fault.h"
34 #include "conf.h"
35 #include "util.h"
36
37 int errno;
38
39 static struct info {
40         Eina_List *livebox_list;
41 } s_info = {
42         .livebox_list = NULL,
43 };
44
45 static inline struct so_item *find_livebox(const char *pkgname)
46 {
47         Eina_List *l;
48         struct so_item *item;
49
50         EINA_LIST_FOREACH(s_info.livebox_list, l, item) {
51                 if (!strcmp(item->pkgname, pkgname))
52                         return item;
53         }
54
55         return NULL;
56 }
57
58 static inline char *so_adaptor_alloc(const char *abi)
59 {
60         /* TODO: Implement me */
61         DbgPrint("ABI[%s] loads %s\n", abi, "/usr/lib/liblivebox-cpp.so");
62         return strdup("/usr/lib/liblivebox-cpp.so");
63 }
64
65 static inline char *old_style_path(const char *pkgname)
66 {
67         char *path;
68         int path_len;
69         int ret;
70
71         path_len = (strlen(pkgname) * 2) + strlen(MODULE_PATH);
72         path = malloc(path_len);
73         if (!path) {
74                 ErrPrint("Memory: %s\n", strerror(errno));
75                 return NULL;
76         }
77
78         ret = snprintf(path, path_len, MODULE_PATH, pkgname, pkgname);
79         if (ret < 0) {
80                 ErrPrint("Fault: %s\n", strerror(errno));
81                 free(path);
82                 return NULL;
83         }
84
85         DbgPrint("Fallback to old style libexec path (%s)\n", path);
86         return path;
87 }
88
89 static inline char *so_path_alloc(const char *pkgname)
90 {
91         char *lb_pkgname;
92         char *path;
93
94         lb_pkgname = livebox_service_pkgname(pkgname);
95         if (!lb_pkgname) {
96                 path = old_style_path(pkgname);
97         } else {
98                 path = livebox_service_libexec(lb_pkgname);
99                 free(lb_pkgname);
100         }
101
102         DbgPrint("so path: %s\n", path);
103         return path;
104 }
105
106 static void delete_livebox(struct so_item *item)
107 {
108         if (item->adaptor.finalize) {
109                 int ret;
110                 fault_mark_call(item->pkgname, "finalize", __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
111                 ret = item->adaptor.finalize(item->pkgname);
112                 fault_unmark_call(item->pkgname, "finalize", __func__, USE_ALARM);
113
114                 ErrPrint("Package %s, finalize returns %d\n", item->pkgname, ret);
115         } else if (item->livebox.finalize) {
116                 int ret;
117                 fault_mark_call(item->pkgname, "finalize", __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
118                 ret = item->livebox.finalize();
119                 fault_unmark_call(item->pkgname, "finalize", __func__, USE_ALARM);
120
121                 ErrPrint("Package %s, finalize returns %d\n", item->pkgname, ret);
122         }
123
124         heap_monitor_del_target(item->so_fname);
125         dlclose(item->handle);
126         free(item->so_fname);
127         free(item->pkgname);
128         free(item);
129 }
130
131 static struct so_item *new_adaptor(const char *pkgname, const char *abi)
132 {
133         struct so_item *item;
134
135         item = calloc(1, sizeof(*item));
136         if (!item) {
137                 ErrPrint("Memory: %s\n", strerror(errno));
138                 return NULL;
139         }
140
141         item->pkgname = strdup(pkgname);
142         if (!item->pkgname) {
143                 ErrPrint("Memory: %s\n", strerror(errno));
144                 free(item);
145                 return NULL;
146         }
147
148         /*! \TODO:
149          * item->timeout
150          */
151
152         /*! \TODO
153          * item->has_livbox_script
154          */
155
156         item->inst_list = NULL;
157
158         item->so_fname = so_adaptor_alloc(abi);
159         if (!item->so_fname) {
160                 free(item->pkgname);
161                 free(item);
162                 return NULL;
163         }
164
165         fault_mark_call(pkgname, __func__, __func__, USE_ALARM, DEFAULT_LOAD_TIMER);
166         item->handle = dlopen(item->so_fname, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
167         if (!item->handle) {
168                 fault_unmark_call(pkgname, __func__, __func__, USE_ALARM);
169                 ErrPrint("dlopen: %s - %s\n", dlerror(), item->so_fname);
170                 free(item->so_fname);
171                 free(item->pkgname);
172                 free(item);
173                 return NULL;
174         }
175         fault_unmark_call(pkgname, __func__, __func__, USE_ALARM);
176
177         item->adaptor.create = (adaptor_create_t)dlsym(item->handle, "livebox_create");
178         if (!item->adaptor.create) {
179                 ErrPrint("symbol: livebox_create - %s\n", dlerror());
180                 delete_livebox(item);
181                 return NULL;
182         }
183
184         item->adaptor.destroy = (adaptor_destroy_t)dlsym(item->handle, "livebox_destroy");
185         if (!item->adaptor.destroy) {
186                 ErrPrint("symbol: livebox_destroy - %s\n", dlerror());
187                 delete_livebox(item);
188                 return NULL;
189         }
190
191         item->adaptor.pinup = (adaptor_pinup_t)dlsym(item->handle, "livebox_pinup");
192         if (!item->adaptor.pinup)
193                 ErrPrint("symbol: livebox_pinup - %s\n", dlerror());
194
195         item->adaptor.is_updated = (adaptor_is_updated_t)dlsym(item->handle, "livebox_need_to_update");
196         if (!item->adaptor.is_updated)
197                 ErrPrint("symbol: livebox_need_to_update - %s\n", dlerror());
198
199         item->adaptor.update_content = (adaptor_update_content_t)dlsym(item->handle, "livebox_update_content");
200         if (!item->adaptor.update_content)
201                 ErrPrint("symbol: livebox_update_content - %s\n", dlerror());
202
203         item->adaptor.clicked = (adaptor_clicked_t)dlsym(item->handle, "livebox_clicked");
204         if (!item->adaptor.clicked)
205                 ErrPrint("symbol: livebox_clicked - %s\n", dlerror());
206
207         item->adaptor.script_event = (adaptor_script_t)dlsym(item->handle, "livebox_content_event");
208         if (!item->adaptor.script_event)
209                 ErrPrint("symbol: livebox_content_event - %s\n", dlerror());
210
211         item->adaptor.resize = (adaptor_resize_t)dlsym(item->handle, "livebox_resize");
212         if (!item->adaptor.resize)
213                 ErrPrint("symbol: livebox_resize - %s\n", dlerror());
214
215         item->adaptor.create_needed = (adaptor_create_needed_t)dlsym(item->handle, "livebox_need_to_create");
216         if (!item->adaptor.create_needed)
217                 ErrPrint("symbol: livebox_need_to_create - %s\n", dlerror());
218
219         item->adaptor.change_group = (adaptor_change_group_t)dlsym(item->handle, "livebox_change_group");
220         if (!item->adaptor.change_group)
221                 ErrPrint("symbol: livebox_change_group - %s\n", dlerror());
222
223         item->adaptor.get_output_info = (adaptor_get_output_info_t)dlsym(item->handle, "livebox_get_info");
224         if (!item->adaptor.get_output_info)
225                 ErrPrint("symbol: livebox_get_info - %s\n", dlerror());
226
227         item->adaptor.initialize = (adaptor_initialize_t)dlsym(item->handle, "livebox_initialize");
228         if (!item->adaptor.initialize)
229                 ErrPrint("symbol: livebox_initialize - %s\n", dlerror());
230
231         item->adaptor.finalize = (adaptor_finalize_t)dlsym(item->handle, "livebox_finalize");
232         if (!item->adaptor.finalize)
233                 ErrPrint("symbol: livebox_finalize - %s\n", dlerror());
234
235         item->adaptor.need_to_destroy = (adaptor_need_to_destroy_t)dlsym(item->handle, "livebox_need_to_destroy");
236         if (!item->adaptor.need_to_destroy)
237                 ErrPrint("symbol: livebox_need_to_destroy - %s\n", dlerror());
238
239         item->adaptor.sys_event = (adaptor_system_event_t)dlsym(item->handle, "livebox_system_event");
240         if (!item->adaptor.sys_event)
241                 ErrPrint("symbol: lievbox_system_event - %s\n", dlerror());
242
243         item->adaptor.is_pinned_up = (adaptor_is_pinned_up_t)dlsym(item->handle, "livebox_is_pinned_up");
244         if (!item->adaptor.is_pinned_up)
245                 ErrPrint("symbol: livebox_is_pinned_up - %s\n", dlerror());
246
247         if (item->adaptor.initialize) {
248                 int ret;
249                 fault_mark_call(pkgname, "initialize", __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
250                 ret = item->adaptor.initialize(pkgname);
251                 fault_unmark_call(pkgname, "initialize", __func__, USE_ALARM);
252                 if (ret < 0) {
253                         ErrPrint("Failed to initialize package %s\n", pkgname);
254                         heap_monitor_del_target(item->so_fname);
255                         delete_livebox(item);
256                         return NULL;
257                 }
258         }
259
260         s_info.livebox_list = eina_list_append(s_info.livebox_list, item);
261         return item;
262 }
263
264 static struct so_item *new_livebox(const char *pkgname)
265 {
266         struct so_item *item;
267
268         item = calloc(1, sizeof(*item));
269         if (!item) {
270                 ErrPrint("Memory: %s\n", strerror(errno));
271                 return NULL;
272         }
273
274         item->pkgname = strdup(pkgname);
275         if (!item->pkgname) {
276                 ErrPrint("Memory: %s\n", strerror(errno));
277                 free(item);
278                 return NULL;
279         }
280
281         /*! \TODO:
282          * item->timeout
283          */
284
285         /*! \TODO
286          * item->has_livbox_script
287          */
288
289         item->inst_list = NULL;
290
291         item->so_fname = so_path_alloc(pkgname);
292         if (!item->so_fname) {
293                 free(item->pkgname);
294                 free(item);
295                 return NULL;
296         }
297
298         fault_mark_call(pkgname, __func__, __func__, USE_ALARM, DEFAULT_LOAD_TIMER);
299         item->handle = dlopen(item->so_fname, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
300         if (!item->handle) {
301                 fault_unmark_call(pkgname, __func__, __func__, USE_ALARM);
302                 ErrPrint("dlopen: %s - %s\n", dlerror(), item->so_fname);
303                 free(item->so_fname);
304                 free(item->pkgname);
305                 free(item);
306                 return NULL;
307         }
308         fault_unmark_call(pkgname, __func__, __func__, USE_ALARM);
309
310         item->livebox.create = (create_t)dlsym(item->handle, "livebox_create");
311         if (!item->livebox.create) {
312                 ErrPrint("symbol: livebox_create - %s\n", dlerror());
313                 delete_livebox(item);
314                 return NULL;
315         }
316
317         item->livebox.destroy = (destroy_t)dlsym(item->handle, "livebox_destroy");
318         if (!item->livebox.destroy) {
319                 ErrPrint("symbol: livebox_destroy - %s\n", dlerror());
320                 delete_livebox(item);
321                 return NULL;
322         }
323
324         item->livebox.pinup = (pinup_t)dlsym(item->handle, "livebox_pinup");
325         if (!item->livebox.pinup)
326                 ErrPrint("symbol: livebox_pinup - %s\n", dlerror());
327
328         item->livebox.is_updated = (is_updated_t)dlsym(item->handle, "livebox_need_to_update");
329         if (!item->livebox.is_updated)
330                 ErrPrint("symbol: livebox_need_to_update - %s\n", dlerror());
331
332         item->livebox.update_content = (update_content_t)dlsym(item->handle, "livebox_update_content");
333         if (!item->livebox.update_content)
334                 ErrPrint("symbol: livebox_update_content - %s\n", dlerror());
335
336         item->livebox.clicked = (clicked_t)dlsym(item->handle, "livebox_clicked");
337         if (!item->livebox.clicked)
338                 ErrPrint("symbol: livebox_clicked - %s\n", dlerror());
339
340         item->livebox.script_event = (script_t)dlsym(item->handle, "livebox_content_event");
341         if (!item->livebox.script_event)
342                 ErrPrint("symbol: livebox_content_event - %s\n", dlerror());
343
344         item->livebox.resize = (resize_t)dlsym(item->handle, "livebox_resize");
345         if (!item->livebox.resize)
346                 ErrPrint("symbol: livebox_resize - %s\n", dlerror());
347
348         item->livebox.create_needed = (create_needed_t)dlsym(item->handle, "livebox_need_to_create");
349         if (!item->livebox.create_needed)
350                 ErrPrint("symbol: livebox_need_to_create - %s\n", dlerror());
351
352         item->livebox.change_group = (change_group_t)dlsym(item->handle, "livebox_change_group");
353         if (!item->livebox.change_group)
354                 ErrPrint("symbol: livebox_change_group - %s\n", dlerror());
355
356         item->livebox.get_output_info = (get_output_info_t)dlsym(item->handle, "livebox_get_info");
357         if (!item->livebox.get_output_info)
358                 ErrPrint("symbol: livebox_get_info - %s\n", dlerror());
359
360         item->livebox.initialize = (initialize_t)dlsym(item->handle, "livebox_initialize");
361         if (!item->livebox.initialize)
362                 ErrPrint("symbol: livebox_initialize - %s\n", dlerror());
363
364         item->livebox.finalize = (finalize_t)dlsym(item->handle, "livebox_finalize");
365         if (!item->livebox.finalize)
366                 ErrPrint("symbol: livebox_finalize - %s\n", dlerror());
367
368         item->livebox.need_to_destroy = (need_to_destroy_t)dlsym(item->handle, "livebox_need_to_destroy");
369         if (!item->livebox.need_to_destroy)
370                 ErrPrint("symbol: livebox_need_to_destroy - %s\n", dlerror());
371
372         item->livebox.sys_event = (system_event_t)dlsym(item->handle, "livebox_system_event");
373         if (!item->livebox.sys_event)
374                 ErrPrint("symbol: livebox_system_event - %s\n", dlerror());
375
376         item->livebox.is_pinned_up = (is_pinned_up_t)dlsym(item->handle, "livebox_is_pinned_up");
377         if (!item->livebox.is_pinned_up)
378                 ErrPrint("symbol: livebox_is_pinned_up - %s\n", dlerror());
379
380         heap_monitor_add_target(item->so_fname);
381
382         if (item->livebox.initialize) {
383                 int ret;
384                 fault_mark_call(pkgname, "initialize", __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
385                 ret = item->livebox.initialize(pkgname);
386                 fault_unmark_call(pkgname, "initialize", __func__, USE_ALARM);
387                 if (ret < 0) {
388                         ErrPrint("Failed to initialize package %s\n", pkgname);
389                         heap_monitor_del_target(item->so_fname);
390                         delete_livebox(item);
391                         return NULL;
392                 }
393         }
394
395         s_info.livebox_list = eina_list_append(s_info.livebox_list, item);
396         return item;
397 }
398
399 static inline struct instance *new_instance(const char *id, const char *content, const char *cluster, const char *category)
400 {
401         struct instance *inst;
402
403         inst = malloc(sizeof(*inst));
404         if (!inst) {
405                 ErrPrint("Heap: %s\n", strerror(errno));
406                 return NULL;
407         }
408
409         inst->id = strdup(id);
410         if (!inst->id) {
411                 ErrPrint("Heap: %s\n", strerror(errno));
412                 free(inst);
413                 return NULL;
414         }
415
416         if (content) {
417                 inst->content = strdup(content);
418                 if (!inst->content) {
419                         ErrPrint("memory: %s\n", strerror(errno));
420                         free(inst->id);
421                         free(inst);
422                         return NULL;
423                 }
424         } else {
425                 inst->content = NULL;
426         }
427
428         if (cluster) {
429                 inst->cluster = strdup(cluster);
430                 if (!inst->cluster) {
431                         ErrPrint("memory: %s\n", strerror(errno));
432                         free(inst->id);
433                         free(inst->content);
434                         free(inst);
435                         return NULL;
436                 }
437         } else {
438                 inst->cluster = NULL;
439         }
440
441         if (category) {
442                 inst->category = strdup(category);
443                 if (!inst->category) {
444                         ErrPrint("memory: %s\n", strerror(errno));
445                         free(inst->cluster);
446                         free(inst->id);
447                         free(inst->content);
448                         free(inst);
449                         return NULL;
450                 }
451         } else {
452                 inst->category = NULL;
453         }
454
455         inst->w = 0;
456         inst->h = 0;
457         inst->priority = 0;
458         inst->title = NULL;
459
460         return inst;
461 }
462
463 static inline int delete_instance(struct instance *inst)
464 {
465         free(inst->cluster);
466         free(inst->category);
467         free(inst->id);
468         free(inst->content);
469         free(inst->title);
470         free(inst);
471         return 0;
472 }
473
474 static inline struct instance *find_instance(struct so_item *item, const char *id)
475 {
476         struct instance *inst;
477         Eina_List *l;
478
479         EINA_LIST_FOREACH(item->inst_list, l, inst) {
480                 if (!strcmp(inst->id, id))
481                         return inst;
482         }
483
484         return NULL;
485 }
486
487 HAPI struct instance *so_find_instance(const char *pkgname, const char *id)
488 {
489         struct so_item *item;
490
491         item = find_livebox(pkgname);
492         if (!item)
493                 return NULL;
494
495         return find_instance(item, id);
496 }
497
498 HAPI int so_create(const char *pkgname, const char *id, const char *content_info, int timeout, int has_livebox_script, const char *cluster, const char *category, const char *abi, struct instance **out)
499 {
500         struct so_item *item;
501         struct instance *inst;
502         int ret;
503
504         item = find_livebox(pkgname);
505         if (item) {
506                 inst = find_instance(item, id);
507                 if (inst) {
508                         ErrPrint("Instance: %s - %s is already exists\n", pkgname, id);
509                         return -EEXIST;
510                 }
511         } else {
512                 if (!strcasecmp(abi, "c"))
513                         item = new_livebox(pkgname);
514                 else
515                         item = new_adaptor(pkgname, abi);
516                 if (!item)
517                         return -EFAULT;
518         }
519
520         inst = new_instance(id, content_info, cluster, category);
521         if (!inst) {
522                 if (!item->inst_list)
523                         delete_livebox(item);
524
525                 return -EFAULT;
526         }
527
528         item->inst_list = eina_list_append(item->inst_list, inst);
529         item->has_livebox_script = has_livebox_script;
530         item->timeout = timeout;
531
532         fault_mark_call(pkgname, id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
533
534         if (item->adaptor.create)
535                 ret = item->adaptor.create(pkgname, util_uri_to_path(id), content_info, cluster, category);
536         else if (item->livebox.create)
537                 ret = item->livebox.create(util_uri_to_path(id), content_info, cluster, category);
538         else /*! \NOTE: This is not possible, but for the exceptional handling */
539                 ret = -ENOSYS;
540
541         fault_unmark_call(pkgname, id, __func__, USE_ALARM);
542
543         if (ret < 0) {
544                 item->inst_list = eina_list_remove(item->inst_list, inst);
545                 delete_instance(inst);
546
547                 if (!item->inst_list) {
548                         /* There is no instances, unload this livebox */
549                         s_info.livebox_list = eina_list_remove(s_info.livebox_list, item);
550                         delete_livebox(item);
551                 }
552                 return ret;
553         }
554
555         inst->item = item;
556         *out = inst;
557         return ret;
558 }
559
560 HAPI int so_destroy(struct instance *inst)
561 {
562         struct so_item *item;
563         int ret;
564
565         item = inst->item;
566         if (!item)
567                 return -EINVAL;
568
569         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
570
571         if (item->adaptor.destroy)
572                 ret = item->adaptor.destroy(item->pkgname, util_uri_to_path(inst->id));
573         else if (item->livebox.destroy)
574                 ret = item->livebox.destroy(util_uri_to_path(inst->id));
575         else
576                 ret = -ENOSYS;
577
578         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
579
580         item->inst_list = eina_list_remove(item->inst_list, inst);
581         delete_instance(inst);
582
583         if (!item->inst_list) {
584                 s_info.livebox_list = eina_list_remove(s_info.livebox_list, item);
585                 delete_livebox(item);
586         }
587
588         return ret;
589 }
590
591 HAPI char *so_pinup(struct instance *inst, int pinup)
592 {
593         struct so_item *item;
594         char *ret;
595
596         item = inst->item;
597         if (!item)
598                 return NULL;
599
600         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
601         if (item->adaptor.pinup)
602                 ret = item->adaptor.pinup(item->pkgname, util_uri_to_path(inst->id), pinup);
603         else if (item->livebox.pinup)
604                 ret = item->livebox.pinup(util_uri_to_path(inst->id), pinup);
605         else
606                 ret = NULL;
607         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
608         return ret;
609 }
610
611 HAPI int so_is_pinned_up(struct instance *inst)
612 {
613         struct so_item *item;
614         int ret;
615
616         item = inst->item;
617         if (!item)
618                 return -EINVAL;
619
620         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
621         if (item->adaptor.is_pinned_up)
622                 ret = item->adaptor.is_pinned_up(item->pkgname, util_uri_to_path(inst->id));
623         else if (item->livebox.is_pinned_up)
624                 ret = item->livebox.is_pinned_up(util_uri_to_path(inst->id));
625         else
626                 ret = -ENOSYS;
627         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
628         return ret;
629 }
630
631 HAPI int so_is_updated(struct instance *inst)
632 {
633         struct so_item *item;
634         int ret;
635
636         item = inst->item;
637         if (!item)
638                 return -EINVAL;
639
640         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
641
642         if (item->adaptor.is_updated)
643                 ret = item->adaptor.is_updated(item->pkgname, util_uri_to_path(inst->id));
644         else if (item->livebox.is_updated)
645                 ret = item->livebox.is_updated(util_uri_to_path(inst->id));
646         else
647                 ret = -ENOSYS;
648
649         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
650
651         return ret;
652 }
653
654 HAPI int so_need_to_destroy(struct instance *inst)
655 {
656         struct so_item *item;
657         int ret;
658
659         item = inst->item;
660         if (!item)
661                 return -EINVAL;
662
663         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
664
665         if (item->adaptor.need_to_destroy)
666                 ret = item->adaptor.need_to_destroy(item->pkgname, util_uri_to_path(inst->id));
667         else if (item->livebox.need_to_destroy)
668                 ret = item->livebox.need_to_destroy(util_uri_to_path(inst->id));
669         else
670                 ret = -ENOSYS;
671
672         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
673
674         return ret;
675 }
676
677 HAPI int so_update(struct instance *inst)
678 {
679         struct so_item *item;
680         int ret;
681
682         item = inst->item;
683         if (!item)
684                 return -EINVAL;
685
686         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
687
688         if (item->adaptor.update_content)
689                 ret = item->adaptor.update_content(item->pkgname, util_uri_to_path(inst->id));
690         else if (item->livebox.update_content)
691                 ret = item->livebox.update_content(util_uri_to_path(inst->id));
692         else
693                 ret = -ENOSYS;
694
695         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
696         return ret;
697 }
698
699 HAPI int so_clicked(struct instance *inst, const char *event, double timestamp, double x, double y)
700 {
701         struct so_item *item;
702         int ret;
703
704         item = inst->item;
705         if (!item)
706                 return -EINVAL;
707
708         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
709
710         if (item->adaptor.clicked)
711                 ret = item->adaptor.clicked(item->pkgname, util_uri_to_path(inst->id), event, timestamp, x, y);
712         else if (item->livebox.clicked)
713                 ret = item->livebox.clicked(util_uri_to_path(inst->id), event, timestamp, x, y);
714         else
715                 ret = -ENOSYS;
716
717         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
718
719         return ret;
720 }
721
722 HAPI int so_script_event(struct instance *inst, const char *emission, const char *source, struct event_info *event_info)
723 {
724         struct so_item *item;
725         int ret;
726
727         item = inst->item;
728         if (!item)
729                 return -EINVAL;
730
731         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
732
733         if (item->adaptor.script_event)
734                 ret = item->adaptor.script_event(item->pkgname, util_uri_to_path(inst->id), emission, source, event_info);
735         else if (item->livebox.script_event)
736                 ret = item->livebox.script_event(util_uri_to_path(inst->id), emission, source, event_info);
737         else
738                 ret = -ENOSYS;
739
740         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
741
742         return ret;
743 }
744
745 HAPI int so_resize(struct instance *inst, int w, int h)
746 {
747         struct so_item *item;
748         int ret;
749         int type;
750
751         item = inst->item;
752         if (!item)
753                 return -EINVAL;
754
755         type = livebox_service_size_type(w, h);
756         if (type == LB_SIZE_TYPE_UNKNOWN)
757                 return -EINVAL;
758
759         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
760
761         if (item->adaptor.resize)
762                 ret = item->adaptor.resize(item->pkgname, util_uri_to_path(inst->id), type);
763         else if (item->livebox.resize)
764                 ret = item->livebox.resize(util_uri_to_path(inst->id), type);
765         else
766                 ret = -ENOSYS;
767
768         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
769
770         return ret;
771 }
772
773 HAPI int so_create_needed(const char *pkgname, const char *cluster, const char *category, const char *abi)
774 {
775         struct so_item *item;
776         int ret;
777
778         item = find_livebox(pkgname);
779         if (!item) {
780                 if (!strcasecmp(abi, "c"))
781                         item = new_livebox(pkgname);
782                 else
783                         item = new_adaptor(pkgname, abi);
784                 if (!item)
785                         return -EFAULT;
786         }
787
788         fault_mark_call(item->pkgname, __func__, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
789
790         if (item->adaptor.create_needed)
791                 ret = item->adaptor.create_needed(pkgname, cluster, category);
792         else if (item->livebox.create_needed)
793                 ret = item->livebox.create_needed(cluster, category);
794         else
795                 ret = -ENOSYS;
796
797         fault_unmark_call(item->pkgname, __func__, __func__, USE_ALARM);
798
799         DbgPrint("[%s] returns %d\n", pkgname, ret);
800         return ret;
801 }
802
803 HAPI int so_change_group(struct instance *inst, const char *cluster, const char *category)
804 {
805         struct so_item *item;
806         int ret;
807         char *tmp_cluster;
808         char *tmp_category;
809
810         item = inst->item;
811         if (!item)
812                 return -EINVAL;
813
814         tmp_cluster = strdup(cluster);
815         if (!tmp_cluster)
816                 return -ENOMEM;
817
818         tmp_category = strdup(category);
819         if (!tmp_category) {
820                 free(tmp_cluster);
821                 return -ENOMEM;
822         }
823
824         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
825
826         if (item->adaptor.change_group)
827                 ret = item->adaptor.change_group(item->pkgname, util_uri_to_path(inst->id), cluster, category);
828         else if (item->livebox.change_group)
829                 ret = item->livebox.change_group(util_uri_to_path(inst->id), cluster, category);
830         else
831                 ret = -ENOSYS;
832
833         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
834         if (ret >= 0) {
835                 free(inst->cluster);
836                 free(inst->category);
837
838                 inst->cluster = tmp_cluster;
839                 inst->category = tmp_category;
840         } else {
841                 free(tmp_cluster);
842                 free(tmp_category);
843         }
844
845         return ret;
846 }
847
848 HAPI int so_get_output_info(struct instance *inst, int *w, int *h, double *priority, char **content, char **title)
849 {
850         struct so_item *item;
851         int ret;
852
853         item = inst->item;
854         if (!item)
855                 return -EINVAL;
856
857         *content = NULL;
858         *title = NULL;
859
860         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
861
862         if (item->adaptor.get_output_info)
863                 ret = item->adaptor.get_output_info(item->pkgname, util_uri_to_path(inst->id), w, h, priority, content, title);
864         else if (item->livebox.get_output_info)
865                 ret = item->livebox.get_output_info(util_uri_to_path(inst->id), w, h, priority, content, title);
866         else
867                 ret = -ENOSYS;
868
869         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
870         if (ret >= 0) {
871                 inst->w = *w;
872                 inst->h = *h;
873                 inst->priority = *priority;
874
875                 /*!
876                  * \todo
877                  * Add "*content" "*title" address validation code.
878                  * using mcheck?
879                  */
880
881                 if (*content) {
882                         free(inst->content);
883                         inst->content = *content;
884                 }
885
886                 if (*title) {
887                         free(inst->title);
888                         inst->title = *title;
889                 }
890         }
891
892         if (main_heap_monitor_is_enabled())
893                 DbgPrint("%s allocates %d bytes\n", item->pkgname, heap_monitor_target_usage(item->so_fname));
894
895         return ret;
896 }
897
898 HAPI int so_sys_event(struct instance *inst, int event)
899 {
900         struct so_item *item;
901         int ret;
902
903         item = inst->item;
904         if (!item)
905                 return -EINVAL;
906
907         fault_mark_call(item->pkgname, inst->id, __func__, USE_ALARM, DEFAULT_LIFE_TIMER);
908         if (item->adaptor.sys_event)
909                 ret = item->adaptor.sys_event(item->pkgname, util_uri_to_path(inst->id), event);
910         else if (item->livebox.sys_event)
911                 ret = item->livebox.sys_event(util_uri_to_path(inst->id), event);
912         else
913                 ret = -ENOSYS;
914
915         fault_unmark_call(item->pkgname, inst->id, __func__, USE_ALARM);
916         return ret;
917 }
918
919 /* End of a file */