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