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