csapi-sensor: check if the sensor is started or not when Stop() is called
[platform/core/csapi/sensor.git] / Tizen.Sensor / Tizen.Sensor / Sensor.cs
1 // Copyright 2016 by Samsung Electronics, Inc.,
2 //
3 // This software is the confidential and proprietary information
4 // of Samsung Electronics, Inc. ("Confidential Information"). You
5 // shall not disclose such Confidential Information and shall use
6 // it only in accordance with the terms of the license agreement
7 // you entered into with Samsung.
8
9 using System;
10 using Tizen.System;
11
12 namespace Tizen.Sensor
13 {
14     internal static class Globals
15     {
16         internal const string LogTag = "Tizen.Sensor";
17     }
18
19     /// <summary>
20     /// Sensor class for storing hardware information about a particular sensor
21     /// </summary>
22     public abstract class Sensor : IDisposable
23     {
24         private string _name;
25         private string _vendor;
26         private float _minValue;
27         private float _maxValue;
28         private float _resolution;
29         private int _minInterval;
30         private int _fifoCount;
31         private int _maxBatchCount;
32         private bool _isSensing = false;
33         private bool _disposed = false;
34         private TimeSpan _timeSpan;
35         private uint _interval = 0;
36         private uint _maxBatchLatency = 0;
37         private SensorPausePolicy _pausePolicy = SensorPausePolicy.None;
38         private IntPtr _sensorHandle = IntPtr.Zero;
39         private IntPtr _listenerHandle = IntPtr.Zero;
40
41         internal abstract SensorType GetSensorType();
42         protected internal abstract void EventListenStart();
43         protected internal abstract void EventListenStop();
44
45         internal Sensor(uint index)
46         {
47             SensorType type = GetSensorType();
48             GetHandleList(type, index);
49             if (CheckSensorHandle())
50             {
51                 CreateListener();
52                 GetProperty();
53             }
54         }
55
56         ~Sensor()
57         {
58             Dispose(false);
59         }
60
61         /// <summary>
62         /// Property: For getting the name of the sensor
63         /// </summary>
64         public string Name
65         {
66             get
67             {
68                 Log.Info(Globals.LogTag, "Getting the sensor name");
69                 return _name;
70             }
71         }
72
73         /// <summary>
74         /// Property: Gets the vendor.
75         /// </summary>
76         public string Vendor
77         {
78             get
79             {
80                 Log.Info(Globals.LogTag, "Getting the sensor vendor name");
81                 return _vendor;
82             }
83         }
84
85         /// <summary>
86         /// Property: Gets the minimum value of range of sensor data.
87         /// </summary>
88         public float MinValue
89         {
90             get
91             {
92                 Log.Info(Globals.LogTag, "Getting the min value of the sensor");
93                 return _minValue;
94             }
95         }
96
97         /// <summary>
98         /// Property: Gets the maximum value of range of sensor data.
99         /// </summary>
100         public float MaxValue
101         {
102             get
103             {
104                 Log.Info(Globals.LogTag, "Getting the max value of the sensor");
105                 return _maxValue;
106             }
107         }
108
109         /// <summary>
110         /// Property: Gets the resolution.
111         /// </summary>
112         public float Resolution
113         {
114             get
115             {
116                 Log.Info(Globals.LogTag, "Getting the resolution of the sensor");
117                 return _resolution;
118             }
119         }
120
121         /// <summary>
122         /// Property: Gets the minimum interval.
123         /// </summary>
124         public int MinInterval
125         {
126             get
127             {
128                 Log.Info(Globals.LogTag, "Getting the min interval for the sensor");
129                 return _minInterval;
130             }
131         }
132
133         /// <summary>
134         /// Property: Gets the fifo count.
135         /// </summary>
136         public int FifoCount
137         {
138             get
139             {
140                 Log.Info(Globals.LogTag, "Getting the fifo count of the sensor");
141                 return _fifoCount;
142             }
143         }
144
145         /// <summary>
146         /// Property: Gets the maximum batch count.
147         /// </summary>
148         public int MaxBatchCount
149         {
150             get
151             {
152                 Log.Info(Globals.LogTag, "Getting the max batch count of the sensor");
153                 return _maxBatchCount;
154             }
155         }
156
157         /// <summary>
158         /// Sets the interval of the sensor for sensor data event
159         /// Callbacks will be called at frequency of this interval
160         /// </summary>
161         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
162         public uint Interval
163         {
164             set
165             {
166                 Log.Info(Globals.LogTag, "Setting the interval of the sensor");
167                 _interval = value;
168                 SetInterval();
169             }
170             get
171             {
172                 Log.Info(Globals.LogTag, "Getting the interval of the sensor");
173                 return _interval;
174             }
175         }
176
177         /// <summary>
178         /// Sets the max batch latency for the sensor corresponding to the sensor data event.
179         /// </summary>
180         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
181         public uint MaxBatchLatency
182         {
183             set
184             {
185                 Log.Info(Globals.LogTag, "Setting the max batch latency of the sensor");
186                 _maxBatchLatency = value;
187                 SetMaxBatchLatency();
188             }
189             get
190             {
191                 Log.Info(Globals.LogTag, "Getting the max batch latency of the sensor");
192                 return _maxBatchLatency;
193             }
194         }
195
196         /// <summary>
197         /// Sets the pause policy of the sensor.
198         /// </summary>
199         /// <value>The pause policy</value>
200         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
201         public SensorPausePolicy PausePolicy
202         {
203             set
204             {
205                 Log.Info(Globals.LogTag, "Setting the pause policy of the sensor");
206                 _pausePolicy = value;
207                 SetAttribute(SensorAttribute.PausePolicy, (int)_pausePolicy);
208             }
209             get
210             {
211                 Log.Info(Globals.LogTag, "Getting the pause policy of the sensor");
212                 return _pausePolicy;
213             }
214         }
215
216         /// <summary>
217         /// Gets or sets the time span.
218         /// </summary>
219         /// <value>The time span.</value>
220         public TimeSpan TimeSpan
221         {
222             set
223             {
224                 Log.Info(Globals.LogTag, "Setting the timespan of the sensor values");
225                 _timeSpan = value;
226             }
227             get
228             {
229                 Log.Info(Globals.LogTag, "Getting the timespan of the sensor values");
230                 return _timeSpan;
231             }
232         }
233
234         /// <summary>
235         /// Indicates whether this sensor is sensing.
236         /// </summary>
237         /// <value><c>true</c> if this sensor is sensing; otherwise, <c>false</c>.</value>
238         public bool IsSensing
239         {
240             get
241             {
242                 Log.Info(Globals.LogTag, "Checking if the sensor is started");
243                 return _isSensing;
244             }
245         }
246
247         internal IntPtr ListenerHandle
248         {
249             get
250             {
251                 return _listenerHandle;
252             }
253         }
254
255         internal static bool CheckIfSupported(SensorType type, String key)
256         {
257             bool isSupported = false;
258             bool error = SystemInfo.TryGetValue(key, out isSupported);
259
260             if (!error || !isSupported)
261             {
262                 Log.Error(Globals.LogTag, "Error checking if sensor is supported(systeminfo)");
263                 return false;
264             }
265
266             int ret = Interop.SensorManager.SensorIsSupported(type, out isSupported);
267             if (ret != (int)SensorError.None)
268             {
269                 Log.Error(Globals.LogTag, "Error checking if sensor is supported");
270                 isSupported = false;
271             }
272
273             return isSupported;
274         }
275
276         /// <summary>
277         /// Starts the sensor.
278         /// After this the event handlers will start receiving events.
279         /// </summary>
280         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
281         public void Start()
282         {
283             Log.Info(Globals.LogTag, "Starting the sensor");
284             if (CheckListenerHandle())
285             {
286                 int error = Interop.SensorListener.StartListener(_listenerHandle);
287                 if (error != (int)SensorError.None)
288                 {
289                     Log.Error(Globals.LogTag, "Error starting sensor");
290                     throw SensorErrorFactory.CheckAndThrowException(error, "Unable to Start Sensor Listener");
291                 }
292                 EventListenStart();
293                 _isSensing = true;
294                 Log.Info(Globals.LogTag, "Sensor started");
295             }
296         }
297
298         /// <summary>
299         /// Stop the sensor.
300         /// After this the event handlers will stop receiving the events
301         /// </summary>
302         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
303         public void Stop()
304         {
305             Log.Info(Globals.LogTag, "Stopping the sensor");
306             if (_isSensing)
307             {
308                 int error = Interop.SensorListener.StopListener(_listenerHandle);
309                 if (error != (int)SensorError.None)
310                 {
311                     Log.Error(Globals.LogTag, "Error stopping the sensor");
312                     throw SensorErrorFactory.CheckAndThrowException(error, "Unable to Stop Sensor Listener");
313                 }
314                 EventListenStop();
315                 _isSensing = false;
316                 Log.Info(Globals.LogTag, "Sensor stopped");
317             }
318         }
319
320         public void Dispose()
321         {
322             Dispose(true);
323             GC.SuppressFinalize(this);
324         }
325
326         protected virtual void Dispose(bool disposing)
327         {
328             if (_disposed)
329                 return;
330
331             DestroyHandles();
332             _disposed = true;
333         }
334
335         protected void SetAttribute(SensorAttribute attribute, int option)
336         {
337             if (CheckListenerHandle())
338             {
339                 int error = Interop.SensorListener.SetAttribute(_listenerHandle, attribute, option);
340                 if (error != (int)SensorError.None)
341                 {
342                     Log.Error(Globals.LogTag, "Error setting sensor pause policy");
343                     throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.PausePolicy Failed");
344                 }
345             }
346         }
347
348         private void GetHandleList(SensorType type, uint index)
349         {
350             IntPtr list;
351             IntPtr[] sensorList;
352             int count;
353             int error = Interop.SensorManager.GetSensorList(type, out list, out count);
354             if (error != (int)SensorError.None)
355             {
356                 Log.Error(Globals.LogTag, "Error getting sensor list");
357                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.GetSensorList Failed");
358             }
359             sensorList = Interop.IntPtrToIntPtrArray(list, count);
360             _sensorHandle = sensorList[index];
361             Interop.Libc.Free(list);
362         }
363
364         private void GetProperty()
365         {
366             int error = (int)SensorError.None;
367
368             error = Interop.Sensor.GetName(_sensorHandle, out _name);
369             if (error != (int)SensorError.None)
370             {
371                 Log.Error(Globals.LogTag, "Error getting sensor name");
372                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Name Failed");
373             }
374
375             error = Interop.Sensor.GetVendor(_sensorHandle, out _vendor);
376             if (error != (int)SensorError.None)
377             {
378                 Log.Error(Globals.LogTag, "Error getting sensor vendor name");
379                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Vendor Failed");
380             }
381
382             error = Interop.Sensor.GetMinRange(_sensorHandle, out _minValue);
383             if (error != (int)SensorError.None)
384             {
385                 Log.Error(Globals.LogTag, "Error getting sensor min value");
386                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MinValue Failed");
387             }
388
389             error = Interop.Sensor.GetMaxRange(_sensorHandle, out _maxValue);
390             if (error != (int)SensorError.None)
391             {
392                 Log.Error(Globals.LogTag, "Error getting sensor max value");
393                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MaxValue Failed");
394             }
395
396             error = Interop.Sensor.GetResolution(_sensorHandle, out _resolution);
397             if (error != (int)SensorError.None)
398             {
399                 Log.Error(Globals.LogTag, "Error getting sensor resolution");
400                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.Resolution Failed");
401             }
402
403             error = Interop.Sensor.GetMinInterval(_sensorHandle, out _minInterval);
404             if (error != (int)SensorError.None)
405             {
406                 Log.Error(Globals.LogTag, "Error getting sensor min interval");
407                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MinInterval Failed");
408             }
409
410             error = Interop.Sensor.GetFifoCount(_sensorHandle, out _fifoCount);
411             if (error != (int)SensorError.None)
412             {
413                 Log.Error(Globals.LogTag, "Error getting sensor fifo count");
414                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.FifoCount Failed");
415             }
416
417             error = Interop.Sensor.GetMaxBatchCount(_sensorHandle, out _maxBatchCount);
418             if (error != (int)SensorError.None)
419             {
420                 Log.Error(Globals.LogTag, "Error getting sensor max batch count");
421                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.MaxBatchCount Failed");
422             }
423         }
424
425         private void CreateListener()
426         {
427             int error = Interop.SensorListener.CreateListener(_sensorHandle, out _listenerHandle);
428             if (error != (int)SensorError.None)
429             {
430                 Log.Error(Globals.LogTag, "Error cerating sensor listener handle");
431                 throw SensorErrorFactory.CheckAndThrowException(error, "Sensor.CreateListener Failed");
432             }
433         }
434
435         private void SetInterval()
436         {
437             if (CheckListenerHandle())
438             {
439                 if (_isSensing)
440                 {
441                     int error = Interop.SensorListener.SetInterval(_listenerHandle, _interval);
442                     if (error != (int)SensorError.None)
443                     {
444                         Log.Error(Globals.LogTag, "Error setting sensor interval");
445                         throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.SetInterval Failed");
446                     }
447                 }
448             }
449         }
450
451         private void SetMaxBatchLatency()
452         {
453             if (CheckListenerHandle())
454             {
455                 int error = Interop.SensorListener.SetMaxBatchLatency(_listenerHandle, _maxBatchLatency);
456                 if (error != (int)SensorError.None)
457                 {
458                     Log.Error(Globals.LogTag, "Error setting max batch latency");
459                     throw SensorErrorFactory.CheckAndThrowException(error, "Setting Sensor.MaxBatchLatency Failed");
460                 }
461             }
462         }
463
464         private bool CheckListenerHandle()
465         {
466             bool result = false;
467             if (_listenerHandle != IntPtr.Zero)
468             {
469                 result = true;
470             }
471             else
472             {
473                 Log.Error(Globals.LogTag, "Sensor listener handle is null");
474                 throw new ArgumentException("Invalid Parameter: Sensor is null");
475             }
476             return result;
477         }
478
479         private bool CheckSensorHandle()
480         {
481             bool result = false;
482             if (_sensorHandle != IntPtr.Zero)
483             {
484                 result = true;
485             }
486             else
487             {
488                 Log.Error(Globals.LogTag, "Sensor handle is null");
489                 throw new ArgumentException("Invalid Parameter: Sensor is null");
490             }
491             return result;
492         }
493
494         private void DestroyHandles()
495         {
496             Interop.SensorListener.DestroyListener(_listenerHandle);
497         }
498     }
499 }