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