/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using Tizen.System;
namespace Tizen.Sensor
{
internal static class Globals
{
internal const string LogTag = "Tizen.Sensor";
}
///
/// Sensor class for storing hardware information about a particular sensor
///
public abstract class Sensor : IDisposable
{
private string _name;
private string _vendor;
private float _minValue;
private float _maxValue;
private float _resolution;
private int _minInterval;
private int _fifoCount;
private int _maxBatchCount;
private bool _isSensing = false;
private bool _disposed = false;
private TimeSpan _timeSpan;
private uint _interval = 0;
private uint _maxBatchLatency = 0;
private SensorPausePolicy _pausePolicy = SensorPausePolicy.None;
private IntPtr _sensorHandle = IntPtr.Zero;
private IntPtr _listenerHandle = IntPtr.Zero;
internal abstract SensorType GetSensorType();
internal abstract void EventListenStart();
internal abstract void EventListenStop();
internal Sensor(uint index)
{
SensorType type = GetSensorType();
GetHandleList(type, index);
if (CheckSensorHandle())
{
CreateListener();
GetProperty();
}
}
~Sensor()
{
Dispose(false);
}
///
/// Property: For getting the name of the sensor
///
/// 3
/// The name of sensor
public string Name
{
get
{
Log.Info(Globals.LogTag, "Getting the sensor name");
return _name;
}
}
///
/// Property: Gets the vendor.
///
/// 3
/// The vendor name of sensor
public string Vendor
{
get
{
Log.Info(Globals.LogTag, "Getting the sensor vendor name");
return _vendor;
}
}
///
/// Property: Gets the minimum value of range of sensor data.
///
/// 3
/// The lower bound of range of sensor reading
public float MinValue
{
get
{
Log.Info(Globals.LogTag, "Getting the min value of the sensor");
return _minValue;
}
}
///
/// Property: Gets the maximum value of range of sensor data.
///
/// 3
/// The upper bound of range of sensor reading
public float MaxValue
{
get
{
Log.Info(Globals.LogTag, "Getting the max value of the sensor");
return _maxValue;
}
}
///
/// Property: Gets the resolution.
///
/// 3
/// The resolution
public float Resolution
{
get
{
Log.Info(Globals.LogTag, "Getting the resolution of the sensor");
return _resolution;
}
}
///
/// Property: Gets the minimum interval.
///
/// 3
/// The minimum update interval
public int MinInterval
{
get
{
Log.Info(Globals.LogTag, "Getting the min interval for the sensor");
return _minInterval;
}
}
///
/// Property: Gets the fifo count.
///
/// 3
/// The size of the hardware FIFO
public int FifoCount
{
get
{
Log.Info(Globals.LogTag, "Getting the fifo count of the sensor");
return _fifoCount;
}
}
///
/// Property: Gets the maximum batch count.
///
/// 3
/// The maximum batch count
public int MaxBatchCount
{
get
{
Log.Info(Globals.LogTag, "Getting the max batch count of the sensor");
return _maxBatchCount;
}
}
///
/// Sets the interval of the sensor for sensor data event
/// Callbacks will be called at frequency of this interval
///
/// 3
/// Thrown when the operation is invalid for the current state
/// The interval of the sensor
public uint Interval
{
set
{
Log.Info(Globals.LogTag, "Setting the interval of the sensor");
_interval = value;
SetInterval();
}
get
{
Log.Info(Globals.LogTag, "Getting the interval of the sensor");
return _interval;
}
}
///
/// Sets the max batch latency for the sensor corresponding to the sensor data event.
///
/// 3
/// Thrown when the operation is invalid for the current state
/// The max batch latency
public uint MaxBatchLatency
{
set
{
Log.Info(Globals.LogTag, "Setting the max batch latency of the sensor");
_maxBatchLatency = value;
SetMaxBatchLatency();
}
get
{
Log.Info(Globals.LogTag, "Getting the max batch latency of the sensor");
return _maxBatchLatency;
}
}
///
/// Sets the pause policy of the sensor.
///
/// 3
/// The pause policy
/// Thrown when the operation is invalid for the current state
/// The pause policy
public SensorPausePolicy PausePolicy
{
set
{
Log.Info(Globals.LogTag, "Setting the pause policy of the sensor");
_pausePolicy = value;
SetAttribute(SensorAttribute.PausePolicy, (int)_pausePolicy);
}
get
{
Log.Info(Globals.LogTag, "Getting the pause policy of the sensor");
return _pausePolicy;
}
}
///
/// Gets or sets the time span.
///
/// 3
/// The time span
public TimeSpan TimeSpan
{
set
{
Log.Info(Globals.LogTag, "Setting the timespan of the sensor values");
_timeSpan = value;
}
get
{
Log.Info(Globals.LogTag, "Getting the timespan of the sensor values");
return _timeSpan;
}
}
///
/// Indicates whether this sensor is sensing.
///
/// 3
/// true if this sensor is sensing; otherwise, false.
public bool IsSensing
{
get
{
Log.Info(Globals.LogTag, "Checking if the sensor is started");
return _isSensing;
}
}
internal IntPtr ListenerHandle
{
get
{
return _listenerHandle;
}
}
internal static bool CheckIfSupported(SensorType type, String key)
{
bool isSupported = false;
bool error = SystemInfo.TryGetValue(key, out isSupported);
if (!error || !isSupported)
{
Log.Error(Globals.LogTag, "Error checking if sensor is supported(systeminfo)");
return false;
}
int ret = Interop.SensorManager.SensorIsSupported(type, out isSupported);
if (ret != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error checking if sensor is supported");
isSupported = false;
}
return isSupported;
}
///
/// Starts the sensor.
/// After this the event handlers will start receiving events.
///
/// 3
/// Thrown when the operation is invalid for the current state
public void Start()
{
Log.Info(Globals.LogTag, "Starting the sensor");
if (CheckListenerHandle())
{
int error = Interop.SensorListener.StartListener(_listenerHandle);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error starting sensor");
throw SensorErrorFactory.CheckAndThrowException(error, "Unable to Start Sensor Listener");
}
EventListenStart();
_isSensing = true;
Log.Info(Globals.LogTag, "Sensor started");
}
}
///
/// Stop the sensor.
/// After this the event handlers will stop receiving the events
///
/// 3
/// Thrown when the operation is invalid for the current state
public void Stop()
{
Log.Info(Globals.LogTag, "Stopping the sensor");
if (_isSensing)
{
int error = Interop.SensorListener.StopListener(_listenerHandle);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error stopping the sensor");
throw SensorErrorFactory.CheckAndThrowException(error, "Unable to Stop Sensor Listener");
}
EventListenStop();
_isSensing = false;
Log.Info(Globals.LogTag, "Sensor stopped");
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
DestroyHandles();
_disposed = true;
}
internal void SetAttribute(SensorAttribute attribute, int option)
{
if (CheckListenerHandle())
{
int error = Interop.SensorListener.SetAttribute(_listenerHandle, attribute, option);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error setting sensor pause policy");
throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.PausePolicy Failed");
}
}
}
private void GetHandleList(SensorType type, uint index)
{
IntPtr list;
IntPtr[] sensorList;
int count;
int error = Interop.SensorManager.GetSensorList(type, out list, out count);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor list");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.GetSensorList Failed");
}
sensorList = Interop.IntPtrToIntPtrArray(list, count);
_sensorHandle = sensorList[index];
Interop.Libc.Free(list);
}
private void GetProperty()
{
int error = (int)SensorError.None;
error = Interop.Sensor.GetName(_sensorHandle, out _name);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor name");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Name Failed");
}
error = Interop.Sensor.GetVendor(_sensorHandle, out _vendor);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor vendor name");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Vendor Failed");
}
error = Interop.Sensor.GetMinRange(_sensorHandle, out _minValue);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor min value");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MinValue Failed");
}
error = Interop.Sensor.GetMaxRange(_sensorHandle, out _maxValue);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor max value");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MaxValue Failed");
}
error = Interop.Sensor.GetResolution(_sensorHandle, out _resolution);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor resolution");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Resolution Failed");
}
error = Interop.Sensor.GetMinInterval(_sensorHandle, out _minInterval);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor min interval");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MinInterval Failed");
}
error = Interop.Sensor.GetFifoCount(_sensorHandle, out _fifoCount);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor fifo count");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.FifoCount Failed");
}
error = Interop.Sensor.GetMaxBatchCount(_sensorHandle, out _maxBatchCount);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error getting sensor max batch count");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MaxBatchCount Failed");
}
}
private void CreateListener()
{
int error = Interop.SensorListener.CreateListener(_sensorHandle, out _listenerHandle);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error cerating sensor listener handle");
throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.CreateListener Failed");
}
}
private void SetInterval()
{
if (CheckListenerHandle())
{
if (_isSensing)
{
int error = Interop.SensorListener.SetInterval(_listenerHandle, _interval);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error setting sensor interval");
throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.SetInterval Failed");
}
}
}
}
private void SetMaxBatchLatency()
{
if (CheckListenerHandle())
{
int error = Interop.SensorListener.SetMaxBatchLatency(_listenerHandle, _maxBatchLatency);
if (error != (int)SensorError.None)
{
Log.Error(Globals.LogTag, "Error setting max batch latency");
throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.MaxBatchLatency Failed");
}
}
}
private bool CheckListenerHandle()
{
bool result = false;
if (_listenerHandle != IntPtr.Zero)
{
result = true;
}
else
{
Log.Error(Globals.LogTag, "Sensor listener handle is null");
throw new ArgumentException("Invalid Parameter: Sensor is null");
}
return result;
}
private bool CheckSensorHandle()
{
bool result = false;
if (_sensorHandle != IntPtr.Zero)
{
result = true;
}
else
{
Log.Error(Globals.LogTag, "Sensor handle is null");
throw new ArgumentException("Invalid Parameter: Sensor is null");
}
return result;
}
private void DestroyHandles()
{
Interop.SensorListener.DestroyListener(_listenerHandle);
}
}
}