00861d1133b325dfae4d5ab7cf8cf131d1a3771b
[platform/core/uifw/mmi-manager.git] / src / mmi-fusion.c
1 /*
2 * Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "mmi-fusion.h"
25 #include "mmi-fusion-iface.h"
26 #include "mmi-manager-dbg.h"
27
28 #include <Ecore.h>
29 #include <dirent.h>
30 #include <stdio.h>
31 #include <dlfcn.h>
32 #include <string.h>
33
34 #define FUSION_PATH "/lib/fusion/"
35
36 Eina_List *_fusion_list = NULL;
37 int _loaded_fusion_cnt = 0;
38
39 int
40 _fusion_load_module(const char *fusion_name)
41 {
42         mmi_fusion_handle *fusion = (mmi_fusion_handle *)calloc(1, sizeof(mmi_fusion_handle));
43
44         void *fusion_info = NULL;
45         mmi_fusion_module *mmi_fusion_module_info = NULL;
46
47         fusion_info = dlopen(fusion_name, RTLD_LAZY);
48
49         if(!fusion_info)
50         {
51                 LOGE("Failed to dlopen(error :%s, path :%s)!\n", dlerror(), fusion_name);
52                 return 0;
53         }
54
55         mmi_fusion_module_info = dlsym(fusion_info, "mmi_fusion_module_info");
56
57         if(!mmi_fusion_module_info)
58         {
59                 LOGE("Module(%s) dosen't have mmi_fusion_module_info \n", fusion_name);
60                 goto err;
61         }
62
63         if(!mmi_fusion_module_info->fusion_init || !mmi_fusion_module_info->fusion_deinit)
64         {
65                 LOGE("Module(%s) doesn't have init/deinit function\n", fusion_name);
66                 goto err;
67         }
68
69         ++_loaded_fusion_cnt;
70
71         fusion->fusion_info = fusion_info;
72         fusion->module_info = mmi_fusion_module_info;
73
74         //FIXME: init() of a fusion module needs to be called in mmi-manager
75         //Right now, we initiate a fusion module found for the first time.
76         if (_loaded_fusion_cnt == 1)
77                 fusion->module_info->fusion_init();
78
79         _fusion_list = eina_list_append(_fusion_list, fusion);
80
81         return 1;
82
83 err:
84         if(fusion_info)
85                 dlclose(fusion_info);
86         return 0;
87 }
88
89 int
90 _modality_fusions_lookup(void)
91 {
92         int cnt = 0;
93         DIR *dir;
94         struct dirent *entry;
95
96         dir = opendir(FUSION_PATH);
97
98         if(!dir)
99         {
100                 LOGE("no dir = %s\n", FUSION_PATH);
101                 return -1;
102         }
103
104         while((entry = readdir(dir)) != NULL)
105         {
106                 char fusion_name[512];
107                 if(strstr(entry->d_name, "fusion") != NULL)
108                 {
109                         snprintf(fusion_name, sizeof(fusion_name), "%s%s", FUSION_PATH, entry->d_name);
110                         LOGD("Fusion full path = %s\n", fusion_name);
111                         cnt += _fusion_load_module(fusion_name);
112                 }
113         }
114
115         return cnt;
116 }
117
118 void
119 modality_fusions_init(void)
120 {
121         int fusion_cnt = -1;
122         fusion_cnt = _modality_fusions_lookup();
123
124         if(fusion_cnt < 0)
125         {
126                 LOGE("No find any fusion in path = %s\n", FUSION_PATH);
127                 return;
128         }
129
130         LOGD("%d fusion modules have been loaded !\n", fusion_cnt);
131 }
132
133 void
134 modality_fusions_shutdown(void)
135 {
136         if(!_fusion_list)
137                 return;
138
139         Eina_List *l = NULL;
140         mmi_fusion_handle *fusion = NULL;
141         EINA_LIST_FOREACH(_fusion_list, l, fusion)
142         {
143                 if(fusion->module_info)
144                 {
145                         if(fusion->module_data)
146                                 fusion->module_info->fusion_deinit(fusion->module_data);
147                         fusion->module_data = NULL;
148                         fusion->module_info = NULL;
149                 }
150                 if(fusion->fusion_info)
151                         dlclose(fusion->fusion_info);
152         }
153
154         _fusion_list = eina_list_free(_fusion_list);
155         _fusion_list = NULL;
156         _loaded_fusion_cnt = 0;
157 }