/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
// CLASS HEADER
-#include "tilt-sensor-impl.h"
+#include <tizen/tilt-sensor-impl.h>
// EXTERNAL INCLUDES
#include <cmath>
-#ifdef DALI_PROFILE_LITE
-#include <sensor_internal.h>
-#else
-#include <sensor.h>
-#endif
-
#include <dali/public-api/object/type-registry.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
#include <singleton-service-impl.h>
-#ifdef __arm__
-#define SENSOR_ENABLED
-#endif
-
namespace // unnamed namespace
{
-
const char* const SIGNAL_TILTED = "tilted";
-const int NUMBER_OF_SAMPLES = 10;
-
-const float MAX_ACCELEROMETER_XY_VALUE = 9.8f;
+const float MAX_ORIENTATION_ROLL_VALUE = 90.f;
+const float MAX_ORIENTATION_PITCH_VALUE = 180.f;
+const float MAX_ACCELEROMETER_VALUE = 9.8f;
// Type Registration
-Dali::BaseHandle GetInstance()
+Dali::BaseHandle Create()
{
return Dali::Internal::Adaptor::TiltSensor::Get();
}
-Dali::TypeRegistration typeRegistration( typeid(Dali::TiltSensor), typeid(Dali::BaseHandle), GetInstance );
+Dali::TypeRegistration typeRegistration( typeid(Dali::TiltSensor), typeid(Dali::BaseHandle), Create );
Dali::SignalConnectorType signalConnector1( typeRegistration, SIGNAL_TILTED, Dali::Internal::Adaptor::TiltSensor::DoConnectSignal );
namespace Adaptor
{
+#ifdef SENSOR_ENABLED
+static void sensor_changed_cb (sensor_h sensor, sensor_event_s *event, void *user_data)
+{
+ TiltSensor* tiltSensor = reinterpret_cast< TiltSensor* >( user_data );
+
+ if(tiltSensor)
+ {
+ tiltSensor->Update(event);
+ }
+
+ return;
+}
+
+static std::string get_sensor_error_string(int errorValue)
+{
+ std::string ret;
+
+ switch(errorValue)
+ {
+ case SENSOR_ERROR_IO_ERROR:
+ ret = "SENSOR_ERROR_IO_ERROR";
+ break;
+ case SENSOR_ERROR_INVALID_PARAMETER:
+ ret = "SENSOR_ERROR_INVALID_PARAMETER";
+ break;
+ case SENSOR_ERROR_NOT_SUPPORTED:
+ ret = "SENSOR_ERROR_NOT_SUPPORTED";
+ break;
+ case SENSOR_ERROR_PERMISSION_DENIED:
+ ret = "SENSOR_ERROR_PERMISSION_DENIED";
+ break;
+ case SENSOR_ERROR_OUT_OF_MEMORY:
+ ret = "SENSOR_ERROR_OUT_OF_MEMORY";
+ break;
+ case SENSOR_ERROR_NOT_NEED_CALIBRATION:
+ ret = "SENSOR_ERROR_NOT_NEED_CALIBRATION";
+ break;
+ case SENSOR_ERROR_OPERATION_FAILED:
+ ret = "SENSOR_ERROR_OPERATION_FAILED";
+ break;
+ }
+
+ return ret;
+}
+#endif
+
Dali::TiltSensor TiltSensor::New()
{
Dali::TiltSensor sensor = Dali::TiltSensor(new TiltSensor());
Dali::TiltSensor sensor;
Dali::SingletonService service( SingletonService::Get() );
+
if ( service )
{
// Check whether the keyboard focus manager is already created
TiltSensor::~TiltSensor()
{
- Disable();
+ Disconnect();
}
-bool TiltSensor::Enable()
+bool TiltSensor::Connect()
{
- // Make sure sensor API is responding
- bool success = Update();
+#ifdef SENSOR_ENABLED
+ if(mState != DISCONNECTED)
+ {
+ Stop();
+ Disconnect();
+ }
+
+ const int interval = 1000/mFrequencyHertz;
+
+ int ret = 0;
+ bool isSupported = false;
+
+ // try to use Orientation sensor at first for less power consumption.
+ ret = sensor_is_supported(SENSOR_ORIENTATION, &isSupported);
+
+ if(ret < 0)
+ {
+ DALI_LOG_ERROR("sensor_is_supported() failed : %s\n", get_sensor_error_string(ret).c_str());
+ return false;
+ }
+
+ if(isSupported == true)
+ {
+ mSensorType = SENSOR_ORIENTATION;
+ }
+ else
+ {
+ DALI_LOG_ERROR("sensor does not support SENSOR_ORIENTATION\n");
+
+ sensor_is_supported(SENSOR_ACCELEROMETER, &isSupported);
+
+ if(isSupported == false)
+ {
+ DALI_LOG_ERROR("sensor does not support both SENSOR_ORIENTATION and SENSOR_ACCELEROMETER\n");
+ return false;
+ }
+
+ mSensorType = SENSOR_ACCELEROMETER;
+ }
+
+ ret = sensor_get_default_sensor(mSensorType, &mSensor); /* mSensor should not be deleted */
+
+ if(ret < 0)
+ {
+ DALI_LOG_ERROR("sensor_get_default_sensor() failed : %s\n", get_sensor_error_string(ret).c_str());
+ return false;
+ }
+
+ sensor_create_listener(mSensor, &mSensorListener);
+ sensor_listener_set_event_cb(mSensorListener, interval, sensor_changed_cb, this);
+ sensor_listener_set_interval(mSensorListener, interval);
+
+ sensor_listener_set_option(mSensorListener, SENSOR_OPTION_DEFAULT /* Not receive data when LCD is off and in power save mode */);
+
+ mState = CONNECTED;
+
+ return true;
+#endif
+
+ return false;
+}
- if ( success )
+void TiltSensor::Disconnect()
+{
+ if(mSensorListener)
{
- if ( !mTimer )
+ if(mState == STARTED)
{
- mTimer = Dali::Timer::New( 1000.0f / mFrequencyHertz );
- mTimer.TickSignal().Connect( mTimerSlot, &TiltSensor::Update );
+ Stop();
}
- if ( mTimer &&
- !mTimer.IsRunning() )
+ if(mState == STOPPED || mState == CONNECTED)
{
- mTimer.Start();
+#ifdef SENSOR_ENABLED
+ sensor_listener_unset_event_cb(mSensorListener);
+ sensor_listener_stop(mSensorListener);
+ sensor_destroy_listener(mSensorListener);
+#endif
+ mSensor = NULL;
+ mSensorListener = NULL;
+ mState = DISCONNECTED;
}
}
+}
- return success;
+bool TiltSensor::Start()
+{
+ if( mSensorListener && ( mState == CONNECTED || mState == STOPPED ) )
+ {
+#ifdef SENSOR_ENABLED
+ int ret = 0;
+ ret = sensor_listener_start(mSensorListener);
+ if(ret != SENSOR_ERROR_NONE)
+ {
+ DALI_LOG_ERROR("sensor_listener_start() failed : %s\n", get_sensor_error_string(ret).c_str());
+ Disconnect();
+ return false;
+ }
+
+ mState = STARTED;
+ return true;
+#endif
+ }
+ else
+ {
+ if( mState == STARTED )
+ {
+ DALI_LOG_ERROR("TiltSensor is already started. Current state [%d]\n", mState);
+ }
+ else
+ {
+ // mState is DISCONNECTED
+ DALI_LOG_ERROR("TiltSensor is disconnected. Current state [%d]\n", mState);
+ }
+ return false;
+ }
+ return false;
}
-void TiltSensor::Disable()
+void TiltSensor::Stop()
{
- if ( mTimer )
+#ifdef SENSOR_ENABLED
+ if(mSensorListener && mState == STARTED)
{
- mTimer.Stop();
- mTimer.Reset();
+ sensor_listener_stop( mSensorListener );
+ mState = STOPPED;
}
+#endif
}
-bool TiltSensor::IsEnabled() const
+bool TiltSensor::IsStarted() const
{
- return ( mTimer && mTimer.IsRunning() );
+ return ( mSensorListener && mState == STARTED );
}
float TiltSensor::GetRoll() const
return mRotation;
}
-TiltSensor::TiltedSignalV2& TiltSensor::TiltedSignal()
+TiltSensor::TiltedSignalType& TiltSensor::TiltedSignal()
{
- return mTiltedSignalV2;
+ return mTiltedSignal;
}
void TiltSensor::SetUpdateFrequency( float frequencyHertz )
{
mFrequencyHertz = frequencyHertz;
- if ( mTimer )
+#ifdef SENSOR_ENABLED
+ if(mSensorListener)
{
- mTimer.SetInterval( 1000.0f / mFrequencyHertz );
+ const int interval = 1000/mFrequencyHertz;
+ sensor_listener_set_interval(mSensorListener, interval);
}
+#endif
}
}
bool connected( true );
TiltSensor* sensor = dynamic_cast<TiltSensor*>( object );
- if( sensor && ( SIGNAL_TILTED == signalName ) )
+ if( sensor && SIGNAL_TILTED == signalName )
{
sensor->TiltedSignal().Connect( tracker, functor );
}
}
TiltSensor::TiltSensor()
-: mFrequencyHertz( Dali::TiltSensor::DEFAULT_UPDATE_FREQUENCY ),
- mTimerSlot( this ),
- mSensorFrameworkHandle( -1 ),
+: mState(DISCONNECTED),
+ mFrequencyHertz( Dali::TiltSensor::DEFAULT_UPDATE_FREQUENCY ),
+ mSensor( NULL ),
+ mSensorListener( NULL ),
mRoll( 0.0f ),
mPitch( 0.0f ),
- mRotation( 0.0f, Vector3::YAXIS ),
+ mRotation( Radian(0.0f), Vector3::YAXIS ),
mRotationThreshold( 0.0f )
{
- mRollValues.resize( NUMBER_OF_SAMPLES, 0.0f );
- mPitchValues.resize( NUMBER_OF_SAMPLES, 0.0f );
+ // connect sensor
+ Connect();
}
-bool TiltSensor::Update()
+#ifdef SENSOR_ENABLED
+void TiltSensor::Update(sensor_event_s *event)
{
- float newRoll = 0.0f;
- float newPitch = 0.0f;
+ Radian newRoll( 0.0f );
+ Radian newPitch( 0.0f );
Quaternion newRotation;
-#ifdef SENSOR_ENABLED
-
- // Read accelerometer data
-
- mSensorFrameworkHandle = sf_connect( ACCELEROMETER_SENSOR );
- if ( mSensorFrameworkHandle < 0 )
- {
- DALI_LOG_ERROR( "Failed to connect to sensor framework" );
- return false;
- }
- if ( sf_start(mSensorFrameworkHandle, 0) < 0 )
+ if(mSensorType == SENSOR_ORIENTATION)
{
- DALI_LOG_ERROR( "Failed to start sensor" );
- sf_disconnect(mSensorFrameworkHandle);
- return false;
+ newRoll = Clamp( float(event->values[2] / MAX_ORIENTATION_ROLL_VALUE) /* -90 < roll < 90 */, -1.0f/*min*/, 1.0f/*max*/ );
+ newPitch = Clamp( float(event->values[1] / MAX_ORIENTATION_PITCH_VALUE) /* -180 < pitch < 180 */, -1.0f/*min*/, 1.0f/*max*/ );
}
-
- sensor_data_t* base_data_values = (sensor_data_t*)malloc(sizeof(sensor_data_t));
-
- int dataErr = sf_get_data(mSensorFrameworkHandle, ACCELEROMETER_BASE_DATA_SET, base_data_values);
- if ( dataErr < 0 )
+ else if(mSensorType == SENSOR_ACCELEROMETER)
{
- DALI_LOG_ERROR( "Failed to retrieve sensor data" );
- free(base_data_values);
- sf_stop(mSensorFrameworkHandle);
- sf_disconnect(mSensorFrameworkHandle);
- return false;
+ newRoll = Clamp( float(event->values[0] / MAX_ACCELEROMETER_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
+ newPitch = Clamp( float(event->values[1] / MAX_ACCELEROMETER_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
}
-
- sf_stop(mSensorFrameworkHandle);
- sf_disconnect(mSensorFrameworkHandle);
-
- mRollValues.push_back( base_data_values->values[0] );
- mRollValues.pop_front();
-
- mPitchValues.push_back( base_data_values->values[1] );
- mPitchValues.pop_front();
-
- free(base_data_values);
- base_data_values = NULL;
-
- float averageRoll( 0.0f );
- for ( std::deque<float>::const_iterator iter = mRollValues.begin(); mRollValues.end() != iter; ++iter )
- {
- averageRoll += *iter;
- }
- averageRoll /= mRollValues.size();
-
- float averagePitch( 0.0f );
- for ( std::deque<float>::const_iterator iter = mPitchValues.begin(); mPitchValues.end() != iter; ++iter )
+ else
{
- averagePitch += *iter;
+ DALI_LOG_ERROR("Invalid sensor type\n");
+ return;
}
- averagePitch /= mPitchValues.size();
- newRoll = Clamp( float(averageRoll / MAX_ACCELEROMETER_XY_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
- newPitch = Clamp( float(averagePitch / MAX_ACCELEROMETER_XY_VALUE), -1.0f/*min*/, 1.0f/*max*/ );
-
- newRotation = Quaternion( newRoll * Math::PI * -0.5f, Vector3::YAXIS ) *
- Quaternion( newPitch * Math::PI * -0.5f, Vector3::XAXIS );
-#endif // SENSOR_ENABLED
+ newRotation = Quaternion( Radian( newRoll * Math::PI * -0.5f ), Vector3::YAXIS ) *
+ Quaternion( Radian( newPitch * Math::PI * -0.5f ), Vector3::XAXIS );
Radian angle(Quaternion::AngleBetween(newRotation, mRotation));
+
// If the change in value is more than the threshold then emit tilted signal.
- if( angle > mRotationThreshold )
+ if( angle >= mRotationThreshold )
{
mRoll = newRoll;
mPitch = newPitch;
mRotation = newRotation;
- if ( !mTiltedSignalV2.Empty() )
+ // emit signal
+ if ( !mTiltedSignal.Empty() )
{
Dali::TiltSensor handle( this );
- mTiltedSignalV2.Emit( handle );
+ mTiltedSignal.Emit( handle );
}
}
-
- return true;
}
+#endif // SENSOR_ENABLED
} // namespace Adaptor