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