Merge "sensord: add the sensord plugin logic for flexibility" into devel/tizen_3.0
[platform/core/system/sensord.git] / src / server / plugins / 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 <sensor_logs.h>
30
31 #include <virtual_sensor.h>
32 #include <auto_rotation_sensor.h>
33 #include <sensor_loader.h>
34 #include <virtual_sensor_config.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 using std::string;
41 using std::vector;
42
43 #define SENSOR_NAME                                             "AUTO_ROTATION_SENSOR"
44 #define SENSOR_TYPE_AUTO_ROTATION               "AUTO_ROTATION"
45
46 #define MS_TO_US 1000
47
48 #define ELEMENT_NAME                                    "NAME"
49 #define ELEMENT_VENDOR                                  "VENDOR"
50 #define ELEMENT_RAW_DATA_UNIT                   "RAW_DATA_UNIT"
51 #define ELEMENT_DEFAULT_SAMPLING_TIME   "DEFAULT_SAMPLING_TIME"
52
53 #define AUTO_ROTATION_LIB                               "/usr/lib/sensord/libauto_rotation_sensor.so"
54
55 auto_rotation_sensor::auto_rotation_sensor()
56 : m_accel_sensor(NULL)
57 , m_alg(NULL)
58 , m_rotation(0)
59 , m_interval(1)
60 , m_rotation_time(1) // rotation state is valid from initial state, so set rotation time to non-zero value
61 , m_default_sampling_time(1)
62 {
63         virtual_sensor_config &config = virtual_sensor_config::get_instance();
64
65         if (!config.get(SENSOR_TYPE_AUTO_ROTATION, ELEMENT_VENDOR, m_vendor)) {
66                 _E("[VENDOR] is empty\n");
67                 throw ENXIO;
68         }
69
70         _I("m_vendor = %s", m_vendor.c_str());
71
72         if (!config.get(SENSOR_TYPE_AUTO_ROTATION, ELEMENT_RAW_DATA_UNIT, m_raw_data_unit)) {
73                 _E("[RAW_DATA_UNIT] is empty\n");
74                 throw ENXIO;
75         }
76
77         _I("m_raw_data_unit = %s", m_raw_data_unit.c_str());
78
79         if (!config.get(SENSOR_TYPE_AUTO_ROTATION, ELEMENT_DEFAULT_SAMPLING_TIME, &m_default_sampling_time)) {
80                 _E("[DEFAULT_SAMPLING_TIME] is empty\n");
81                 throw ENXIO;
82         }
83
84         _I("m_default_sampling_time = %d", m_default_sampling_time);
85
86         m_interval = m_default_sampling_time * MS_TO_US;
87 }
88
89 auto_rotation_sensor::~auto_rotation_sensor()
90 {
91         delete m_alg;
92
93         _I("auto_rotation_sensor is destroyed!\n");
94 }
95
96 bool auto_rotation_sensor::init(void)
97 {
98         m_accel_sensor = sensor_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR);
99
100         if (!m_accel_sensor) {
101                 _E("cannot load accel sensor_hal from %s", get_name());
102                 return false;
103         }
104
105         m_alg = get_alg();
106
107         if (!m_alg) {
108                 _E("Not supported AUTO ROTATION sensor");
109                 return false;
110         }
111
112         if (!m_alg->open())
113                 return false;
114
115         _I("%s is created!\n", get_name());
116
117         return true;
118 }
119
120 sensor_type_t auto_rotation_sensor::get_type(void)
121 {
122         return AUTO_ROTATION_SENSOR;
123 }
124
125 unsigned int auto_rotation_sensor::get_event_type(void)
126 {
127         return (AUTO_ROTATION_SENSOR << 16) | 0x0001;
128 }
129
130 const char* auto_rotation_sensor::get_name(void)
131 {
132         return SENSOR_NAME;
133 }
134
135 bool auto_rotation_sensor::get_sensor_info(sensor_info &info)
136 {
137         info.set_type(get_type());
138         info.set_id(get_id());
139         info.set_privilege(SENSOR_PRIVILEGE_PUBLIC); // FIXME
140         info.set_name("Auto Rotation Sensor");
141         info.set_vendor("Samsung Electronics");
142         info.set_min_range(AUTO_ROTATION_DEGREE_UNKNOWN);
143         info.set_max_range(AUTO_ROTATION_DEGREE_270);
144         info.set_resolution(1);
145         info.set_min_interval(1);
146         info.set_fifo_count(0);
147         info.set_max_batch_count(0);
148         info.set_supported_event(get_event_type());
149         info.set_wakeup_supported(false);
150
151         return true;
152 }
153
154 void auto_rotation_sensor::synthesize(const sensor_event_t& event)
155 {
156         if (event.event_type != ACCELEROMETER_RAW_DATA_EVENT)
157                 return;
158
159         int rotation;
160         float acc[3];
161         acc[0] = event.data->values[0];
162         acc[1] = event.data->values[1];
163         acc[2] = event.data->values[2];
164
165         if (!m_alg->get_rotation(acc, event.data->timestamp, m_rotation, rotation))
166                 return;
167
168         m_rotation = rotation;
169         m_rotation_time = event.data->timestamp;
170
171         sensor_event_t *rotation_event;
172         sensor_data_t *rotation_data;
173         int data_length;
174         int remains;
175
176         rotation_event = (sensor_event_t *)malloc(sizeof(sensor_event_t));
177         remains = get_data(&rotation_data, &data_length);
178
179         if (remains < 0)
180                 return;
181
182         rotation_event->sensor_id = get_id();
183         rotation_event->event_type = AUTO_ROTATION_CHANGE_STATE_EVENT;
184         rotation_event->data_length = data_length;
185         rotation_event->data = rotation_data;
186
187         push(rotation_event);
188
189         _D("Rotation: %d, ACC[0]: %f, ACC[1]: %f, ACC[2]: %f", rotation, event.data->values[0], event.data->values[1], event.data->values[2]);
190         return;
191 }
192
193 int auto_rotation_sensor::get_data(sensor_data_t **data, int *length)
194 {
195         /* if It is batch sensor, remains can be 2+ */
196         int remains = 1;
197
198         sensor_data_t *sensor_data;
199         sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
200
201         sensor_data->accuracy = SENSOR_ACCURACY_GOOD;
202         sensor_data->timestamp = m_rotation_time;
203         sensor_data->values[0] = m_rotation;
204         sensor_data->value_count = 1;
205
206         *data = sensor_data;
207         *length = sizeof(sensor_data_t);
208
209         return --remains;
210 }
211
212 bool auto_rotation_sensor::set_interval(unsigned long interval)
213 {
214         return false;
215 }
216
217 bool auto_rotation_sensor::set_batch_latency(unsigned long latency)
218 {
219         return false;
220 }
221
222 bool auto_rotation_sensor::set_wakeup(int wakeup)
223 {
224         return false;
225 }
226
227 bool auto_rotation_sensor::on_start(void)
228 {
229         m_rotation = AUTO_ROTATION_DEGREE_UNKNOWN;
230
231         m_alg->start();
232
233         m_accel_sensor->add_interval((intptr_t)this , (m_interval/MS_TO_US), true);
234         m_accel_sensor->start();
235
236         return activate();
237 }
238
239 bool auto_rotation_sensor::on_stop(void)
240 {
241         m_accel_sensor->delete_interval((intptr_t)this , true);
242         m_accel_sensor->stop();
243
244         return deactivate();
245 }
246
247 bool auto_rotation_sensor::check_lib(void)
248 {
249         if (access(AUTO_ROTATION_LIB, F_OK) < 0)
250                 return false;
251
252         return true;
253 }
254
255 auto_rotation_alg *auto_rotation_sensor::get_alg()
256 {
257         auto_rotation_alg *alg = new(std::nothrow) auto_rotation_alg_emul();
258         retvm_if(!alg, NULL, "Failed to allocate memory");
259
260         return alg;
261 }
262