Disable sensor part for sensor header change
[platform/core/uifw/dali-adaptor.git] / adaptors / tizen / tilt-sensor-impl-tizen.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
18 // CLASS HEADER
19 #include "tilt-sensor-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23 #ifdef SENSOR_ENABLED
24 #include <sensor_internal.h>
25 #endif
26
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/integration-api/debug.h>
29
30 // INTERNAL INCLUDES
31 #include <singleton-service-impl.h>
32
33 namespace // unnamed namespace
34 {
35
36 const char* const SIGNAL_TILTED = "tilted";
37
38 const int NUMBER_OF_SAMPLES = 10;
39
40 const float MAX_ACCELEROMETER_XY_VALUE = 9.8f;
41
42 // Type Registration
43 Dali::BaseHandle GetInstance()
44 {
45   return Dali::Internal::Adaptor::TiltSensor::Get();
46 }
47
48 Dali::TypeRegistration typeRegistration( typeid(Dali::TiltSensor), typeid(Dali::BaseHandle), GetInstance );
49
50 Dali::SignalConnectorType signalConnector1( typeRegistration, SIGNAL_TILTED, Dali::Internal::Adaptor::TiltSensor::DoConnectSignal );
51
52 } // unnamed namespace
53
54 namespace Dali
55 {
56
57 namespace Internal
58 {
59
60 namespace Adaptor
61 {
62
63 Dali::TiltSensor TiltSensor::New()
64 {
65   Dali::TiltSensor sensor = Dali::TiltSensor(new TiltSensor());
66
67   return sensor;
68 }
69
70 Dali::TiltSensor TiltSensor::Get()
71 {
72   Dali::TiltSensor sensor;
73
74   Dali::SingletonService service( SingletonService::Get() );
75   if ( service )
76   {
77     // Check whether the keyboard focus manager is already created
78     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::TiltSensor ) );
79     if(handle)
80     {
81       // If so, downcast the handle of singleton to keyboard focus manager
82       sensor = Dali::TiltSensor( dynamic_cast< TiltSensor* >( handle.GetObjectPtr() ) );
83     }
84     else
85     {
86       // Create a singleton instance
87       sensor = TiltSensor::New();
88       service.Register( typeid( sensor ), sensor );
89       handle = sensor;
90     }
91   }
92
93   return sensor;
94 }
95
96 TiltSensor::~TiltSensor()
97 {
98   Disable();
99 }
100
101 bool TiltSensor::Enable()
102 {
103   // Make sure sensor API is responding
104   bool success = Update();
105
106   if ( success )
107   {
108     if ( !mTimer )
109     {
110       mTimer = Dali::Timer::New( 1000.0f / mFrequencyHertz );
111       mTimer.TickSignal().Connect( mTimerSlot, &TiltSensor::Update );
112     }
113
114     if ( mTimer &&
115          !mTimer.IsRunning() )
116     {
117       mTimer.Start();
118     }
119   }
120
121   return success;
122 }
123
124 void TiltSensor::Disable()
125 {
126   if ( mTimer )
127   {
128     mTimer.Stop();
129     mTimer.Reset();
130   }
131 }
132
133 bool TiltSensor::IsEnabled() const
134 {
135   return ( mTimer && mTimer.IsRunning() );
136 }
137
138 float TiltSensor::GetRoll() const
139 {
140   return mRoll;
141 }
142
143 float TiltSensor::GetPitch() const
144 {
145   return mPitch;
146 }
147
148 Quaternion TiltSensor::GetRotation() const
149 {
150   return mRotation;
151 }
152
153 TiltSensor::TiltedSignalType& TiltSensor::TiltedSignal()
154 {
155   return mTiltedSignal;
156 }
157
158 void TiltSensor::SetUpdateFrequency( float frequencyHertz )
159 {
160   DALI_ASSERT_ALWAYS( frequencyHertz > 0.0f && "Frequency must have a positive value" );
161
162   if ( fabsf(mFrequencyHertz - frequencyHertz) >= GetRangedEpsilon(mFrequencyHertz, frequencyHertz) )
163   {
164     mFrequencyHertz = frequencyHertz;
165
166     if ( mTimer )
167     {
168       mTimer.SetInterval( 1000.0f / mFrequencyHertz );
169     }
170   }
171 }
172
173 float TiltSensor::GetUpdateFrequency() const
174 {
175   return mFrequencyHertz;
176 }
177
178 void TiltSensor::SetRotationThreshold(Radian rotationThreshold)
179 {
180   mRotationThreshold = rotationThreshold;
181 }
182
183 Radian TiltSensor::GetRotationThreshold() const
184 {
185   return mRotationThreshold;
186 }
187
188 bool TiltSensor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
189 {
190   bool connected( true );
191   TiltSensor* sensor = dynamic_cast<TiltSensor*>( object );
192
193   if( sensor && ( SIGNAL_TILTED == signalName ) )
194   {
195     sensor->TiltedSignal().Connect( tracker, functor );
196   }
197   else
198   {
199     // signalName does not match any signal
200     connected = false;
201   }
202
203   return connected;
204 }
205
206 TiltSensor::TiltSensor()
207 : mFrequencyHertz( Dali::TiltSensor::DEFAULT_UPDATE_FREQUENCY ),
208   mTimerSlot( this ),
209   mSensorFrameworkHandle( -1 ),
210   mRoll( 0.0f ),
211   mPitch( 0.0f ),
212   mRotation( 0.0f, Vector3::YAXIS ),
213   mRotationThreshold( 0.0f )
214 {
215   mRollValues.resize( NUMBER_OF_SAMPLES, 0.0f );
216   mPitchValues.resize( NUMBER_OF_SAMPLES, 0.0f );
217 }
218
219 bool TiltSensor::Update()
220 {
221   float newRoll = 0.0f;
222   float newPitch = 0.0f;
223   Quaternion newRotation;
224 #ifdef SENSOR_ENABLED
225
226   // Read accelerometer data
227
228   mSensorFrameworkHandle = sf_connect( ACCELEROMETER_SENSOR );
229   if ( mSensorFrameworkHandle < 0 )
230   {
231     DALI_LOG_ERROR( "Failed to connect to sensor framework" );
232     return false;
233   }
234
235   if ( sf_start(mSensorFrameworkHandle, 0) < 0 )
236   {
237     DALI_LOG_ERROR( "Failed to start sensor" );
238     sf_disconnect(mSensorFrameworkHandle);
239     return false;
240   }
241
242   sensor_data_t* base_data_values = (sensor_data_t*)malloc(sizeof(sensor_data_t));
243
244   int dataErr = sf_get_data(mSensorFrameworkHandle, ACCELEROMETER_BASE_DATA_SET, base_data_values);
245   if ( dataErr < 0 )
246   {
247     DALI_LOG_ERROR( "Failed to retrieve sensor data" );
248     free(base_data_values);
249     sf_stop(mSensorFrameworkHandle);
250     sf_disconnect(mSensorFrameworkHandle);
251     return false;
252   }
253
254   sf_stop(mSensorFrameworkHandle);
255   sf_disconnect(mSensorFrameworkHandle);
256
257   mRollValues.push_back( base_data_values->values[0] );
258   mRollValues.pop_front();
259
260   mPitchValues.push_back( base_data_values->values[1] );
261   mPitchValues.pop_front();
262
263   free(base_data_values);
264   base_data_values = NULL;
265
266   float averageRoll( 0.0f );
267   for ( std::deque<float>::const_iterator iter = mRollValues.begin(); mRollValues.end() != iter; ++iter )
268   {
269     averageRoll += *iter;
270   }
271   averageRoll /= mRollValues.size();
272
273   float averagePitch( 0.0f );
274   for ( std::deque<float>::const_iterator iter = mPitchValues.begin(); mPitchValues.end() != iter; ++iter )
275   {
276     averagePitch += *iter;
277   }
278   averagePitch /= mPitchValues.size();
279
280   newRoll  = Clamp( float(averageRoll  / MAX_ACCELEROMETER_XY_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
281   newPitch = Clamp( float(averagePitch / MAX_ACCELEROMETER_XY_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
282
283   newRotation = Quaternion( newRoll  * Math::PI * -0.5f, Vector3::YAXIS ) *
284               Quaternion( newPitch * Math::PI * -0.5f, Vector3::XAXIS );
285 #endif // SENSOR_ENABLED
286
287   Radian angle(Quaternion::AngleBetween(newRotation, mRotation));
288   // If the change in value is more than the threshold then emit tilted signal.
289   if( angle > mRotationThreshold )
290   {
291     mRoll = newRoll;
292     mPitch = newPitch;
293     mRotation = newRotation;
294
295     if ( !mTiltedSignal.Empty() )
296     {
297       Dali::TiltSensor handle( this );
298       mTiltedSignal.Emit( handle );
299     }
300   }
301
302   return true;
303 }
304
305 } // namespace Adaptor
306
307 } // namespace Internal
308
309 } // namespace Dali