/*
* sensord
*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
*/
-#include <dlfcn.h>
+#include "sensor_loader.h"
+
#include <dirent.h>
-#include <sensor_common.h>
-#include <sensor_loader.h>
-#include <sensor_hal.h>
-#include <sensor_base.h>
-#include <sensor_log.h>
+#include <dlfcn.h>
+#include <fusion_sensor.h>
+#include <hal/hal-sensor.h>
#include <physical_sensor.h>
-#include <virtual_sensor.h>
-#include <external_sensor.h>
-#include <unordered_set>
-#include <algorithm>
-#include <memory>
-
-#include <hrm_sensor.h>
-
-#ifdef ENABLE_AUTO_ROTATION
-#include <auto_rotation_sensor.h>
-#endif
-#ifdef ENABLE_GRAVITY
-#include <gravity_sensor.h>
-#endif
-#ifdef ENABLE_LINEAR_ACCEL
-#include <linear_accel_sensor.h>
-#endif
-#ifdef ENABLE_ORIENTATION
-#include <orientation_sensor.h>
-#endif
-#ifdef ENABLE_ROTATION_VECTOR
-#include <rv_sensor.h>
-#endif
-
-using std::vector;
-using std::string;
-
-#define DEVICE_HAL_DIR_PATH "/usr/lib/sensor"
-
-sensor_loader::sensor_loader()
-{
-}
-
-sensor_loader::~sensor_loader()
-{
- sensor_device_map_t::iterator it_device;
- std::vector<void *>::iterator it_handle;
+#include <sensor_log.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
- for (it_device = m_active_devices.begin(); it_device != m_active_devices.end();)
- it_device = m_active_devices.erase(it_device);
+#include <memory>
- for (it_handle = m_handles.begin(); it_handle != m_handles.end(); ++it_handle)
- dlclose(*it_handle);
+using namespace sensor;
- m_handles.clear();
+sensor_loader::sensor_loader() {
+ if (hal_sensor_get_backend() != 0) {
+ _E("Failed to load hal sensor backend");
+ }
}
-sensor_loader& sensor_loader::get_instance(void)
-{
- static sensor_loader inst;
- return inst;
+sensor_loader::~sensor_loader() {
+ if (hal_sensor_put_backend() != 0) {
+ _E("Failed to clear hal sensor backend");
+ }
}
-bool sensor_loader::load(void)
-{
- std::vector<string> device_hal_paths;
- std::vector<string> unique_device_hal_paths;
+void sensor_loader::load_hal(device_sensor_registry_t &devices) {
+ void **results = nullptr;
- get_paths_from_dir(string(DEVICE_HAL_DIR_PATH), device_hal_paths);
+ int size = hal_sensor_create(&results);
+ if (size <= 0 || !results) {
+ _E("Failed to get sensor from hal sensor backend");
+ return;
+ }
- std::unordered_set<string> s;
- auto unique = [&s](vector<string> &paths, const string &path) {
- if (s.insert(path).second)
- paths.push_back(path);
- };
-
- for_each(device_hal_paths.begin(), device_hal_paths.end(),
- [&](const string &path) {
- unique(unique_device_hal_paths, path);
- }
- );
-
- for_each(unique_device_hal_paths.begin(), unique_device_hal_paths.end(),
- [&](const string &path) {
- void *handle;
- load_sensor_devices(path, handle);
- m_handles.push_back(handle);
- }
- );
-
- create_sensors();
- show_sensor_info();
-
- return true;
+ for (int i = 0; i < size; ++i) {
+ devices.emplace_back(static_cast<sensor_device *>(results[i]));
+ }
+ _I("Success to load sensor from hal sensor backend");
}
-bool sensor_loader::load_sensor_devices(const string &path, void* &handle)
-{
- sensor_device_t *_devices = NULL;
- sensor_device *device = NULL;
- const sensor_info_t *infos;
-
- _I("load device: [%s]", path.c_str());
-
- void *_handle = dlopen(path.c_str(), RTLD_NOW);
- if (!_handle) {
- _E("Failed to dlopen(%s), dlerror : %s", path.c_str(), dlerror());
- return false;
- }
-
- dlerror();
-
- /* TODO: The out-param of the create function should be const */
- create_t create_devices = (create_t) dlsym(_handle, "create");
- if (!create_devices) {
- _E("Failed to find symbols in %s", path.c_str());
- dlclose(_handle);
- return false;
- }
-
- int device_size = create_devices(&_devices);
- if (!_devices) {
- _E("Failed to create devices, path is %s\n", path.c_str());
- dlclose(_handle);
- return false;
- }
-
- for (int i = 0; i < device_size; ++i) {
- device = static_cast<sensor_device *>(_devices[i]);
- std::shared_ptr<sensor_device> device_ptr(device);
-
- int info_size = device_ptr->get_sensors(&infos);
- for (int j = 0; j < info_size; ++j)
- m_devices[&infos[j]] = device_ptr;
- }
-
- handle = _handle;
- return true;
+void sensor_loader::load_hal_legacy(const std::string &path, device_sensor_registry_t &devices)
+{
+ load<sensor_device>(path, devices);
}
-void sensor_loader::create_sensors(void)
+void sensor_loader::load_physical_sensor(const std::string &path, physical_sensor_registry_t &sensors)
{
- /* HRM sensors need SENSOR_PERMISSION_BIO */
- create_physical_sensors<hrm_sensor>(HRM_RAW_SENSOR);
- create_physical_sensors<hrm_sensor>(HRM_SENSOR);
- create_physical_sensors<hrm_sensor>(HRM_LED_GREEN_SENSOR);
- create_physical_sensors<hrm_sensor>(HRM_LED_IR_SENSOR);
- create_physical_sensors<hrm_sensor>(HRM_LED_RED_SENSOR);
-
- create_physical_sensors<physical_sensor>(UNKNOWN_SENSOR);
-
-#ifdef ENABLE_AUTO_ROTATION
- create_virtual_sensors<auto_rotation_sensor>("Auto Rotation");
-#endif
-#ifdef ENABLE_ROTATION_VECTOR
- create_virtual_sensors<rv_sensor>("Rotation Vector");
-#endif
-#ifdef ENABLE_GRAVITY
- create_virtual_sensors<gravity_sensor>("Gravity");
-#endif
-#ifdef ENABLE_LINEAR_ACCEL
- create_virtual_sensors<linear_accel_sensor>("Linear Accel");
-#endif
-#ifdef ENABLE_ORIENTATION
- create_virtual_sensors<orientation_sensor>("Orientation");
-#endif
+ load<physical_sensor>(path, sensors);
}
-template<typename _sensor>
-void sensor_loader::create_physical_sensors(sensor_type_t type)
+void sensor_loader::load_fusion_sensor(const std::string &path, fusion_sensor_registry_t &sensors)
{
- int32_t index;
- const sensor_info_t *info;
- physical_sensor *sensor;
- sensor_device *device;
-
- sensor_device_map_t::iterator it;
-
- for (it = m_devices.begin(); it != m_devices.end(); ++it) {
- info = it->first;
- device = it->second.get();
-
- if (type != UNKNOWN_SENSOR) {
- if (type != (sensor_type_t)(info->type))
- continue;
- }
-
- sensor = dynamic_cast<physical_sensor *>(create_sensor<_sensor>());
-
- if (!sensor) {
- _E("Memory allocation failed[%s]", info->name);
- return;
- }
-
- sensor_type_t _type = (sensor_type_t)info->type;
- index = (int32_t)m_sensors.count(_type);
-
- sensor->set_id(((int64_t)_type << SENSOR_TYPE_SHIFT) | index);
- sensor->set_sensor_info(info);
- sensor->set_sensor_device(device);
-
- std::shared_ptr<sensor_base> sensor_ptr(sensor);
- m_sensors.insert(std::make_pair(_type, sensor_ptr));
-
- m_active_devices[it->first] = it->second;
- m_devices.erase(it->first);
-
- _I("created [%s] sensor", sensor->get_name());
- }
+ load<fusion_sensor>(path, sensors);
}
-template <typename _sensor>
-void sensor_loader::create_virtual_sensors(const char *name)
+void sensor_loader::load_external_sensor(const std::string &path, external_sensor_registry_t &sensors)
{
- int32_t index;
- sensor_type_t type;
- virtual_sensor *instance;
-
- instance = dynamic_cast<virtual_sensor *>(create_sensor<_sensor>());
- if (!instance) {
- _E("Memory allocation failed[%s]", name);
- return;
- }
-
- if (!instance->init()) {
- _E("Failed to init %s", name);
- delete instance;
- return;
- }
-
- std::shared_ptr<sensor_base> sensor(instance);
- type = sensor->get_type();
- index = (int32_t)(m_sensors.count(type));
-
- sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
-
- m_sensors.insert(std::make_pair(type, sensor));
-
- _I("created [%s] sensor", sensor->get_name());
+ load<external_sensor>(path, sensors);
}
-template <typename _sensor>
-void sensor_loader::create_external_sensors(const char *name)
+void sensor_loader::unload(void)
{
- int32_t index;
- sensor_type_t type;
- external_sensor *instance;
-
- instance = dynamic_cast<external_sensor *>(create_sensor<_sensor>());
- if (!instance) {
- _E("Memory allocation failed[%s]", name);
- return;
- }
-
- std::shared_ptr<sensor_base> sensor(instance);
- type = sensor->get_type();
- index = (int32_t)(m_sensors.count(type));
-
- sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index);
-
- m_sensors.insert(std::make_pair(type, sensor));
-
- _I("created [%s] sensor", sensor->get_name());
+ for (auto it = m_modules.begin(); it != m_modules.end(); ++it)
+ dlclose(it->second);
}
-template <typename _sensor>
-sensor_base* sensor_loader::create_sensor(void)
+template<typename T>
+bool sensor_loader::load(const std::string &dir_path, std::vector<std::shared_ptr<T>> &sensors)
{
- sensor_base *instance = NULL;
-
- try {
- instance = new _sensor;
- } catch (std::exception &e) {
- _E("Failed to create sensor, exception: %s", e.what());
- return NULL;
- } catch (int err) {
- _ERRNO(errno, _E, "Failed to create sensor");
- return NULL;
- }
+ bool ret;
+ void *handle;
+ std::vector<std::string> module_paths;
+ void **results;
- return instance;
-}
+ ret = get_module_paths(dir_path, module_paths);
+ retv_if(!ret, false);
-void sensor_loader::show_sensor_info(void)
-{
- _I("========== Loaded sensor information ==========\n");
+ for (auto &path : module_paths) {
+ _I("Load sensor devices from %s", path.c_str());
+ handle = dlopen(path.c_str(), RTLD_NOW);
+ retvm_if(!handle, false, "Failed to dlopen from %s because %s", path.c_str(), dlerror());
- int index = 0;
+ /* TODO: out-param of the create function should be const */
+ create_t create = reinterpret_cast<create_t>(dlsym(handle, "create"));
+ if (!create) {
+ _E("Failed to find symbols from %s", path.c_str());
+ dlclose(handle);
+ return false;
+ }
- auto it = m_sensors.begin();
+ int size = create(&results);
+ if (size <= 0 || !results) {
+ _E("Failed to create sensors from %s", path.c_str());
+ dlclose(handle);
+ return false;
+ }
- while (it != m_sensors.end()) {
- sensor_base *sensor = it->second.get();
+ for (int i = 0; i < size; ++i)
+ sensors.emplace_back(static_cast<T *>(results[i]));
- sensor_info info;
- sensor->get_sensor_info(info);
- _I("No:%d [%s]\n", ++index, sensor->get_name());
- info.show();
- it++;
+ m_modules[path.c_str()] = handle;
+ _I("Success to load sensor devices from %s", path.c_str());
}
- _I("===============================================\n");
+ return true;
}
-bool sensor_loader::get_paths_from_dir(const string &dir_path, vector<string> &hal_paths)
+bool sensor_loader::get_module_paths(const std::string &dir_path, std::vector<std::string> &paths)
{
DIR *dir = NULL;
- struct dirent dir_entry;
- struct dirent *result;
- string name;
- int ret;
+ struct dirent *entry;
+ struct stat buf;
+ std::string filename;
dir = opendir(dir_path.c_str());
-
- if (!dir) {
- _E("Failed to open dir: %s", dir_path.c_str());
- return false;
- }
+ retvm_if(!dir, false, "Failed to open directory[%s]", dir_path.c_str());
while (true) {
- ret = readdir_r(dir, &dir_entry, &result);
-
- if (ret != 0)
- continue;
+ entry = readdir(dir);
+ if (!entry) break;
- if (result == NULL)
- break;
+ filename = std::string(entry->d_name);
- name = string(dir_entry.d_name);
-
- if (name == "." || name == "..")
+ if (filename == "." || filename == "..")
continue;
- hal_paths.push_back(dir_path + "/" + name);
- }
-
- closedir(dir);
- return true;
-}
-
-sensor_base* sensor_loader::get_sensor(sensor_type_t type)
-{
- auto it = m_sensors.find(type);
-
- if (it == m_sensors.end())
- return NULL;
+ std::string full_path = dir_path + "/" + filename;
- return it->second.get();
-}
-
-sensor_base* sensor_loader::get_sensor(sensor_id_t id)
-{
- vector<sensor_base *> sensors;
-
- sensor_type_t type = static_cast<sensor_type_t>(id >> SENSOR_TYPE_SHIFT);
- unsigned int index = (id & SENSOR_INDEX_MASK);
-
- sensors = get_sensors(type);
-
- if (index >= sensors.size())
- return NULL;
-
- return sensors[index];
-}
-
-vector<sensor_type_t> sensor_loader::get_sensor_types(void)
-{
- vector<sensor_type_t> sensor_types;
-
- auto it = m_sensors.begin();
-
- while (it != m_sensors.end()) {
- sensor_types.push_back((sensor_type_t)(it->first));
- it = m_sensors.upper_bound(it->first);
- }
-
- return sensor_types;
-}
-
-vector<sensor_base *> sensor_loader::get_sensors(sensor_type_t type)
-{
- vector<sensor_base *> sensor_list;
- std::pair<sensor_map_t::iterator, sensor_map_t::iterator> ret;
-
- if ((int)(type) == (int)SENSOR_DEVICE_ALL)
- ret = std::make_pair(m_sensors.begin(), m_sensors.end());
- else
- ret = m_sensors.equal_range(type);
-
- for (auto it = ret.first; it != ret.second; ++it)
- sensor_list.push_back(it->second.get());
-
- return sensor_list;
-}
-
-vector<sensor_base *> sensor_loader::get_virtual_sensors(void)
-{
- vector<sensor_base *> virtual_list;
- sensor_base* sensor;
-
- for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
- sensor = it->second.get();
+ if (lstat(full_path.c_str(), &buf) != 0)
+ break;
- if (!sensor || !sensor->is_virtual())
+ if (S_ISDIR(buf.st_mode))
continue;
- virtual_list.push_back(sensor);
+ paths.push_back(full_path);
}
+ closedir(dir);
- return virtual_list;
+ return true;
}