tizen beta release
[framework/web/wrt-plugins-common.git] / src / modules / tizen / Accelerometer / Accelerometer.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file          Accelerometer.cpp
18  * @author      Qi Xiangguo (xiangguo.qi@samsung.com)
19  * @version     0.1
20  * @brief
21  */
22
23 #include <cassert>
24 #include <Accelerometer/EventGetCurrentAcceleration.h>
25 #include <Commons/Exception.h>
26 #include "Accelerometer.h"
27
28 using namespace DPL;
29
30 namespace WrtDeviceApis {
31 namespace Accelerometer {
32
33 using namespace Api;
34
35 namespace {
36 /**
37  * Callback method called by platform as interval time.
38  * @param event_type Platform accelerometer evet type
39  * @param event Platform sensor event data
40  * @param this_ User data pointer.
41  */
42 static void accelerationChangedCallback(unsigned int event_type,
43         sensor_event_data_t *event,
44         void *watcher_ptr)
45 {
46     LogDebug("Callback accelerationChangedCallback.");
47     if (watcher_ptr) {
48         if (event_type == ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME &&
49             event != NULL) {
50             ((Accelerometer::Watcher*)watcher_ptr)->accelerationHasChanged(
51                 event);
52         }
53     } else {
54         LogError("Callback private data is NULL.");
55     }
56 }
57 } //private namespace
58
59 Accelerometer::Accelerometer() :
60     m_handle(-1),
61     m_initialized(false),
62     m_isWatch(false)
63 {
64     LogDebug("Platform::Accelerometer Enter");
65 }
66
67 Accelerometer::~Accelerometer()
68 {
69     LogDebug("Platform::~Accelerometer Enter");
70
71     if (m_initialized == true) {
72         stop(m_handle);
73     }
74
75     LogDebug("All watchers : (" << m_watchers.size() << ")");
76     std::vector<WatcherPtr>::iterator it;
77     for (it = m_watchers.begin(); it != m_watchers.end(); ++it) {
78         stop((*it)->getHandle(), true);
79     }
80     m_watchers.clear();
81     LogDebug("All watchers were cleared. (" << m_watchers.size() << ")");
82 }
83
84 void Accelerometer::getCurrentAcceleration(
85         const EventGetCurrentAccelerationPtr& event)
86 {
87     if (m_initialized == false) {
88         m_handle = initialize();
89         start(m_handle);
90         m_initialized = true;
91     }
92     EventRequestReceiver<EventGetCurrentAcceleration>::PostRequest(event);
93 }
94
95 void Accelerometer::OnRequestReceived(
96         const EventGetCurrentAccelerationPtr& event)
97 {
98     LogDebug("Enter");
99     sensor_data_t data;
100     memset(&data, 0, sizeof(sensor_data_t));
101     /**
102        *Invoke platform API sf_get_data gets raw data from a sensor with connecting the sensor-server.
103      * The type of sensor is supplied and return data is stored in the output parameter values [].
104      */
105     if ((sf_get_data(m_handle, ACCELEROMETER_BASE_DATA_SET, &data) < 0) ||
106         (data.values_num < 3)) {
107         LogError("Can't get current Acceleration. ");
108         Throw(Commons::PlatformException);
109         return;
110     }
111     event->setXAxis(static_cast<double>(data.values[0]));
112     event->setYAxis(static_cast<double>(data.values[1]));
113     event->setZAxis(static_cast<double>(data.values[2]));
114 }
115
116 long Accelerometer::watchAcceleration(
117         const EventAccelerationChangedEmitterPtr& emitter,
118         long minNotificationInterval)
119 {
120     LogDebug("Enter");
121     int new_handle = initialize();
122
123     event_condition_t* condition = NULL;
124     event_condition_t conditionData;
125
126     if (minNotificationInterval > 0) {
127         conditionData.cond_op = CONDITION_EQUAL;
128         conditionData.cond_value1 = minNotificationInterval;
129         condition = &conditionData;
130     }
131
132     /**
133      * Invoke platform API sf_register_event registers a user defined callback function with a connected sensor for a particular event.
134      **This callback function will be called when there is a change in the state of respective sensor.
135      **cb_data will be the parameter used during the callback call.
136      **Callback interval can be adjusted using even_contion_t argument.
137      */
138
139     WatcherPtr watcher(new Watcher(new_handle, emitter));
140
141     int sensor_state = sf_register_event(
142             watcher->getHandle(),
143             ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME, condition,
144             accelerationChangedCallback, watcher.Get());
145     if (sensor_state < 0) {
146         stop(watcher->getHandle());
147         Throw(Commons::PlatformException);
148     }
149
150     start(watcher->getHandle());
151
152     m_isWatch = true;
153     m_watchers.push_back(watcher);
154     LogDebug("Watcher is added. (" << m_watchers.size() << ")");
155     watcher->getCurrentAccelerationForWatch();
156
157     return static_cast<long>(emitter->getId());
158 }
159
160 void Accelerometer::clearWatch(EventAccelerationChangedEmitter::IdType id)
161 {
162     LogDebug("Enter");
163
164     std::vector<WatcherPtr>::iterator it;
165     for (it = m_watchers.begin(); it != m_watchers.end(); ++it) {
166         if (id == (*it)->getEmitter()->getId()) {
167             stop((*it)->getHandle(), true);
168
169             m_watchers.erase(it);
170             LogDebug("Watcher is removed. (" << m_watchers.size() << ")");
171
172             if (m_watchers.size() == 0) {
173                 m_isWatch = false;
174             }
175             break;
176         }
177     }
178 }
179
180 void Accelerometer::getCurrentAccelerationForWatch(void)
181 {
182     LogDebug("Enter");
183     sensor_data_t data;
184     memset(&data, 0, sizeof(sensor_data_t));
185     if ((sf_get_data(m_handle, ACCELEROMETER_BASE_DATA_SET, &data) < 0) ||
186         (data.values_num < 3)) {
187         Throw(Commons::PlatformException);
188     }
189
190     EventAccelerationChangedPtr event(new EventAccelerationChanged());
191     AccelerationProperties props;
192     props.xAxis = static_cast<double>(data.values[0]);
193     props.yAxis = static_cast<double>(data.values[1]);
194     props.zAxis = static_cast<double>(data.values[2]);
195
196     event->setAccelerationProperties(props);
197
198     m_AccelerationEmitters.emit(event);
199 }
200
201 void Accelerometer::accelerationHasChanged(sensor_event_data_t *sensorEvent)
202 {
203     LogDebug("Enter");
204     sensor_data_t *sensor_data = NULL;
205     sensor_data = (sensor_data_t *)sensorEvent->event_data;
206     if (sensor_data == NULL ||
207         (sensor_data->values_num < 3)) {
208         LogError("Can't get current Acceleration. ");
209         Throw(Commons::PlatformException);
210         return;
211     }
212
213     EventAccelerationChangedPtr event(new EventAccelerationChanged());
214     AccelerationProperties props;
215     props.xAxis = static_cast<double>(sensor_data->values[0]);
216     props.yAxis = static_cast<double>(sensor_data->values[1]);
217     props.zAxis = static_cast<double>(sensor_data->values[2]);
218     LogDebug(
219         "xAxis:" << sensor_data->values[0] << ",yAxis:" <<
220         sensor_data->values[1] << ",zAxis:" << sensor_data->values[2]);
221
222     event->setAccelerationProperties(props);
223
224     m_AccelerationEmitters.emit(event);
225 }
226
227 int Accelerometer::initialize()
228 {
229     LogDebug("Enter");
230     DPL::Mutex::ScopedLock lock(&m_initializationMutex);
231     int handle = sf_connect(ACCELEROMETER_SENSOR);
232
233     if (handle < 0) {
234         LogError("Could not connect with accelerometer sensor.");
235         Throw(Commons::UnsupportedException);
236     }
237
238     return handle;
239 }
240
241 void Accelerometer::restart(int& handle)
242 {
243     stop(handle);
244     start(handle);
245 }
246
247 void Accelerometer::start(int handle)
248 {
249     LogDebug("Enter");
250     if (sf_start(handle, 0) < 0) {
251         LogError("Could not start communication with sensor.");
252         if (handle >= 0) {
253             sf_disconnect(handle);
254             Throw(Commons::UnsupportedException);
255         }
256     }
257 }
258
259 void Accelerometer::stop(int& handle,
260         bool isWatcherHandle)
261 {
262     LogDebug("Enter");
263
264     if (handle >= 0) {
265         if (isWatcherHandle == true) {
266             LogError("unregister event sensor.");
267             sf_unregister_event(handle,
268                                 ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
269         }
270         sf_stop(handle);
271         sf_disconnect(handle);
272         handle = -1;
273     }
274 }
275
276 //Watcher's
277 void Accelerometer::Watcher::getCurrentAccelerationForWatch()
278 {
279     LogDebug("Enter");
280     sensor_data_t data;
281     memset(&data, 0, sizeof(sensor_data_t));
282     if ((sf_get_data(m_handle, ACCELEROMETER_BASE_DATA_SET, &data) < 0) ||
283         (data.values_num < 3)) {
284         Throw(Commons::PlatformException);
285     }
286
287     EventAccelerationChangedPtr event(new EventAccelerationChanged());
288     AccelerationProperties props;
289     props.xAxis = static_cast<double>(data.values[0]);
290     props.yAxis = static_cast<double>(data.values[1]);
291     props.zAxis = static_cast<double>(data.values[2]);
292
293     event->setAccelerationProperties(props);
294
295     emit(event);
296 }
297
298 //Watcher's
299 void Accelerometer::Watcher::accelerationHasChanged(
300         sensor_event_data_t *sensorEvent)
301 {
302     LogDebug("Enter");
303     sensor_data_t *sensor_data = NULL;
304     sensor_data = (sensor_data_t *)sensorEvent->event_data;
305     if (sensor_data == NULL ||
306         (sensor_data->values_num < 3)) {
307         LogError("Can't get current Acceleration. ");
308         Throw(Commons::PlatformException);
309         return;
310     }
311
312     EventAccelerationChangedPtr event(new EventAccelerationChanged());
313     AccelerationProperties props;
314     props.xAxis = static_cast<double>(sensor_data->values[0]);
315     props.yAxis = static_cast<double>(sensor_data->values[1]);
316     props.zAxis = static_cast<double>(sensor_data->values[2]);
317     LogDebug(
318         "xAxis:" << sensor_data->values[0] << ",yAxis:" <<
319         sensor_data->values[1] << ",zAxis:" << sensor_data->values[2]);
320
321     event->setAccelerationProperties(props);
322
323     emit(event);
324 }
325
326 }
327 }