95f5724a5f535b1642959262ab393e3479d09298
[platform/core/uifw/dali-adaptor.git] / adaptors / ubuntu / tilt-sensor-impl-ubuntu.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
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <singleton-service-impl.h>
29
30 namespace // unnamed namespace
31 {
32
33 const char* const SIGNAL_TILTED = "tilted";
34
35 const int NUMBER_OF_SAMPLES = 10;
36
37 const float MAX_ACCELEROMETER_XY_VALUE = 9.8f;
38
39 // Type Registration
40 Dali::BaseHandle GetInstance()
41 {
42   return Dali::Internal::Adaptor::TiltSensor::Get();
43 }
44
45 Dali::TypeRegistration typeRegistration( typeid(Dali::TiltSensor), typeid(Dali::BaseHandle), GetInstance );
46
47 Dali::SignalConnectorType signalConnector1( typeRegistration, SIGNAL_TILTED, Dali::Internal::Adaptor::TiltSensor::DoConnectSignal );
48
49 } // unnamed namespace
50
51 namespace Dali
52 {
53
54 namespace Internal
55 {
56
57 namespace Adaptor
58 {
59
60 Dali::TiltSensor TiltSensor::New()
61 {
62   Dali::TiltSensor sensor = Dali::TiltSensor(new TiltSensor());
63
64   return sensor;
65 }
66
67 Dali::TiltSensor TiltSensor::Get()
68 {
69   Dali::TiltSensor sensor;
70
71   Dali::SingletonService service( SingletonService::Get() );
72   if ( service )
73   {
74     // Check whether the keyboard focus manager is already created
75     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::TiltSensor ) );
76     if(handle)
77     {
78       // If so, downcast the handle of singleton to keyboard focus manager
79       sensor = Dali::TiltSensor( dynamic_cast< TiltSensor* >( handle.GetObjectPtr() ) );
80     }
81     else
82     {
83       // Create a singleton instance
84       sensor = TiltSensor::New();
85       service.Register( typeid( sensor ), sensor );
86       handle = sensor;
87     }
88   }
89
90   return sensor;
91 }
92
93 TiltSensor::~TiltSensor()
94 {
95   Stop();
96 }
97
98 bool TiltSensor::Start()
99 {
100   // Make sure sensor API is responding
101   bool success = Update();
102
103   if ( success )
104   {
105     if ( !mTimer )
106     {
107       mTimer = Dali::Timer::New( 1000.0f / mFrequencyHertz );
108       mTimer.TickSignal().Connect( mTimerSlot, &TiltSensor::Update );
109     }
110
111     if ( mTimer &&
112          !mTimer.IsRunning() )
113     {
114       mTimer.Start();
115     }
116   }
117
118   return success;
119 }
120
121 void TiltSensor::Stop()
122 {
123   if ( mTimer )
124   {
125     mTimer.Stop();
126     mTimer.Reset();
127   }
128 }
129
130 bool TiltSensor::IsStarted() const
131 {
132   return ( mTimer && mTimer.IsRunning() );
133 }
134
135 float TiltSensor::GetRoll() const
136 {
137   return mRoll;
138 }
139
140 float TiltSensor::GetPitch() const
141 {
142   return mPitch;
143 }
144
145 Quaternion TiltSensor::GetRotation() const
146 {
147   return mRotation;
148 }
149
150 TiltSensor::TiltedSignalType& TiltSensor::TiltedSignal()
151 {
152   return mTiltedSignal;
153 }
154
155 void TiltSensor::SetUpdateFrequency( float frequencyHertz )
156 {
157   DALI_ASSERT_ALWAYS( frequencyHertz > 0.0f && "Frequency must have a positive value" );
158
159   if ( fabsf(mFrequencyHertz - frequencyHertz) >= GetRangedEpsilon(mFrequencyHertz, frequencyHertz) )
160   {
161     mFrequencyHertz = frequencyHertz;
162
163     if ( mTimer )
164     {
165       mTimer.SetInterval( 1000.0f / mFrequencyHertz );
166     }
167   }
168 }
169
170 float TiltSensor::GetUpdateFrequency() const
171 {
172   return mFrequencyHertz;
173 }
174
175 void TiltSensor::SetRotationThreshold(Radian rotationThreshold)
176 {
177   mRotationThreshold = rotationThreshold;
178 }
179
180 Radian TiltSensor::GetRotationThreshold() const
181 {
182   return mRotationThreshold;
183 }
184
185 bool TiltSensor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
186 {
187   bool connected( true );
188   TiltSensor* sensor = dynamic_cast<TiltSensor*>( object );
189
190   if( sensor && ( SIGNAL_TILTED == signalName ) )
191   {
192     sensor->TiltedSignal().Connect( tracker, functor );
193   }
194   else
195   {
196     // signalName does not match any signal
197     connected = false;
198   }
199
200   return connected;
201 }
202
203 TiltSensor::TiltSensor()
204 : mFrequencyHertz( Dali::TiltSensor::DEFAULT_UPDATE_FREQUENCY ),
205   mTimerSlot( this ),
206   mSensorFrameworkHandle( -1 ),
207   mRoll( 0.0f ),
208   mPitch( 0.0f ),
209   mRotation( Dali::ANGLE_0, Vector3::YAXIS ),
210   mRotationThreshold( 0.0f )
211 {
212   mRollValues.resize( NUMBER_OF_SAMPLES, 0.0f );
213   mPitchValues.resize( NUMBER_OF_SAMPLES, 0.0f );
214 }
215
216 bool TiltSensor::Update()
217 {
218   float newRoll = 0.0f;
219   float newPitch = 0.0f;
220   Quaternion newRotation;
221
222   Radian angle(Quaternion::AngleBetween(newRotation, mRotation));
223   // If the change in value is more than the threshold then emit tilted signal.
224   if( angle > mRotationThreshold )
225   {
226     mRoll = newRoll;
227     mPitch = newPitch;
228     mRotation = newRotation;
229
230     if ( !mTiltedSignal.Empty() )
231     {
232       Dali::TiltSensor handle( this );
233       mTiltedSignal.Emit( handle );
234     }
235   }
236
237   return true;
238 }
239
240 } // namespace Adaptor
241
242 } // namespace Internal
243
244 } // namespace Dali