From f192807171708e30d467c3a11cea4855f6bcd947 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 13:50:49 +0900 Subject: [PATCH] sensor: api: implement internal api using classes - check invalid parameters. - call proper operations/functions. Change-Id: I61b9813a3f77cfd116a8ea72ee417f4cb7356640 Signed-off-by: kibak.yoon --- src/client/sensor_internal.cpp | 532 +++++++++++++++++++++++++++++------------ 1 file changed, 373 insertions(+), 159 deletions(-) diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 0864b14..f9b2698 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -17,184 +17,270 @@ * */ -#include "sensor_internal.h" -#include +#include +#include +#include + +#include +#include +#include #include +#include + +#define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11) + +using namespace sensor; + +class sensor_event_handler : public ipc::channel_handler +{ +public: + sensor_event_handler(sensor_t sensor, sensor_cb_t cb, void *user_data) + : m_sensor(reinterpret_cast(sensor)) + , m_cb(cb) + , m_user_data(user_data) + {} + + void connected(ipc::channel *ch) {} + void disconnected(ipc::channel *ch) {} + void read(ipc::channel *ch, ipc::message &msg) + { + int event_type; + sensor_data_t *data; + + data = reinterpret_cast(msg.body()); + event_type = CONVERT_TYPE_EVENT(m_sensor->get_type()); + + m_cb(m_sensor, event_type, data, m_user_data); + } + + void read_complete(ipc::channel *ch) {} + void error_caught(ipc::channel *ch, int error) {} + +private: + sensor_info *m_sensor; + sensor_cb_t m_cb; + void *m_user_data; +}; + +class sensor_accuracy_handler : public ipc::channel_handler +{ +public: + sensor_accuracy_handler(sensor_t sensor, sensor_accuracy_changed_cb_t cb, void *user_data) + : m_sensor(reinterpret_cast(sensor)) + , m_cb(cb) + , m_user_data(user_data) + {} + + void connected(ipc::channel *ch) {} + void disconnected(ipc::channel *ch) {} + void read(ipc::channel *ch, ipc::message &msg) + { + sensor_data_t *data; + data = reinterpret_cast(msg.body()); + + m_cb(m_sensor, data->timestamp, data->accuracy, m_user_data); + } + + void read_complete(ipc::channel *ch) {} + void error_caught(ipc::channel *ch, int error) {} + +private: + sensor_info *m_sensor; + sensor_accuracy_changed_cb_t m_cb; + void *m_user_data; +}; + +static sensor::sensor_manager manager; +static std::unordered_map listeners; /* * TO-DO-LIST: - * 1. restore session - * 1.1 close socket - * 1.2 listener : start, interval, batch latency, attributes - * 2. power save option / lcd vconf : move to server - * 3. clean up data - * 4. thread-safe : ipc_client - * 5. client-id - * 6. cmd_hello - * 7. stop : unset interval, batch - * 8. get sensor list + * 1. power save option / lcd vconf : move to server + * 2. thread-safe : ipc_client */ API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count) { - /* - * 1. get sensor list() - * 2. if sensor list is empty, return -ENODATA - * 3. if id is -EACCESS, return -EACCESS (except ALL_SENSOR) - * 4. list : memory allocation - * 5. return list, count - */ + int ret = OP_ERROR; + + retvm_if((!list || !count), -EINVAL, + "Invalid parameter[%#x, %#x]", list, count); + retvm_if(!manager.connect(), -EIO, "Failed to connect"); + + ret = manager.get_sensors(type, list, count); + retv_if(ret < 0, ret); return OP_SUCCESS; } API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor) { - /* - * 1. get sensor list() - * 2. if there is no sensor, return -ENODATA - * 3. if id is -EACCESS, return -EACCESS - * 4. if SENSOR_ALL, ??? - * 5. return sensor - */ + int ret = OP_ERROR; + + retvm_if(!sensor, -EPERM, "Invalid parameter[%#x]", sensor); + retvm_if(!manager.connect(), -EIO, "Failed to connect"); + + ret = manager.get_sensor(type, sensor); + retv_if(ret < 0, ret); return OP_SUCCESS; } API bool sensord_get_type(sensor_t sensor, sensor_type_t *type) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!type, false, "Invalid parameter[%#x]", type); + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *type = static_cast(sensor)->get_type(); return true; } API const char* sensord_get_name(sensor_t sensor) { - /* - * 1. if there is no sensor, return NULL - */ + retvm_if(!manager.connect(), NULL, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), NULL, + "Invalid sensor[%#x]", sensor); - return NULL; + return static_cast(sensor)->get_uri().c_str(); } API const char* sensord_get_vendor(sensor_t sensor) { - /* - * 1. if there is no sensor, return NULL - */ + retvm_if(!manager.connect(), NULL, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), NULL, + "Invalid sensor[%#x]", sensor); - return NULL; + return static_cast(sensor)->get_vendor().c_str(); } API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege) { - /* - * 1. check parameter - * 2. if there is no sensor, return false + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!privilege, false, "Invalid parameter[%#x]", privilege); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + /* TODO: + * sensor_permission_t perm = static_cast(sensor)->get_permission(); + * *privilege = static_cast(perm); */ + *privilege = SENSOR_PRIVILEGE_PUBLIC; return true; } API bool sensord_get_min_range(sensor_t sensor, float *min_range) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!min_range, false, "Invalid parameter[%#x]", min_range); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *min_range = static_cast(sensor)->get_min_range(); return true; } API bool sensord_get_max_range(sensor_t sensor, float *max_range) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!max_range, false, "Invalid parameter[%#x]", max_range); + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *max_range = static_cast(sensor)->get_max_range(); return true; } API bool sensord_get_resolution(sensor_t sensor, float *resolution) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!resolution, false, "Invalid parameter[%#x]", resolution); + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *resolution = static_cast(sensor)->get_resolution(); return true; } API bool sensord_get_min_interval(sensor_t sensor, int *min_interval) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!min_interval, false, "Invalid parameter[%#x]", min_interval); + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *min_interval = static_cast(sensor)->get_min_interval(); return true; } API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!fifo_count, false, "Invalid parameter[%#x]", fifo_count); + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *fifo_count = 0; return true; } API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!max_batch_count, false, "Invalid parameter[%#x]", max_batch_count); + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + *max_batch_count = static_cast(sensor)->get_max_batch_count(); return true; } API bool sensord_is_wakeup_supported(sensor_t sensor) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + retvm_if(!manager.connect(), false, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); - return true; + return static_cast(sensor)->is_wakeup_supported(); } API int sensord_connect(sensor_t sensor) { - /* - * 1. check parameter - * 2. if there is no sensor, return -EPERM - * 3. sensor is already registered(sensor), it doesn't need to connect server - * 4. create integer handle for only this client - * 5. if it is first connection(client), get client id from server - * 6. if it is first connection(client), start sensor event listener - * 7. sensor initialization : stop, pause_all - * 8. if it is first connection(client), send cmd hello - * 9. if cmd hello is failed and it is first connection(client) stop listener, remove id - */ + retvm_if(!manager.connect(), -EIO, "Failed to connect"); + retvm_if(!manager.is_supported(sensor), -EINVAL, + "Invalid sensor[%#x]", sensor); - return 0; + sensor::sensor_listener *listener; + + listener = new(std::nothrow) sensor::sensor_listener(sensor); + retvm_if(!listener, -ENOMEM, "Failed to allocate memory"); + + listeners[listener->get_id()] = listener; + + return listener->get_id(); } API bool sensord_disconnect(int handle) { - /* - * 1. check parameter(check handle???) - * 2. check state of this handle - * 3. if it is on passive mode, unregister event and unset interval/latency - * 4. if it is not stop, stop it - * 5. if there is no active sensor(client), reset id & byebye and stop listener - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + retvm_if(!listener, false, "Invalid handle[%d]", handle); + + delete listener; + listeners.erase(handle); return true; } @@ -202,148 +288,270 @@ API bool sensord_disconnect(int handle) API bool sensord_register_event(int handle, unsigned int event_type, unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data) { - /* - * 1. check parameter - * 2. if interval is 0, default interval - * ** if cb is null, how to handle it? - * ** event type is deprecated - */ + sensor::sensor_listener *listener; + int prev_interval; + int prev_max_batch_latency; + sensor_event_handler *handler; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + prev_interval = listener->get_interval(); + prev_max_batch_latency = listener->get_max_batch_latency(); + + if (listener->set_interval(interval) < 0) { + _E("Failed to set interval"); + return false; + } + + if (listener->set_max_batch_latency(max_batch_latency) < 0) { + listener->set_interval(prev_interval); + _E("Failed to set max_batch_latency"); + return false; + } + + handler = new(std::nothrow) sensor_event_handler(listener->get_sensor(), cb, user_data); + if (!handler) { + listener->set_max_batch_latency(prev_max_batch_latency); + listener->set_interval(prev_interval); + _E("Failed to allocate memory"); + return false; + } + + listener->set_event_handler(handler); return true; } API bool sensord_unregister_event(int handle, unsigned int event_type) { - /* - * 1. check parameter - * 2. check previous interval, latency, cb, user_data - * 3. if passive mode is true, set false - * 4. if ret is false, register event - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + listener->unset_event_handler(); return true; } API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data) { - /* - * 1. check parameter - */ + sensor::sensor_listener *listener; + sensor_accuracy_handler *handler; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + handler = new(std::nothrow) sensor_accuracy_handler(listener->get_sensor(), cb, user_data); + retvm_if(!handler, false, "Failed to allocate memory"); + + listener->set_accuracy_handler(handler); return true; } API bool sensord_unregister_accuracy_cb(int handle) { - /* - * 1. check parameter - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + listener->unset_accuracy_handler(); return true; } API bool sensord_start(int handle, int option) { - /* - * 1. check parameter - * 2. pause = CONVERT_OPTION_PAUSE_POLICY(option) - * 3. start listener - */ + sensor::sensor_listener *listener; + int prev_pause; + int pause; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + pause = CONVERT_OPTION_PAUSE_POLICY(option); + prev_pause = listener->get_pause_policy(); + + if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) { + _E("Failed to set pause policy[%d]", pause); + return false; + } + + if (listener->start() < 0) { + listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause); + _E("Failed to start listener"); + return false; + } return true; } API bool sensord_stop(int handle) { - /* - * 1. check parameter - * 2. check sensor state, id - * 2.1. if sensor is already stopped, return true - * 3. stop listener - */ + int ret; + sensor::sensor_listener *listener; - return true; + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + ret = listener->stop(); + + if (ret == -EAGAIN || ret == OP_SUCCESS) + return true; + + return false; } API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval) { - /* - * 1. check parameter - * 2. if interval is 0, default interval - * 3. if previous interval is lower than interval, return true - * 4. change interval - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->set_interval(interval) < 0) { + _E("Failed to set interval to listener"); + return false; + } return true; } API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency) { - /* - * 1. check parameter - * 2. if previous interval is lower than interval, return true - * 3. change batch latency - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->set_max_batch_latency(max_batch_latency) < 0) { + _E("Failed to set max_batch_latency to listener"); + return false; + } return true; } API bool sensord_set_option(int handle, int option) { - /* - * change option, always-on/power save option/lcd off/default - */ + sensor::sensor_listener *listener; + int pause; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + pause = CONVERT_OPTION_PAUSE_POLICY(option); + + if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) { + _E("Failed to set option[%d(%d)] to listener", option, pause); + return false; + } return true; } API int sensord_set_attribute_int(int handle, int attribute, int value) { - /* - * 1. if ATTRIBUTE_PAUSE_POLICY - * 2. if ATTRIBUTE_AXIS_ORIENTATION - * 3. else attribute - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->set_attribute(attribute, value) < 0) { + _E("Failed to set attribute[%d, %d]", attribute, value); + return -EIO; + } return OP_SUCCESS; } API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len) { - /* - * 1. check parameter - * 2. if client id is invalid, return -EPERM - * 3. if there is other problems, return -EPERM - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->set_attribute(attribute, value, len) < 0) { + _E("Failed to set attribute[%d, %s]", attribute, value); + return -EIO; + } return OP_SUCCESS; } API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data) { - /* - * 1. check parameter - * 2. check sensor state(is it really needed?) - * 3. get data - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->get_sensor_data(sensor_data) < 0) { + _E("Failed to get sensor data from listener"); + return false; + } return true; } API bool sensord_flush(int handle) { - /* - * 1. check parameter - * 2. check sensor state(is it really needed?) - * 3. flush sensor - */ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->flush() < 0) { + _E("Failed to flush sensor"); + return false; + } return true; } API bool sensord_set_passive_mode(int handle, bool passive) { - /* set passive mode*/ + sensor::sensor_listener *listener; + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->set_passive_mode(passive) < 0) { + _E("Failed to set passive mode"); + return false; + } return true; } @@ -387,7 +595,12 @@ API bool sensord_external_post(int handle, unsigned long long timestamp, const f /* deperecated */ API sensor_t sensord_get_sensor(sensor_type_t type) { - return NULL; + sensor_t sensor; + + if (sensord_get_default_sensor(type, &sensor) < 0) + return NULL; + + return sensor; } /* deprecated */ @@ -417,10 +630,11 @@ API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event /* deprecated(BUT it is used in C-API....) */ API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported) { - /* - * 1. check parameter - * 2. if there is no sensor, return false - */ + if (!manager.is_supported(sensor)) + *supported = false; + else + *supported = true; + return true; } -- 2.7.4