1 // Copyright 2014 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/device_sensors/data_fetcher_impl_tizen.h"
7 #include "base/logging.h"
8 #include "base/memory/singleton.h"
9 #include "build/tizen_version.h"
13 static sensor_h sensor_orientation_;
14 static sensor_h sensor_accelerometer_;
15 static sensor_h sensor_gyroscope_;
16 static sensor_listener_h listener_orientation_;
17 static sensor_listener_h listener_accelerometer_;
18 static sensor_listener_h listener_gyroscope_;
20 DataFetcherImplTizen::DataFetcherImplTizen()
21 : device_motion_buffer_(NULL),
22 device_orientation_buffer_(NULL),
23 has_last_motion_data_(false),
24 last_motion_timestamp_(0),
25 is_orientation_buffer_ready_(false) {
26 sensor_get_default_sensor(SENSOR_ORIENTATION, &sensor_orientation_);
27 sensor_get_default_sensor(SENSOR_ACCELEROMETER, &sensor_accelerometer_);
28 sensor_get_default_sensor(SENSOR_GYROSCOPE, &sensor_gyroscope_);
30 sensor_create_listener(sensor_orientation_, &listener_orientation_);
31 sensor_create_listener(sensor_accelerometer_, &listener_accelerometer_);
32 sensor_create_listener(sensor_gyroscope_, &listener_gyroscope_);
35 DataFetcherImplTizen::~DataFetcherImplTizen() {
36 sensor_listener_unset_event_cb(listener_orientation_);
37 sensor_listener_stop(listener_orientation_);
38 sensor_destroy_listener(listener_orientation_);
40 sensor_listener_unset_event_cb(listener_accelerometer_);
41 sensor_listener_stop(listener_accelerometer_);
42 sensor_destroy_listener(listener_accelerometer_);
44 sensor_listener_stop(listener_gyroscope_);
45 sensor_destroy_listener(listener_gyroscope_);
48 DataFetcherImplTizen* DataFetcherImplTizen::GetInstance() {
49 return base::Singleton<DataFetcherImplTizen,
50 base::LeakySingletonTraits<DataFetcherImplTizen> >::get();
53 bool DataFetcherImplTizen::StartFetchingDeviceMotionData(
54 DeviceMotionHardwareBuffer* buffer) {
57 base::AutoLock autolock(motion_buffer_lock_);
58 device_motion_buffer_ = buffer;
60 sensor_listener_set_event_cb(listener_accelerometer_,
61 kInertialSensorIntervalMicroseconds / 1000,
62 DataFetcherImplTizen::onAccelerationChanged, this);
63 return Start(CONSUMER_TYPE_MOTION);
66 void DataFetcherImplTizen::StopFetchingDeviceMotionData() {
67 Stop(CONSUMER_TYPE_MOTION);
69 base::AutoLock autolock(motion_buffer_lock_);
70 if (device_motion_buffer_) {
71 sensor_listener_unset_event_cb(listener_accelerometer_);
72 device_motion_buffer_ = NULL;
77 bool DataFetcherImplTizen::StartFetchingDeviceOrientationData(
78 DeviceOrientationHardwareBuffer* buffer) {
81 base::AutoLock autolock(orientation_buffer_lock_);
82 device_orientation_buffer_ = buffer;
84 sensor_listener_set_event_cb(listener_orientation_,
85 kInertialSensorIntervalMicroseconds / 1000,
86 DataFetcherImplTizen::onOrientationChanged, this);
87 bool success = Start(CONSUMER_TYPE_ORIENTATION);
90 base::AutoLock autolock(orientation_buffer_lock_);
91 // If Start() was unsuccessful then set the buffer ready flag to true
92 // to start firing all-null events.
93 SetOrientationBufferReadyStatus(!success);
98 void DataFetcherImplTizen::StopFetchingDeviceOrientationData() {
99 Stop(CONSUMER_TYPE_ORIENTATION);
101 base::AutoLock autolock(orientation_buffer_lock_);
102 if (device_orientation_buffer_) {
103 SetOrientationBufferReadyStatus(false);
104 sensor_listener_unset_event_cb(listener_orientation_);
105 device_orientation_buffer_ = NULL;
110 bool DataFetcherImplTizen::Start(ConsumerType type) {
112 case CONSUMER_TYPE_ORIENTATION:
113 return (SENSOR_ERROR_NONE == sensor_listener_start(listener_orientation_));
114 case CONSUMER_TYPE_MOTION:
115 if (SENSOR_ERROR_NONE != sensor_listener_start(listener_accelerometer_)) {
118 return (SENSOR_ERROR_NONE == sensor_listener_start(listener_gyroscope_));
126 void DataFetcherImplTizen::Stop(ConsumerType type) {
128 case CONSUMER_TYPE_ORIENTATION:
129 sensor_listener_stop(listener_orientation_);
131 case CONSUMER_TYPE_MOTION:
132 sensor_listener_stop(listener_accelerometer_);
133 sensor_listener_stop(listener_gyroscope_);
134 memset(&last_motion_data_, 0, sizeof(last_motion_data_));
135 has_last_motion_data_ = false;
144 void DataFetcherImplTizen::onOrientationChanged(sensor_h sensor,
145 sensor_event_s *event, void* userData) {
146 DataFetcherImplTizen *fetcher = static_cast<DataFetcherImplTizen*>(userData);
147 base::AutoLock autolock(fetcher->orientation_buffer_lock_);
149 if (!fetcher->device_orientation_buffer_)
152 fetcher->device_orientation_buffer_->seqlock.WriteBegin();
154 float azimuth = event->values[0];
155 float pitch = event->values[1];
156 float roll = event->values[2];
158 fetcher->device_orientation_buffer_->data.alpha = azimuth;
159 fetcher->device_orientation_buffer_->data.hasAlpha = true;
160 fetcher->device_orientation_buffer_->data.beta = pitch;
161 fetcher->device_orientation_buffer_->data.hasBeta = true;
162 fetcher->device_orientation_buffer_->data.gamma = roll;
163 fetcher->device_orientation_buffer_->data.hasGamma = true;
164 fetcher->device_orientation_buffer_->seqlock.WriteEnd();
166 if (!fetcher->is_orientation_buffer_ready_)
167 fetcher->SetOrientationBufferReadyStatus(true);
171 void DataFetcherImplTizen::onAccelerationChanged(sensor_h sensor,
172 sensor_event_s *event, void* userData) {
173 DataFetcherImplTizen *self = static_cast<DataFetcherImplTizen*>(userData);
175 float x = event->values[0];
176 float y = event->values[1];
177 float z = event->values[2];
179 float gravityX = x * 0.2f;
180 float gravityY = y * 0.2f;
181 float gravityZ = z * 0.2f;
182 bool accelerationAvailable = false;
184 unsigned long long timestamp = event->timestamp;
186 double interval = static_cast<double>(self->last_motion_timestamp_ ?
187 (timestamp - self->last_motion_timestamp_) / 1000 :
188 kInertialSensorIntervalMicroseconds / 1000);
189 self->last_motion_timestamp_ = timestamp;
191 if (self->has_last_motion_data_) {
192 const blink::WebDeviceMotionData* m = &self->last_motion_data_;
193 gravityX += (m->accelerationIncludingGravityX - m->accelerationX) * 0.8f;
194 gravityY += (m->accelerationIncludingGravityY - m->accelerationY) * 0.8f;
195 gravityZ += (m->accelerationIncludingGravityZ - m->accelerationZ) * 0.8f;
196 accelerationAvailable = true;
199 float alpha, beta, gamma;
200 bool rotationRateAvailable = false;
202 sensor_event_s event_gyroscope;
203 if (!sensor_listener_read_data(listener_gyroscope_, &event_gyroscope))
204 rotationRateAvailable = true;
206 alpha = event_gyroscope.values[0];
207 beta = event_gyroscope.values[1];
208 gamma = event_gyroscope.values[2];
210 self->device_motion_buffer_->seqlock.WriteBegin();
212 self->device_motion_buffer_->data.accelerationIncludingGravityX = x;
213 self->device_motion_buffer_->data.hasAccelerationIncludingGravityX = true;
214 self->device_motion_buffer_->data.accelerationIncludingGravityY = y;
215 self->device_motion_buffer_->data.hasAccelerationIncludingGravityY = true;
216 self->device_motion_buffer_->data.accelerationIncludingGravityZ = z;
217 self->device_motion_buffer_->data.hasAccelerationIncludingGravityZ = true;
219 self->device_motion_buffer_->data.accelerationX = x - gravityX;
220 self->device_motion_buffer_->data.hasAccelerationX = accelerationAvailable;
221 self->device_motion_buffer_->data.accelerationY = y - gravityY;
222 self->device_motion_buffer_->data.hasAccelerationY = accelerationAvailable;
223 self->device_motion_buffer_->data.accelerationZ = z - gravityZ;
224 self->device_motion_buffer_->data.hasAccelerationZ = accelerationAvailable;
226 self->device_motion_buffer_->data.rotationRateAlpha = alpha;
227 self->device_motion_buffer_->data.hasRotationRateAlpha = rotationRateAvailable;
228 self->device_motion_buffer_->data.rotationRateBeta = beta;
229 self->device_motion_buffer_->data.hasRotationRateBeta = rotationRateAvailable;
230 self->device_motion_buffer_->data.rotationRateGamma = gamma;
231 self->device_motion_buffer_->data.hasRotationRateGamma = rotationRateAvailable;
233 self->device_motion_buffer_->data.allAvailableSensorsAreActive =
234 (accelerationAvailable && rotationRateAvailable);
236 self->last_motion_data_ = self->device_motion_buffer_->data;
237 self->has_last_motion_data_ = true;
239 self->device_motion_buffer_->data.interval = interval;
241 self->device_motion_buffer_->seqlock.WriteEnd();
244 void DataFetcherImplTizen::SetOrientationBufferReadyStatus(bool ready) {
245 device_orientation_buffer_->seqlock.WriteBegin();
246 device_orientation_buffer_->data.absolute = ready;
247 device_orientation_buffer_->data.hasAbsolute = ready;
248 device_orientation_buffer_->data.allAvailableSensorsAreActive = ready;
249 device_orientation_buffer_->seqlock.WriteEnd();
250 is_orientation_buffer_ready_ = ready;
253 } // namespace content