Merge "sensord: add the sensord plugin logic for flexibility" into devel/tizen_3.0
[platform/core/system/sensord.git] / src / server / sensor_loader.cpp
1 /*
2  * libsensord-share
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <sensor_loader.h>
21 #include <libxml/xmlmemory.h>
22 #include <libxml/parser.h>
23 #include <sensor_hal.h>
24 #include <sensor_base.h>
25 #include <physical_sensor.h>
26 #include <dlfcn.h>
27 #include <dirent.h>
28 #include <sensor_logs.h>
29 #include <unordered_set>
30 #include <algorithm>
31
32 #include <accel_sensor.h>
33 #ifdef ENABLE_AUTO_ROTATION
34 #include <auto_rotation_sensor.h>
35 #endif
36
37 using std::vector;
38 using std::string;
39
40 #define DEVICE_PLUGINS_DIR_PATH "/usr/lib/sensor"
41 #define SENSOR_TYPE_SHIFT 32
42 #define SENSOR_INDEX_MASK 0xFFFFFFFF
43
44 sensor_loader::sensor_loader()
45 {
46 }
47
48 sensor_loader& sensor_loader::get_instance()
49 {
50         static sensor_loader inst;
51         return inst;
52 }
53
54 bool sensor_loader::load(void)
55 {
56         std::vector<string> device_plugin_paths;
57         std::vector<string> unique_device_plugin_paths;
58
59         get_paths_from_dir(string(DEVICE_PLUGINS_DIR_PATH), device_plugin_paths);
60
61         std::unordered_set<string> s;
62         auto unique = [&s](vector<string> &paths, const string &path) {
63                 if (s.insert(path).second)
64                         paths.push_back(path);
65         };
66
67         for_each(device_plugin_paths.begin(), device_plugin_paths.end(),
68                 [&](const string &path) {
69                         unique(unique_device_plugin_paths, path);
70                 }
71         );
72
73         for_each(unique_device_plugin_paths.begin(), unique_device_plugin_paths.end(),
74                 [&](const string &path) {
75                         void *handle;
76                         load_sensor_devices(path, handle);
77                 }
78         );
79
80         create_sensors();
81         show_sensor_info();
82
83         return true;
84 }
85
86 bool sensor_loader::load_sensor_devices(const string &path, void* &handle)
87 {
88         sensor_device_t *_devices = NULL;
89         sensor_device *device;
90         const sensor_handle_t *handles;
91
92         _I("load device: [%s]", path.c_str());
93
94         void *_handle = dlopen(path.c_str(), RTLD_NOW);
95         if (!_handle) {
96                 _E("Failed to dlopen(%s), dlerror : %s", path.c_str(), dlerror());
97                 return false;
98         }
99
100         dlerror();
101
102         create_t create_devices = (create_t) dlsym(_handle, "create");
103         if (!create_devices) {
104                 _E("Failed to find symbols in %s", path.c_str());
105                 dlclose(_handle);
106                 return false;
107         }
108
109         int device_size = create_devices(&_devices);
110         if (!_devices) {
111                 _E("Failed to create devices, path is %s\n", path.c_str());
112                 dlclose(_handle);
113                 return false;
114         }
115
116         for (int i = 0; i < device_size; ++i) {
117                 device = static_cast<sensor_device *>(_devices[i]);
118
119                 int handle_size = device->get_sensors(&handles);
120                 for (int j = 0; j < handle_size; ++j)
121                         m_devices[&handles[j]] = device;
122         }
123
124         handle = _handle;
125
126         delete _devices;
127         return true;
128 }
129
130 void sensor_loader::create_sensors(void)
131 {
132         create_physical_sensors<accel_sensor>(ACCELEROMETER_SENSOR);
133         create_physical_sensors<physical_sensor>(UNKNOWN_SENSOR);
134
135         create_virtual_sensors<auto_rotation_sensor>("Auto Rotation");
136 }
137
138 template<typename _sensor>
139 void sensor_loader::create_physical_sensors(sensor_type_t type)
140 {
141         int32_t index;
142         const sensor_handle_t *handle;
143         physical_sensor *sensor;
144         sensor_device *device;
145
146         sensor_device_map_t::iterator it = m_devices.begin();
147
148         for (sensor_device_map_t::iterator it = m_devices.begin(); it != m_devices.end(); ++it) {
149                 handle = it->first;
150                 device = it->second;
151                 if (m_devices[handle] == NULL)
152                         continue;
153
154                 if (type != UNKNOWN_SENSOR) {
155                         if (type != (sensor_type_t)(handle->type))
156                                 continue;
157                 }
158
159                 sensor = reinterpret_cast<physical_sensor *>(create_sensor<_sensor>());
160
161                 if (!sensor) {
162                         _E("Memory allocation failed[%s]", handle->name);
163                         return;
164                 }
165
166                 index = (int32_t) (m_sensors.count(type));
167
168                 sensor->set_id(((int64_t)handle->type << SENSOR_TYPE_SHIFT) | index);
169                 sensor->set_sensor_handle(handle);
170                 sensor->set_sensor_device(device);
171
172                 std::shared_ptr<sensor_base> sensor_ptr(sensor);
173                 m_sensors.insert(std::make_pair(type, sensor_ptr));
174
175                 _I("created [%s] sensor", sensor->get_name());
176
177                 m_devices[handle] = NULL;
178         }
179         return;
180 }
181
182 template <typename _sensor>
183 void sensor_loader::create_virtual_sensors(const char *name)
184 {
185         int32_t index;
186         sensor_type_t type;
187         virtual_sensor *instance;
188
189         instance = reinterpret_cast<virtual_sensor *>(create_sensor<_sensor>());
190         if (!instance) {
191                 _E("Memory allocation failed[%s]", name);
192                 return;
193         }
194
195         if (!instance->init()) {
196                 _E("Failed to init %s", name);
197                 delete instance;
198                 return;
199         }
200
201         std::shared_ptr<sensor_base> sensor(instance);
202         type = sensor->get_type();
203         index = (int32_t)(m_sensors.count(type));
204
205         sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
206
207         m_sensors.insert(std::make_pair(type, sensor));
208
209         _I("created [%s] sensor", sensor->get_name());
210 }
211
212 template <typename _sensor>
213 sensor_base* sensor_loader::create_sensor(void)
214 {
215         sensor_base *instance = NULL;
216
217         try {
218                 instance = new _sensor;
219         } catch (std::exception &e) {
220                 _E("Failed to create sensor, exception: %s", e.what());
221                 return NULL;
222         } catch (int err) {
223                 _E("Failed to create sensor err: %d, cause: %s", err, strerror(err));
224                 return NULL;
225         }
226
227         return instance;
228 }
229
230 void sensor_loader::show_sensor_info(void)
231 {
232         _I("========== Loaded sensor information ==========\n");
233
234         int index = 0;
235
236         auto it = m_sensors.begin();
237
238         while (it != m_sensors.end()) {
239                 sensor_base *sensor = it->second.get();
240
241                 sensor_info info;
242                 sensor->get_sensor_info(info);
243                 _I("No:%d [%s]\n", ++index, sensor->get_name());
244                 info.show();
245                 it++;
246         }
247
248         _I("===============================================\n");
249 }
250
251 bool sensor_loader::get_paths_from_dir(const string &dir_path, vector<string> &plugin_paths)
252 {
253         DIR *dir = NULL;
254         struct dirent *dir_entry = NULL;
255
256         dir = opendir(dir_path.c_str());
257
258         if (!dir) {
259                 _E("Failed to open dir: %s", dir_path.c_str());
260                 return false;
261         }
262
263         string name;
264
265         while ((dir_entry = readdir(dir))) {
266                 name = string(dir_entry->d_name);
267                 plugin_paths.push_back(dir_path + "/" + name);
268         }
269
270         closedir(dir);
271         return true;
272 }
273
274 sensor_base* sensor_loader::get_sensor(sensor_type_t type)
275 {
276         auto it_plugins = m_sensors.find(type);
277
278         if (it_plugins == m_sensors.end())
279                 return NULL;
280
281         return it_plugins->second.get();
282 }
283
284 sensor_base* sensor_loader::get_sensor(sensor_id_t id)
285 {
286         vector<sensor_base *> sensors;
287
288         sensor_type_t type = static_cast<sensor_type_t> (id >> SENSOR_TYPE_SHIFT);
289         unsigned int index = (id & SENSOR_INDEX_MASK);
290
291         sensors = get_sensors(type);
292
293         if (index >= sensors.size())
294                 return NULL;
295
296         return sensors[index];
297 }
298
299 vector<sensor_type_t> sensor_loader::get_sensor_types(void)
300 {
301         vector<sensor_type_t> sensor_types;
302
303         auto it = m_sensors.begin();
304
305         while (it != m_sensors.end()) {
306                 sensor_types.push_back((sensor_type_t)(it->first));
307                 it = m_sensors.upper_bound(it->first);
308         }
309
310         return sensor_types;
311 }
312
313 vector<sensor_base *> sensor_loader::get_sensors(sensor_type_t type)
314 {
315         vector<sensor_base *> sensor_list;
316         std::pair<sensor_map_t::iterator, sensor_map_t::iterator> ret;
317
318         if ((int)(type) == (int)SENSOR_DEVICE_ALL)
319                 ret = std::make_pair(m_sensors.begin(), m_sensors.end());
320         else
321                 ret = m_sensors.equal_range(type);
322
323         for (auto it = ret.first; it != ret.second; ++it)
324                 sensor_list.push_back(it->second.get());
325
326         return sensor_list;
327 }
328
329 vector<sensor_base *> sensor_loader::get_virtual_sensors(void)
330 {
331         vector<sensor_base *> virtual_list;
332         sensor_base* sensor;
333
334         for (auto sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
335                 sensor = sensor_it->second.get();
336
337                 if (sensor && sensor->is_virtual() == true) {
338                         virtual_list.push_back(sensor);
339                 }
340         }
341
342         return virtual_list;
343 }