sensord: support external sensor feature
[platform/core/system/sensord.git] / src / server / sensor_loader.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2013 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 <dlfcn.h>
21 #include <dirent.h>
22 #include <sensor_common.h>
23 #include <sensor_loader.h>
24 #include <sensor_hal.h>
25 #include <sensor_base.h>
26 #include <sensor_log.h>
27 #include <physical_sensor.h>
28 #include <virtual_sensor.h>
29 #include <external_sensor.h>
30 #include <unordered_set>
31 #include <algorithm>
32 #include <memory>
33
34 #include <hrm_sensor.h>
35
36 #ifdef ENABLE_AUTO_ROTATION
37 #include <auto_rotation_sensor.h>
38 #endif
39 #ifdef ENABLE_GRAVITY
40 #include <gravity_sensor.h>
41 #endif
42 #ifdef ENABLE_LINEAR_ACCEL
43 #include <linear_accel_sensor.h>
44 #endif
45 #ifdef ENABLE_ORIENTATION
46 #include <orientation_sensor.h>
47 #endif
48 #ifdef ENABLE_ROTATION_VECTOR
49 #include <rotation_vector_sensor.h>
50 #endif
51
52 using std::vector;
53 using std::string;
54
55 #define DEVICE_HAL_DIR_PATH "/usr/lib/sensor"
56
57 sensor_loader::sensor_loader()
58 {
59 }
60
61 sensor_loader::~sensor_loader()
62 {
63         sensor_device_map_t::iterator it_device;
64         std::vector<void *>::iterator it_handle;
65
66         for (it_device = m_devices.begin(); it_device != m_devices.end();)
67                 it_device = m_devices.erase(it_device);
68
69         for (it_handle = m_handles.begin(); it_handle != m_handles.end(); ++it_handle)
70                 dlclose(*it_handle);
71
72         m_handles.clear();
73 }
74
75 sensor_loader& sensor_loader::get_instance(void)
76 {
77         static sensor_loader inst;
78         return inst;
79 }
80
81 bool sensor_loader::load(void)
82 {
83         std::vector<string> device_hal_paths;
84         std::vector<string> unique_device_hal_paths;
85
86         get_paths_from_dir(string(DEVICE_HAL_DIR_PATH), device_hal_paths);
87
88         std::unordered_set<string> s;
89         auto unique = [&s](vector<string> &paths, const string &path) {
90                 if (s.insert(path).second)
91                         paths.push_back(path);
92         };
93
94         for_each(device_hal_paths.begin(), device_hal_paths.end(),
95                 [&](const string &path) {
96                         unique(unique_device_hal_paths, path);
97                 }
98         );
99
100         for_each(unique_device_hal_paths.begin(), unique_device_hal_paths.end(),
101                 [&](const string &path) {
102                         void *handle;
103                         load_sensor_devices(path, handle);
104                         m_handles.push_back(handle);
105                 }
106         );
107
108         create_sensors();
109         show_sensor_info();
110
111         return true;
112 }
113
114 bool sensor_loader::load_sensor_devices(const string &path, void* &handle)
115 {
116         sensor_device_t *_devices = NULL;
117         sensor_device *device = NULL;
118         const sensor_info_t *infos;
119
120         _I("load device: [%s]", path.c_str());
121
122         void *_handle = dlopen(path.c_str(), RTLD_NOW);
123         if (!_handle) {
124                 _E("Failed to dlopen(%s), dlerror : %s", path.c_str(), dlerror());
125                 return false;
126         }
127
128         dlerror();
129
130         /* TODO: The out-param of the create function should be const */
131         create_t create_devices = (create_t) dlsym(_handle, "create");
132         if (!create_devices) {
133                 _E("Failed to find symbols in %s", path.c_str());
134                 dlclose(_handle);
135                 return false;
136         }
137
138         int device_size = create_devices(&_devices);
139         if (!_devices) {
140                 _E("Failed to create devices, path is %s\n", path.c_str());
141                 dlclose(_handle);
142                 return false;
143         }
144
145         for (int i = 0; i < device_size; ++i) {
146                 device = static_cast<sensor_device *>(_devices[i]);
147                 std::shared_ptr<sensor_device> device_ptr(device);
148
149                 int info_size = device_ptr->get_sensors(&infos);
150                 for (int j = 0; j < info_size; ++j)
151                         m_devices[&infos[j]] = device_ptr;
152         }
153
154         handle = _handle;
155
156         return true;
157 }
158
159 void sensor_loader::create_sensors(void)
160 {
161         /* HRM sensors need SENSOR_PERMISSION_BIO */
162         create_physical_sensors<hrm_sensor>(HRM_RAW_SENSOR);
163         create_physical_sensors<hrm_sensor>(HRM_SENSOR);
164         create_physical_sensors<hrm_sensor>(HRM_LED_GREEN_SENSOR);
165         create_physical_sensors<hrm_sensor>(HRM_LED_IR_SENSOR);
166         create_physical_sensors<hrm_sensor>(HRM_LED_RED_SENSOR);
167
168         create_physical_sensors<physical_sensor>(UNKNOWN_SENSOR);
169
170 #ifdef ENABLE_AUTO_ROTATION
171         create_virtual_sensors<auto_rotation_sensor>("Auto Rotation");
172 #endif
173 #ifdef ENABLE_ROTATION_VECTOR
174         create_virtual_sensors<rotation_vector_sensor>("Rotation Vector");
175 #endif
176 #ifdef ENABLE_GRAVITY
177         create_virtual_sensors<gravity_sensor>("Gravity");
178 #endif
179 #ifdef ENABLE_LINEAR_ACCEL
180         create_virtual_sensors<linear_accel_sensor>("Linear Accel");
181 #endif
182 #ifdef ENABLE_ORIENTATION
183         create_virtual_sensors<orientation_sensor>("Orientation");
184 #endif
185 }
186
187 template<typename _sensor>
188 void sensor_loader::create_physical_sensors(sensor_type_t type)
189 {
190         int32_t index;
191         const sensor_info_t *info;
192         physical_sensor *sensor;
193         sensor_device *device;
194
195         sensor_device_map_t::iterator it;
196
197         for (it = m_devices.begin(); it != m_devices.end(); ++it) {
198                 info = it->first;
199                 device = it->second.get();
200
201                 if (type != UNKNOWN_SENSOR) {
202                         if (type != (sensor_type_t)(info->type))
203                                 continue;
204                 }
205
206                 sensor = dynamic_cast<physical_sensor *>(create_sensor<_sensor>());
207
208                 if (!sensor) {
209                         _E("Memory allocation failed[%s]", info->name);
210                         return;
211                 }
212
213                 sensor_type_t _type = (sensor_type_t)info->type;
214                 index = (int32_t)m_sensors.count(_type);
215
216                 sensor->set_id(((int64_t)_type << SENSOR_TYPE_SHIFT) | index);
217                 sensor->set_sensor_info(info);
218                 sensor->set_sensor_device(device);
219
220                 std::shared_ptr<sensor_base> sensor_ptr(sensor);
221                 m_sensors.insert(std::make_pair(_type, sensor_ptr));
222
223                 _I("created [%s] sensor", sensor->get_name());
224         }
225 }
226
227 template <typename _sensor>
228 void sensor_loader::create_virtual_sensors(const char *name)
229 {
230         int32_t index;
231         sensor_type_t type;
232         virtual_sensor *instance;
233
234         instance = dynamic_cast<virtual_sensor *>(create_sensor<_sensor>());
235         if (!instance) {
236                 _E("Memory allocation failed[%s]", name);
237                 return;
238         }
239
240         if (!instance->init()) {
241                 _E("Failed to init %s", name);
242                 delete instance;
243                 return;
244         }
245
246         std::shared_ptr<sensor_base> sensor(instance);
247         type = sensor->get_type();
248         index = (int32_t)(m_sensors.count(type));
249
250         sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
251
252         m_sensors.insert(std::make_pair(type, sensor));
253
254         _I("created [%s] sensor", sensor->get_name());
255 }
256
257 template <typename _sensor>
258 void sensor_loader::create_external_sensors(const char *name)
259 {
260         int32_t index;
261         sensor_type_t type;
262         external_sensor *instance;
263
264         instance = dynamic_cast<external_sensor *>(create_sensor<_sensor>());
265         if (!instance) {
266                 _E("Memory allocation failed[%s]", name);
267                 return;
268         }
269
270         std::shared_ptr<sensor_base> sensor(instance);
271         type = sensor->get_type();
272         index = (int32_t)(m_sensors.count(type));
273
274         sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
275
276         m_sensors.insert(std::make_pair(type, sensor));
277
278         _I("created [%s] sensor", sensor->get_name());
279 }
280
281 template <typename _sensor>
282 sensor_base* sensor_loader::create_sensor(void)
283 {
284         sensor_base *instance = NULL;
285
286         try {
287                 instance = new _sensor;
288         } catch (std::exception &e) {
289                 _E("Failed to create sensor, exception: %s", e.what());
290                 return NULL;
291         } catch (int err) {
292                 _ERRNO(errno, _E, "Failed to create sensor");
293                 return NULL;
294         }
295
296         return instance;
297 }
298
299 void sensor_loader::show_sensor_info(void)
300 {
301         _I("========== Loaded sensor information ==========\n");
302
303         int index = 0;
304
305         auto it = m_sensors.begin();
306
307         while (it != m_sensors.end()) {
308                 sensor_base *sensor = it->second.get();
309
310                 sensor_info info;
311                 sensor->get_sensor_info(info);
312                 _I("No:%d [%s]\n", ++index, sensor->get_name());
313                 info.show();
314                 it++;
315         }
316
317         _I("===============================================\n");
318 }
319
320 bool sensor_loader::get_paths_from_dir(const string &dir_path, vector<string> &hal_paths)
321 {
322         DIR *dir = NULL;
323         struct dirent dir_entry;
324         struct dirent *result;
325         string name;
326         int error;
327
328         dir = opendir(dir_path.c_str());
329
330         if (!dir) {
331                 _E("Failed to open dir: %s", dir_path.c_str());
332                 return false;
333         }
334
335         while (true) {
336                 error = readdir_r(dir, &dir_entry, &result);
337
338                 if (error != 0)
339                         continue;
340
341                 if (result == NULL)
342                         break;
343
344                 name = string(dir_entry.d_name);
345
346                 if (name == "." || name == "..")
347                         continue;
348
349                 hal_paths.push_back(dir_path + "/" + name);
350         }
351
352         closedir(dir);
353         return true;
354 }
355
356 sensor_base* sensor_loader::get_sensor(sensor_type_t type)
357 {
358         auto it = m_sensors.find(type);
359
360         if (it == m_sensors.end())
361                 return NULL;
362
363         return it->second.get();
364 }
365
366 sensor_base* sensor_loader::get_sensor(sensor_id_t id)
367 {
368         vector<sensor_base *> sensors;
369
370         sensor_type_t type = static_cast<sensor_type_t>(id >> SENSOR_TYPE_SHIFT);
371         unsigned int index = (id & SENSOR_INDEX_MASK);
372
373         sensors = get_sensors(type);
374
375         if (index >= sensors.size())
376                 return NULL;
377
378         return sensors[index];
379 }
380
381 vector<sensor_type_t> sensor_loader::get_sensor_types(void)
382 {
383         vector<sensor_type_t> sensor_types;
384
385         auto it = m_sensors.begin();
386
387         while (it != m_sensors.end()) {
388                 sensor_types.push_back((sensor_type_t)(it->first));
389                 it = m_sensors.upper_bound(it->first);
390         }
391
392         return sensor_types;
393 }
394
395 vector<sensor_base *> sensor_loader::get_sensors(sensor_type_t type)
396 {
397         vector<sensor_base *> sensor_list;
398         std::pair<sensor_map_t::iterator, sensor_map_t::iterator> ret;
399
400         if ((int)(type) == (int)SENSOR_DEVICE_ALL)
401                 ret = std::make_pair(m_sensors.begin(), m_sensors.end());
402         else
403                 ret = m_sensors.equal_range(type);
404
405         for (auto it = ret.first; it != ret.second; ++it)
406                 sensor_list.push_back(it->second.get());
407
408         return sensor_list;
409 }
410
411 vector<sensor_base *> sensor_loader::get_virtual_sensors(void)
412 {
413         vector<sensor_base *> virtual_list;
414         sensor_base* sensor;
415
416         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
417                 sensor = it->second.get();
418
419                 if (!sensor || !sensor->is_virtual())
420                         continue;
421
422                 virtual_list.push_back(sensor);
423         }
424
425         return virtual_list;
426 }