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 <dali/internal/sensor/tizen/tilt-sensor-impl-tizen.h>
20 #include <dali/internal/sensor/common/tilt-sensor-factory.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/devel-api/common/singleton-service.h>
26 #include <dali/integration-api/debug.h>
28 namespace // unnamed namespace
30 const char* const SIGNAL_TILTED = "tilted";
32 const float MAX_ORIENTATION_ROLL_VALUE = 90.f;
33 const float MAX_ORIENTATION_PITCH_VALUE = 180.f;
34 const float MAX_ACCELEROMETER_VALUE = 9.8f;
37 Dali::BaseHandle Create()
39 return Dali::Internal::Adaptor::TiltSensorFactory::Get();
42 Dali::TypeRegistration typeRegistration( typeid(Dali::TiltSensor), typeid(Dali::BaseHandle), Create );
44 Dali::SignalConnectorType signalConnector1( typeRegistration, SIGNAL_TILTED, Dali::Internal::Adaptor::TiltSensor::DoConnectSignal );
46 } // unnamed namespace
58 static void sensor_changed_cb (sensor_h sensor, sensor_event_s *event, void *user_data)
60 TiltSensorTizen* tiltSensor = reinterpret_cast< TiltSensorTizen* >( user_data );
64 tiltSensor->Update(event);
70 static std::string get_sensor_error_string(int errorValue)
76 case SENSOR_ERROR_IO_ERROR:
77 ret = "SENSOR_ERROR_IO_ERROR";
79 case SENSOR_ERROR_INVALID_PARAMETER:
80 ret = "SENSOR_ERROR_INVALID_PARAMETER";
82 case SENSOR_ERROR_NOT_SUPPORTED:
83 ret = "SENSOR_ERROR_NOT_SUPPORTED";
85 case SENSOR_ERROR_PERMISSION_DENIED:
86 ret = "SENSOR_ERROR_PERMISSION_DENIED";
88 case SENSOR_ERROR_OUT_OF_MEMORY:
89 ret = "SENSOR_ERROR_OUT_OF_MEMORY";
91 case SENSOR_ERROR_NOT_NEED_CALIBRATION:
92 ret = "SENSOR_ERROR_NOT_NEED_CALIBRATION";
94 case SENSOR_ERROR_OPERATION_FAILED:
95 ret = "SENSOR_ERROR_OPERATION_FAILED";
103 TiltSensorTizen* TiltSensorTizen::New()
105 return new TiltSensorTizen();
108 TiltSensorTizen::~TiltSensorTizen()
113 bool TiltSensorTizen::Connect()
115 #ifdef SENSOR_ENABLED
116 if(mState != DISCONNECTED)
122 const int interval = 1000/mFrequencyHertz;
125 bool isSupported = false;
127 // try to use Orientation sensor at first for less power consumption.
128 ret = sensor_is_supported(SENSOR_ORIENTATION, &isSupported);
132 DALI_LOG_ERROR("sensor_is_supported() failed : %s\n", get_sensor_error_string(ret).c_str());
136 if(isSupported == true)
138 mSensorType = SENSOR_ORIENTATION;
142 DALI_LOG_ERROR("sensor does not support SENSOR_ORIENTATION\n");
144 ret = sensor_is_supported(SENSOR_ACCELEROMETER, &isSupported);
148 DALI_LOG_ERROR("sensor_is_supported() failed : %s\n", get_sensor_error_string(ret).c_str());
152 if(isSupported == false)
154 DALI_LOG_ERROR("sensor does not support both SENSOR_ORIENTATION and SENSOR_ACCELEROMETER\n");
158 mSensorType = SENSOR_ACCELEROMETER;
161 ret = sensor_get_default_sensor(mSensorType, &mSensor); /* mSensor should not be deleted */
165 DALI_LOG_ERROR("sensor_get_default_sensor() failed : %s\n", get_sensor_error_string(ret).c_str());
169 ret = sensor_create_listener(mSensor, &mSensorListener);
173 DALI_LOG_ERROR("sensor_create_listener() failed : %s\n", get_sensor_error_string(ret).c_str());
177 sensor_listener_set_event_cb(mSensorListener, interval, sensor_changed_cb, this);
178 sensor_listener_set_interval(mSensorListener, interval);
180 sensor_listener_set_option(mSensorListener, SENSOR_OPTION_DEFAULT /* Not receive data when LCD is off and in power save mode */);
190 void TiltSensorTizen::Disconnect()
194 if(mState == STARTED)
199 if(mState == STOPPED || mState == CONNECTED)
201 #ifdef SENSOR_ENABLED
202 sensor_listener_unset_event_cb(mSensorListener);
203 sensor_listener_stop(mSensorListener);
204 sensor_destroy_listener(mSensorListener);
207 mSensorListener = NULL;
208 mState = DISCONNECTED;
213 bool TiltSensorTizen::Start()
215 if( mSensorListener && ( mState == CONNECTED || mState == STOPPED ) )
217 #ifdef SENSOR_ENABLED
219 ret = sensor_listener_start(mSensorListener);
220 if(ret != SENSOR_ERROR_NONE)
222 DALI_LOG_ERROR("sensor_listener_start() failed : %s\n", get_sensor_error_string(ret).c_str());
233 if( mState == STARTED )
235 DALI_LOG_ERROR("TiltSensor is already started. Current state [%d]\n", mState);
239 // mState is DISCONNECTED
240 DALI_LOG_ERROR("TiltSensor is disconnected. Current state [%d]\n", mState);
247 void TiltSensorTizen::Stop()
249 #ifdef SENSOR_ENABLED
250 if(mSensorListener && mState == STARTED)
252 sensor_listener_stop( mSensorListener );
258 bool TiltSensorTizen::IsStarted() const
260 return ( mSensorListener && mState == STARTED );
263 float TiltSensorTizen::GetRoll() const
268 float TiltSensorTizen::GetPitch() const
273 Quaternion TiltSensorTizen::GetRotation() const
278 TiltSensor::TiltedSignalType& TiltSensorTizen::TiltedSignal()
280 return mTiltedSignal;
283 void TiltSensorTizen::SetUpdateFrequency( float frequencyHertz )
285 DALI_ASSERT_ALWAYS( frequencyHertz > 0.0f && "Frequency must have a positive value" );
287 if ( fabsf(mFrequencyHertz - frequencyHertz) >= GetRangedEpsilon(mFrequencyHertz, frequencyHertz) )
289 mFrequencyHertz = frequencyHertz;
291 #ifdef SENSOR_ENABLED
294 const int interval = 1000/mFrequencyHertz;
295 sensor_listener_set_interval(mSensorListener, interval);
301 float TiltSensorTizen::GetUpdateFrequency() const
303 return mFrequencyHertz;
306 void TiltSensorTizen::SetRotationThreshold(Radian rotationThreshold)
308 mRotationThreshold = rotationThreshold;
311 Radian TiltSensorTizen::GetRotationThreshold() const
313 return mRotationThreshold;
316 bool TiltSensorTizen::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
318 bool connected( true );
319 TiltSensor* sensor = dynamic_cast<TiltSensor*>( object );
321 if( sensor && SIGNAL_TILTED == signalName )
323 sensor->TiltedSignal().Connect( tracker, functor );
327 // signalName does not match any signal
334 TiltSensorTizen::TiltSensorTizen()
335 : mState(DISCONNECTED),
336 mFrequencyHertz( Dali::TiltSensor::DEFAULT_UPDATE_FREQUENCY ),
338 mSensorListener( NULL ),
341 mRotation( Radian(0.0f), Vector3::YAXIS ),
342 mRotationThreshold( 0.0f )
348 #ifdef SENSOR_ENABLED
349 void TiltSensorTizen::Update(sensor_event_s *event)
351 Radian newRoll( 0.0f );
352 Radian newPitch( 0.0f );
353 Quaternion newRotation;
355 if(mSensorType == SENSOR_ORIENTATION)
357 newRoll = Clamp( float(event->values[2] / MAX_ORIENTATION_ROLL_VALUE) /* -90 < roll < 90 */, -1.0f/*min*/, 1.0f/*max*/ );
358 newPitch = Clamp( float(event->values[1] / MAX_ORIENTATION_PITCH_VALUE) /* -180 < pitch < 180 */, -1.0f/*min*/, 1.0f/*max*/ );
360 else if(mSensorType == SENSOR_ACCELEROMETER)
362 newRoll = Clamp( float(event->values[0] / MAX_ACCELEROMETER_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
363 newPitch = Clamp( float(event->values[1] / MAX_ACCELEROMETER_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
367 DALI_LOG_ERROR("Invalid sensor type\n");
371 newRotation = Quaternion( Radian( newRoll * Math::PI * -0.5f ), Vector3::YAXIS ) *
372 Quaternion( Radian( newPitch * Math::PI * -0.5f ), Vector3::XAXIS );
374 Radian angle(Quaternion::AngleBetween(newRotation, mRotation));
376 // If the change in value is more than the threshold then emit tilted signal.
377 if( angle >= mRotationThreshold )
381 mRotation = newRotation;
384 if ( !mTiltedSignal.Empty() )
386 Dali::TiltSensor handle( this );
387 mTiltedSignal.Emit( handle );
391 #endif // SENSOR_ENABLED
393 } // namespace Adaptor
395 } // namespace Internal