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