2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file Orientation.cpp
18 * @author Qi Xiangguo (xiangguo.qi@samsung.com)
24 #include <Orientation/EventGetCurrentOrientation.h>
25 #include <Commons/Exception.h>
26 #include "Orientation.h"
30 namespace WrtDeviceApis {
31 namespace Orientation {
37 * Callback method called by platform as interval time.
38 * @param event_type Platform orientation evet type
39 * @param event Platform sensor event data
40 * @param this_ User data pointer.
42 static void OrientationChangedCallback(unsigned int event_type,
43 sensor_event_data_t *event,
46 LogDebug("Callback OrientationChangedCallback.");
48 if (event_type == GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME &&
50 ((Orientation::Watcher*)watcher_ptr)->orientationHasChanged(event);
53 LogError("Callback private data is NULL.");
58 Orientation::Orientation() :
63 LogDebug("Platform::Orientation Enter");
66 Orientation::~Orientation()
70 if (m_initialized == true) {
74 LogDebug("All watchers : (" << m_watchers.size() << ")");
75 std::vector<WatcherPtr>::iterator it;
76 for (it = m_watchers.begin(); it != m_watchers.end(); ++it) {
77 stop((*it)->getHandle(), true);
80 LogDebug("All watchers were cleared. (" << m_watchers.size() << ")");
83 void Orientation::getCurrentOrientation(
84 const EventGetCurrentOrientationPtr& event)
88 if (m_initialized == false) {
89 m_handle = initialize();
93 EventRequestReceiver<EventGetCurrentOrientation>::PostRequest(event);
96 void Orientation::OnRequestReceived(const EventGetCurrentOrientationPtr& event)
100 memset(&data, 0, sizeof(sensor_data_t));
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 [].
105 if ((sf_get_data(m_handle, GEOMAGNETIC_BASE_DATA_SET, &data) < 0) ||
106 (data.values_num < 3)) {
107 LogError("Can't get current Orientation. ");
108 Throw(Commons::PlatformException);
111 event->setAlpha(static_cast<double>(data.values[0]));
112 event->setBeta(static_cast<double>(data.values[1]));
113 event->setGamma(static_cast<double>(data.values[2]));
116 long Orientation::watchOrientation(
117 const EventOrientationChangedEmitterPtr& emitter,
118 long minNotificationInterval)
121 int new_handle = initialize();
122 int sensor_state = 0;
123 event_condition_t condition;
124 condition.cond_op = CONDITION_EQUAL;
125 condition.cond_value1 = minNotificationInterval;
127 * Invoke platform API sf_register_event registers a user defined callback function with a connected sensor for a particular event.
128 **This callback function will be called when there is a change in the state of respective sensor.
129 **cb_data will be the parameter used during the callback call.
130 **Callback interval can be adjusted using even_contion_t argument.
132 WatcherPtr watcher(new Watcher(new_handle, emitter));
134 sensor_state = sf_register_event(
135 watcher->getHandle(),
136 GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME, &condition,
137 OrientationChangedCallback, watcher.Get());
138 if (sensor_state < 0) {
139 stop(watcher->getHandle());
140 Throw(Commons::PlatformException);
143 start(watcher->getHandle());
144 m_watchers.push_back(watcher);
145 watcher->getCurrentOrientationForWatch();
146 return static_cast<long>(emitter->getId());
149 void Orientation::clearWatch(EventOrientationChangedEmitter::IdType id)
153 std::vector<WatcherPtr>::iterator it;
154 for (it = m_watchers.begin(); it != m_watchers.end(); ++it) {
155 if (id == (*it)->getEmitter()->getId()) {
156 stop((*it)->getHandle(), true);
158 m_watchers.erase(it);
159 LogDebug("Watcher is removed. (" << m_watchers.size() << ")");
161 if (m_watchers.size() == 0) {
169 void Orientation::OrientationHasChanged(sensor_event_data_t *sensorEvent)
173 sensor_data_t *sensor_data = NULL;
174 sensor_data = (sensor_data_t *)sensorEvent->event_data;
175 if (sensor_data == NULL ||
176 (sensor_data->values_num < 3)) {
177 LogError("Can't get current Acceleration. ");
178 Throw(Commons::PlatformException);
182 EventOrientationChangedPtr event(new EventOrientationChanged());
183 OrientationProperties props;
184 props.alpha = static_cast<double>(sensor_data->values[0]);
185 props.beta = static_cast<double>(-(sensor_data->values[1]));
186 props.gamma = static_cast<double>(-(sensor_data->values[2]));
189 "alpha" << props.alpha << ",beta" << props.beta << ",gamma" <<
192 event->setOrientationProperties(props);
194 m_OrientationEmitters.emit(event);
197 void Orientation::getCurrentOrientationForWatch(void)
201 memset(&data, 0, sizeof(sensor_data_t));
202 if ((sf_get_data(m_handle, GEOMAGNETIC_BASE_DATA_SET, &data) < 0) ||
203 (data.values_num < 3)) {
204 Throw(Commons::PlatformException);
207 EventOrientationChangedPtr event(new EventOrientationChanged());
208 OrientationProperties props;
209 props.alpha = static_cast<double>(data.values[0]);
210 props.beta = static_cast<double>(-(data.values[1]));
211 props.gamma = static_cast<double>(-(data.values[2]));
213 event->setOrientationProperties(props);
215 m_OrientationEmitters.emit(event);
218 int Orientation::initialize()
221 DPL::Mutex::ScopedLock lock(&m_initializationMutex);
222 int handle = sf_connect(GEOMAGNETIC_SENSOR);
224 LogError("Could not connect with orientation sensor.");
225 Throw(Commons::UnsupportedException);
230 void Orientation::restart(int& handle)
236 void Orientation::start(int handle)
239 if (sf_start(handle, 0) < 0) {
240 LogError("Could not start communication with sensor.");
242 sf_disconnect(handle);
243 Throw(Commons::UnsupportedException);
246 // TODO: find the way to fix this
251 void Orientation::stop(int& handle,
252 bool isWatcherHandle)
257 if (isWatcherHandle == true) {
258 sf_unregister_event(handle,
259 GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME);
262 sf_disconnect(handle);
268 void Orientation::Watcher::getCurrentOrientationForWatch()
272 memset(&data, 0, sizeof(sensor_data_t));
273 if ((sf_get_data(m_handle, GEOMAGNETIC_BASE_DATA_SET, &data) < 0) ||
274 (data.values_num < 3)) {
275 Throw(Commons::PlatformException);
278 EventOrientationChangedPtr event(new EventOrientationChanged());
279 OrientationProperties props;
280 props.alpha = static_cast<double>(data.values[0]);
281 props.beta = static_cast<double>(data.values[1]);
282 props.gamma = static_cast<double>(data.values[2]);
284 event->setOrientationProperties(props);
290 void Orientation::Watcher::orientationHasChanged(
291 sensor_event_data_t *sensorEvent)
294 sensor_data_t *sensor_data = NULL;
295 sensor_data = (sensor_data_t *)sensorEvent->event_data;
296 if (sensor_data == NULL ||
297 (sensor_data->values_num < 3)) {
298 LogError("Can't get current Orientation. ");
299 Throw(Commons::PlatformException);
303 EventOrientationChangedPtr event(new EventOrientationChanged());
304 OrientationProperties props;
305 props.alpha = static_cast<double>(sensor_data->values[0]);
306 props.beta = static_cast<double>(sensor_data->values[1]);
307 props.gamma = static_cast<double>(sensor_data->values[2]);
309 "alpha:" << sensor_data->values[0] << ",beta:" <<
310 sensor_data->values[1] << ",gamma:" << sensor_data->values[2]);
312 event->setOrientationProperties(props);