Removing redundant accelerometer events
[platform/core/system/sensord.git] / src / auto_rotation / auto_rotation_sensor.cpp
1 /*
2  * sensord
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 <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <math.h>
25 #include <time.h>
26 #include <sys/types.h>
27 #include <dlfcn.h>
28
29 #include <common.h>
30 #include <sf_common.h>
31
32 #include <virtual_sensor.h>
33 #include <auto_rotation_sensor.h>
34 #include <sensor_plugin_loader.h>
35 #include <auto_rotation_alg.h>
36 #include <auto_rotation_alg_emul.h>
37
38 using std::bind1st;
39 using std::mem_fun;
40
41 #define SENSOR_NAME "AUTO_ROTATION_SENSOR"
42 #define AUTO_ROTATION_LIB "/usr/lib/sensord/libauto-rotation.so"
43
44 auto_rotation_sensor::auto_rotation_sensor()
45 : m_accel_sensor(NULL)
46 , m_rotation(0)
47 , m_rotation_time(1) // rotation state is valid from initial state, so set rotation time to non-zero value
48 , m_alg(NULL)
49 {
50         m_name = string(SENSOR_NAME);
51
52         register_supported_event(AUTO_ROTATION_EVENT_CHANGE_STATE);
53 }
54
55 auto_rotation_sensor::~auto_rotation_sensor()
56 {
57         delete m_alg;
58
59         INFO("auto_rotation_sensor is destroyed!\n");
60 }
61
62 bool auto_rotation_sensor::check_lib(void)
63 {
64         if (access(AUTO_ROTATION_LIB, F_OK) < 0)
65                 return false;
66
67         return true;
68 }
69
70 auto_rotation_alg *auto_rotation_sensor::get_alg()
71 {
72         return new auto_rotation_alg_emul();
73 }
74
75 bool auto_rotation_sensor::init()
76 {
77         m_accel_sensor = sensor_plugin_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR);
78
79         if (!m_accel_sensor) {
80                 ERR("cannot load accel sensor_hal[%s]", sensor_base::get_name());
81                 return false;
82         }
83
84         m_alg = get_alg();
85
86         if (!m_alg) {
87                 ERR("Not supported AUTO ROTATION sensor");
88                 return false;
89         }
90
91         if (!m_alg->open())
92                 return false;
93
94         set_privilege(SENSOR_PRIVILEGE_INTERNAL);
95
96         INFO("%s is created!\n", sensor_base::get_name());
97
98         return true;
99 }
100
101 sensor_type_t auto_rotation_sensor::get_type(void)
102 {
103         return AUTO_ROTATION_SENSOR;
104 }
105
106 bool auto_rotation_sensor::on_start(void)
107 {
108         const int SAMPLING_TIME = 60;
109         m_rotation = AUTO_ROTATION_DEGREE_UNKNOWN;
110
111         m_alg->start();
112
113         m_accel_sensor->add_client(ACCELEROMETER_RAW_DATA_EVENT);
114         m_accel_sensor->add_interval((int)this , SAMPLING_TIME, true);
115         m_accel_sensor->start();
116
117         return activate();
118 }
119
120 bool auto_rotation_sensor::on_stop(void)
121 {
122         m_accel_sensor->delete_client(ACCELEROMETER_RAW_DATA_EVENT);
123         m_accel_sensor->delete_interval((int)this , true);
124         m_accel_sensor->stop();
125
126         return deactivate();
127 }
128
129 void auto_rotation_sensor::synthesize(const sensor_event_t& event, vector<sensor_event_t> &outs)
130 {
131         AUTOLOCK(m_mutex);
132
133         if (event.event_type == ACCELEROMETER_RAW_DATA_EVENT) {
134                 int rotation;
135                 float acc[3];
136                 acc[0] = event.data.values[0];
137                 acc[1] = event.data.values[1];
138                 acc[2] = event.data.values[2];
139
140                 if (!m_alg->get_rotation(acc, event.data.timestamp, m_rotation, rotation))
141                         return;
142
143                 AUTOLOCK(m_value_mutex);
144                 sensor_event_t rotation_event;
145
146                 INFO("Rotation: %d, ACC[0]: %f, ACC[1]: %f, ACC[2]: %f", rotation, event.data.values[0], event.data.values[1], event.data.values[2]);
147                 rotation_event.sensor_id = get_id();
148                 rotation_event.data.accuracy = SENSOR_ACCURACY_GOOD;
149                 rotation_event.event_type = AUTO_ROTATION_EVENT_CHANGE_STATE;
150                 rotation_event.data.timestamp = event.data.timestamp;
151                 rotation_event.data.values[0] = rotation;
152                 rotation_event.data.value_count = 1;
153                 outs.push_back(rotation_event);
154                 m_rotation = rotation;
155                 m_rotation_time = event.data.timestamp;
156
157                 return;
158         }
159         return;
160 }
161
162 int auto_rotation_sensor::get_sensor_data(unsigned int data_id, sensor_data_t &data)
163 {
164         if (data_id != AUTO_ROTATION_BASE_DATA_SET)
165                 return -1;
166
167         AUTOLOCK(m_value_mutex);
168
169         data.accuracy = SENSOR_ACCURACY_GOOD;
170         data.timestamp = m_rotation_time;
171         data.values[0] = m_rotation;
172         data.value_count = 1;
173
174         return 0;
175 }
176
177 bool auto_rotation_sensor::get_properties(sensor_properties_t &properties)
178 {
179         properties.name = "Auto Rotation Sensor";
180         properties.vendor = "Samsung Electronics";
181         properties.min_range = AUTO_ROTATION_DEGREE_UNKNOWN;
182         properties.max_range = AUTO_ROTATION_DEGREE_270;
183         properties.min_interval = 1;
184         properties.resolution = 1;
185         properties.fifo_count = 0;
186         properties.max_batch_count = 0;
187
188         return true;
189 }
190
191 extern "C" sensor_module* create(void)
192 {
193         auto_rotation_sensor *sensor;
194
195         try {
196                 sensor = new(std::nothrow) auto_rotation_sensor;
197         } catch (int err) {
198                 ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
199                 return NULL;
200         }
201
202         sensor_module *module = new(std::nothrow) sensor_module;
203         retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
204
205         module->sensors.push_back(sensor);
206         return module;
207 }