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