4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
34 #include <hrm_sensor.h>
36 #ifdef ENABLE_AUTO_ROTATION
37 #include <auto_rotation_sensor.h>
40 #include <gravity_sensor.h>
42 #ifdef ENABLE_LINEAR_ACCEL
43 #include <linear_accel_sensor.h>
45 #ifdef ENABLE_ORIENTATION
46 #include <orientation_sensor.h>
48 #ifdef ENABLE_ROTATION_VECTOR
49 #include <rv_sensor.h>
55 #define DEVICE_HAL_DIR_PATH "/usr/lib/sensor"
57 sensor_loader::sensor_loader()
61 sensor_loader::~sensor_loader()
63 sensor_device_map_t::iterator it_device;
64 std::vector<void *>::iterator it_handle;
66 for (it_device = m_active_devices.begin(); it_device != m_active_devices.end();)
67 it_device = m_active_devices.erase(it_device);
69 for (it_handle = m_handles.begin(); it_handle != m_handles.end(); ++it_handle)
75 sensor_loader& sensor_loader::get_instance(void)
77 static sensor_loader inst;
81 bool sensor_loader::load(void)
83 std::vector<string> device_hal_paths;
84 std::vector<string> unique_device_hal_paths;
86 get_paths_from_dir(string(DEVICE_HAL_DIR_PATH), device_hal_paths);
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);
94 for_each(device_hal_paths.begin(), device_hal_paths.end(),
95 [&](const string &path) {
96 unique(unique_device_hal_paths, path);
100 for_each(unique_device_hal_paths.begin(), unique_device_hal_paths.end(),
101 [&](const string &path) {
103 load_sensor_devices(path, handle);
104 m_handles.push_back(handle);
114 bool sensor_loader::load_sensor_devices(const string &path, void* &handle)
116 sensor_device_t *_devices = NULL;
117 sensor_device *device = NULL;
118 const sensor_info_t *infos;
120 _I("load device: [%s]", path.c_str());
122 void *_handle = dlopen(path.c_str(), RTLD_NOW);
124 _E("Failed to dlopen(%s), dlerror : %s", path.c_str(), dlerror());
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());
138 int device_size = create_devices(&_devices);
140 _E("Failed to create devices, path is %s\n", path.c_str());
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);
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;
159 void sensor_loader::create_sensors(void)
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);
168 create_physical_sensors<physical_sensor>(UNKNOWN_SENSOR);
170 #ifdef ENABLE_AUTO_ROTATION
171 create_virtual_sensors<auto_rotation_sensor>("Auto Rotation");
173 #ifdef ENABLE_ROTATION_VECTOR
174 create_virtual_sensors<rv_sensor>("Rotation Vector");
176 #ifdef ENABLE_GRAVITY
177 create_virtual_sensors<gravity_sensor>("Gravity");
179 #ifdef ENABLE_LINEAR_ACCEL
180 create_virtual_sensors<linear_accel_sensor>("Linear Accel");
182 #ifdef ENABLE_ORIENTATION
183 create_virtual_sensors<orientation_sensor>("Orientation");
187 template<typename _sensor>
188 void sensor_loader::create_physical_sensors(sensor_type_t type)
191 const sensor_info_t *info;
192 physical_sensor *sensor;
193 sensor_device *device;
195 sensor_device_map_t::iterator it;
197 for (it = m_devices.begin(); it != m_devices.end(); ++it) {
199 device = it->second.get();
201 if (type != UNKNOWN_SENSOR) {
202 if (type != (sensor_type_t)(info->type))
206 sensor = dynamic_cast<physical_sensor *>(create_sensor<_sensor>());
209 _E("Memory allocation failed[%s]", info->name);
213 sensor_type_t _type = (sensor_type_t)info->type;
214 index = (int32_t)m_sensors.count(_type);
216 sensor->set_id(((int64_t)_type << SENSOR_TYPE_SHIFT) | index);
217 sensor->set_sensor_info(info);
218 sensor->set_sensor_device(device);
220 std::shared_ptr<sensor_base> sensor_ptr(sensor);
221 m_sensors.insert(std::make_pair(_type, sensor_ptr));
223 m_active_devices[it->first] = it->second;
224 m_devices.erase(it->first);
226 _I("created [%s] sensor", sensor->get_name());
230 template <typename _sensor>
231 void sensor_loader::create_virtual_sensors(const char *name)
235 virtual_sensor *instance;
237 instance = dynamic_cast<virtual_sensor *>(create_sensor<_sensor>());
239 _E("Memory allocation failed[%s]", name);
243 if (!instance->init()) {
244 _E("Failed to init %s", name);
249 std::shared_ptr<sensor_base> sensor(instance);
250 type = sensor->get_type();
251 index = (int32_t)(m_sensors.count(type));
253 sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
255 m_sensors.insert(std::make_pair(type, sensor));
257 _I("created [%s] sensor", sensor->get_name());
260 template <typename _sensor>
261 void sensor_loader::create_external_sensors(const char *name)
265 external_sensor *instance;
267 instance = dynamic_cast<external_sensor *>(create_sensor<_sensor>());
269 _E("Memory allocation failed[%s]", name);
273 std::shared_ptr<sensor_base> sensor(instance);
274 type = sensor->get_type();
275 index = (int32_t)(m_sensors.count(type));
277 sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
279 m_sensors.insert(std::make_pair(type, sensor));
281 _I("created [%s] sensor", sensor->get_name());
284 template <typename _sensor>
285 sensor_base* sensor_loader::create_sensor(void)
287 sensor_base *instance = NULL;
290 instance = new _sensor;
291 } catch (std::exception &e) {
292 _E("Failed to create sensor, exception: %s", e.what());
295 _ERRNO(errno, _E, "Failed to create sensor");
302 void sensor_loader::show_sensor_info(void)
304 _I("========== Loaded sensor information ==========\n");
308 auto it = m_sensors.begin();
310 while (it != m_sensors.end()) {
311 sensor_base *sensor = it->second.get();
314 sensor->get_sensor_info(info);
315 _I("No:%d [%s]\n", ++index, sensor->get_name());
320 _I("===============================================\n");
323 bool sensor_loader::get_paths_from_dir(const string &dir_path, vector<string> &hal_paths)
326 struct dirent dir_entry;
327 struct dirent *result;
331 dir = opendir(dir_path.c_str());
334 _E("Failed to open dir: %s", dir_path.c_str());
339 ret = readdir_r(dir, &dir_entry, &result);
347 name = string(dir_entry.d_name);
349 if (name == "." || name == "..")
352 hal_paths.push_back(dir_path + "/" + name);
359 sensor_base* sensor_loader::get_sensor(sensor_type_t type)
361 auto it = m_sensors.find(type);
363 if (it == m_sensors.end())
366 return it->second.get();
369 sensor_base* sensor_loader::get_sensor(sensor_id_t id)
371 vector<sensor_base *> sensors;
373 sensor_type_t type = static_cast<sensor_type_t>(id >> SENSOR_TYPE_SHIFT);
374 unsigned int index = (id & SENSOR_INDEX_MASK);
376 sensors = get_sensors(type);
378 if (index >= sensors.size())
381 return sensors[index];
384 vector<sensor_type_t> sensor_loader::get_sensor_types(void)
386 vector<sensor_type_t> sensor_types;
388 auto it = m_sensors.begin();
390 while (it != m_sensors.end()) {
391 sensor_types.push_back((sensor_type_t)(it->first));
392 it = m_sensors.upper_bound(it->first);
398 vector<sensor_base *> sensor_loader::get_sensors(sensor_type_t type)
400 vector<sensor_base *> sensor_list;
401 std::pair<sensor_map_t::iterator, sensor_map_t::iterator> ret;
403 if ((int)(type) == (int)SENSOR_DEVICE_ALL)
404 ret = std::make_pair(m_sensors.begin(), m_sensors.end());
406 ret = m_sensors.equal_range(type);
408 for (auto it = ret.first; it != ret.second; ++it)
409 sensor_list.push_back(it->second.get());
414 vector<sensor_base *> sensor_loader::get_virtual_sensors(void)
416 vector<sensor_base *> virtual_list;
419 for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
420 sensor = it->second.get();
422 if (!sensor || !sensor->is_virtual())
425 virtual_list.push_back(sensor);