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