sensord: fix to return approprivate error
[platform/core/system/sensord.git] / src / client / sensor_internal.cpp
index 0864b14..a0b683f 100644 (file)
  *
  */
 
-#include "sensor_internal.h"
-#include <stdlib.h>
+#include <sensor_internal.h>
+#include <sensor_internal_deprecated.h>
+#include <sensor_types.h>
+
+#include <channel_handler.h>
+#include <sensor_manager.h>
+#include <sensor_listener.h>
 #include <sensor_log.h>
+#include <unordered_map>
+
+#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_info *>(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<sensor_data_t *>(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_info *>(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<sensor_data_t *>(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<int, sensor::sensor_listener *> 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, -EINVAL, "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_info *>(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_info *>(sensor)->get_uri().c_str();
 }
 
 API const char* sensord_get_vendor(sensor_t sensor)
 {
-       /*
-        * 1. if there is no sensor, return NULL
-        */
-
-       return NULL;
-}
-
-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(), NULL, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), NULL,
+                       "Invalid sensor[%#x]", sensor);
 
-       return true;
+       return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
 }
 
 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_info *>(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_info *>(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_info *>(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_info *>(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_info *>(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_info *>(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 +272,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;
 }
@@ -356,7 +548,7 @@ API int sensord_external_connect(const char *key, sensor_external_command_cb_t c
         * 3. first connection(client)
         * 4. cmd_connect for external sensor with key
         */
-       retvm_if(!key, -EPERM, "Invalid key");
+       retvm_if(!key, -EINVAL, "Invalid key");
        return 0;
 }
 
@@ -387,7 +579,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 +614,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;
 }
 
@@ -436,3 +634,11 @@ API bool sensord_send_command(int handle, const char *command, int command_len)
        return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
 }
 
+/* deprecated */
+API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
+{
+       *privilege = SENSOR_PRIVILEGE_PUBLIC;
+
+       return true;
+}
+