2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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.
19 #include <tizen/tilt-sensor-impl.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/integration-api/debug.h>
27 #include <singleton-service-impl.h>
29 namespace // unnamed namespace
31 const char* const SIGNAL_TILTED = "tilted";
33 const float MAX_ORIENTATION_ROLL_VALUE = 90.f;
34 const float MAX_ORIENTATION_PITCH_VALUE = 180.f;
35 const float MAX_ACCELEROMETER_VALUE = 9.8f;
38 Dali::BaseHandle Create()
40 return Dali::Internal::Adaptor::TiltSensor::Get();
43 Dali::TypeRegistration typeRegistration( typeid(Dali::TiltSensor), typeid(Dali::BaseHandle), Create );
45 Dali::SignalConnectorType signalConnector1( typeRegistration, SIGNAL_TILTED, Dali::Internal::Adaptor::TiltSensor::DoConnectSignal );
47 } // unnamed namespace
59 static void sensor_changed_cb (sensor_h sensor, sensor_event_s *event, void *user_data)
61 TiltSensor* tiltSensor = reinterpret_cast< TiltSensor* >( user_data );
65 tiltSensor->Update(event);
71 static std::string get_sensor_error_string(int errorValue)
77 case SENSOR_ERROR_IO_ERROR:
78 ret = "SENSOR_ERROR_IO_ERROR";
80 case SENSOR_ERROR_INVALID_PARAMETER:
81 ret = "SENSOR_ERROR_INVALID_PARAMETER";
83 case SENSOR_ERROR_NOT_SUPPORTED:
84 ret = "SENSOR_ERROR_NOT_SUPPORTED";
86 case SENSOR_ERROR_PERMISSION_DENIED:
87 ret = "SENSOR_ERROR_PERMISSION_DENIED";
89 case SENSOR_ERROR_OUT_OF_MEMORY:
90 ret = "SENSOR_ERROR_OUT_OF_MEMORY";
92 case SENSOR_ERROR_NOT_NEED_CALIBRATION:
93 ret = "SENSOR_ERROR_NOT_NEED_CALIBRATION";
95 case SENSOR_ERROR_OPERATION_FAILED:
96 ret = "SENSOR_ERROR_OPERATION_FAILED";
104 Dali::TiltSensor TiltSensor::New()
106 Dali::TiltSensor sensor = Dali::TiltSensor(new TiltSensor());
111 Dali::TiltSensor TiltSensor::Get()
113 Dali::TiltSensor sensor;
115 Dali::SingletonService service( SingletonService::Get() );
119 // Check whether the keyboard focus manager is already created
120 Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::TiltSensor ) );
123 // If so, downcast the handle of singleton to keyboard focus manager
124 sensor = Dali::TiltSensor( dynamic_cast< TiltSensor* >( handle.GetObjectPtr() ) );
128 // Create a singleton instance
129 sensor = TiltSensor::New();
130 service.Register( typeid( sensor ), sensor );
138 TiltSensor::~TiltSensor()
143 bool TiltSensor::Connect()
145 #ifdef SENSOR_ENABLED
146 if(mState != DISCONNECTED)
152 const int interval = 1000/mFrequencyHertz;
155 bool isSupported = false;
157 // try to use Orientation sensor at first for less power consumption.
158 ret = sensor_is_supported(SENSOR_ORIENTATION, &isSupported);
162 DALI_LOG_ERROR("sensor_is_supported() failed : %s\n", get_sensor_error_string(ret).c_str());
166 if(isSupported == true)
168 mSensorType = SENSOR_ORIENTATION;
172 DALI_LOG_ERROR("sensor does not support SENSOR_ORIENTATION\n");
174 ret = sensor_is_supported(SENSOR_ACCELEROMETER, &isSupported);
178 DALI_LOG_ERROR("sensor_is_supported() failed : %s\n", get_sensor_error_string(ret).c_str());
182 if(isSupported == false)
184 DALI_LOG_ERROR("sensor does not support both SENSOR_ORIENTATION and SENSOR_ACCELEROMETER\n");
188 mSensorType = SENSOR_ACCELEROMETER;
191 ret = sensor_get_default_sensor(mSensorType, &mSensor); /* mSensor should not be deleted */
195 DALI_LOG_ERROR("sensor_get_default_sensor() failed : %s\n", get_sensor_error_string(ret).c_str());
199 sensor_create_listener(mSensor, &mSensorListener);
200 sensor_listener_set_event_cb(mSensorListener, interval, sensor_changed_cb, this);
201 sensor_listener_set_interval(mSensorListener, interval);
203 sensor_listener_set_option(mSensorListener, SENSOR_OPTION_DEFAULT /* Not receive data when LCD is off and in power save mode */);
213 void TiltSensor::Disconnect()
217 if(mState == STARTED)
222 if(mState == STOPPED || mState == CONNECTED)
224 #ifdef SENSOR_ENABLED
225 sensor_listener_unset_event_cb(mSensorListener);
226 sensor_listener_stop(mSensorListener);
227 sensor_destroy_listener(mSensorListener);
230 mSensorListener = NULL;
231 mState = DISCONNECTED;
236 bool TiltSensor::Start()
238 if( mSensorListener && ( mState == CONNECTED || mState == STOPPED ) )
240 #ifdef SENSOR_ENABLED
242 ret = sensor_listener_start(mSensorListener);
243 if(ret != SENSOR_ERROR_NONE)
245 DALI_LOG_ERROR("sensor_listener_start() failed : %s\n", get_sensor_error_string(ret).c_str());
256 if( mState == STARTED )
258 DALI_LOG_ERROR("TiltSensor is already started. Current state [%d]\n", mState);
262 // mState is DISCONNECTED
263 DALI_LOG_ERROR("TiltSensor is disconnected. Current state [%d]\n", mState);
270 void TiltSensor::Stop()
272 #ifdef SENSOR_ENABLED
273 if(mSensorListener && mState == STARTED)
275 sensor_listener_stop( mSensorListener );
281 bool TiltSensor::IsStarted() const
283 return ( mSensorListener && mState == STARTED );
286 float TiltSensor::GetRoll() const
291 float TiltSensor::GetPitch() const
296 Quaternion TiltSensor::GetRotation() const
301 TiltSensor::TiltedSignalType& TiltSensor::TiltedSignal()
303 return mTiltedSignal;
306 void TiltSensor::SetUpdateFrequency( float frequencyHertz )
308 DALI_ASSERT_ALWAYS( frequencyHertz > 0.0f && "Frequency must have a positive value" );
310 if ( fabsf(mFrequencyHertz - frequencyHertz) >= GetRangedEpsilon(mFrequencyHertz, frequencyHertz) )
312 mFrequencyHertz = frequencyHertz;
314 #ifdef SENSOR_ENABLED
317 const int interval = 1000/mFrequencyHertz;
318 sensor_listener_set_interval(mSensorListener, interval);
324 float TiltSensor::GetUpdateFrequency() const
326 return mFrequencyHertz;
329 void TiltSensor::SetRotationThreshold(Radian rotationThreshold)
331 mRotationThreshold = rotationThreshold;
334 Radian TiltSensor::GetRotationThreshold() const
336 return mRotationThreshold;
339 bool TiltSensor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
341 bool connected( true );
342 TiltSensor* sensor = dynamic_cast<TiltSensor*>( object );
344 if( sensor && SIGNAL_TILTED == signalName )
346 sensor->TiltedSignal().Connect( tracker, functor );
350 // signalName does not match any signal
357 TiltSensor::TiltSensor()
358 : mState(DISCONNECTED),
359 mFrequencyHertz( Dali::TiltSensor::DEFAULT_UPDATE_FREQUENCY ),
361 mSensorListener( NULL ),
364 mRotation( Radian(0.0f), Vector3::YAXIS ),
365 mRotationThreshold( 0.0f )
371 #ifdef SENSOR_ENABLED
372 void TiltSensor::Update(sensor_event_s *event)
374 Radian newRoll( 0.0f );
375 Radian newPitch( 0.0f );
376 Quaternion newRotation;
378 if(mSensorType == SENSOR_ORIENTATION)
380 newRoll = Clamp( float(event->values[2] / MAX_ORIENTATION_ROLL_VALUE) /* -90 < roll < 90 */, -1.0f/*min*/, 1.0f/*max*/ );
381 newPitch = Clamp( float(event->values[1] / MAX_ORIENTATION_PITCH_VALUE) /* -180 < pitch < 180 */, -1.0f/*min*/, 1.0f/*max*/ );
383 else if(mSensorType == SENSOR_ACCELEROMETER)
385 newRoll = Clamp( float(event->values[0] / MAX_ACCELEROMETER_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
386 newPitch = Clamp( float(event->values[1] / MAX_ACCELEROMETER_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
390 DALI_LOG_ERROR("Invalid sensor type\n");
394 newRotation = Quaternion( Radian( newRoll * Math::PI * -0.5f ), Vector3::YAXIS ) *
395 Quaternion( Radian( newPitch * Math::PI * -0.5f ), Vector3::XAXIS );
397 Radian angle(Quaternion::AngleBetween(newRotation, mRotation));
399 // If the change in value is more than the threshold then emit tilted signal.
400 if( angle >= mRotationThreshold )
404 mRotation = newRotation;
407 if ( !mTiltedSignal.Empty() )
409 Dali::TiltSensor handle( this );
410 mTiltedSignal.Emit( handle );
414 #endif // SENSOR_ENABLED
416 } // namespace Adaptor
418 } // namespace Internal