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