f90ed36ae3926af77bab079d26572d96e0504e34
[platform/core/csapi/sensor.git] / Tizen.Sensor / Tizen.Sensor / Plugins / MagnetometerRotationVectorSensor.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
11 namespace Tizen.Sensor
12 {
13     /// <summary>
14     /// MagnetometerRotationVectorSensor Class. Used for registering callbacks for magnetometer rotation vector sensor and getting magnetometer rotation vector data
15     /// /// </summary>
16     public class MagnetometerRotationVectorSensor : Sensor
17     {
18         private static string MagnetometerRVKey = "http://tizen.org/feature/sensor.geomagnetic_rotation_vector";
19
20         private event EventHandler<SensorAccuracyChangedEventArgs> _accuracyChanged;
21         /// <summary>
22         /// Gets the X component of the magnetometer rotation vector.
23         /// </summary>
24         public float X { get; private set; }
25
26         /// <summary>
27         /// Gets the Y component of the magnetometer rotation vector.
28         /// </summary>
29         public float Y { get; private set; }
30
31         /// <summary>
32         /// Gets the Z component of the magnetometer rotation vector.
33         /// </summary>
34         public float Z { get; private set; }
35
36         /// <summary>
37         /// Gets the W component of the magnetometer rotation vector.
38         /// </summary>
39         public float W { get; private set; }
40
41         /// <summary>
42         /// Gets the Accuracy of the magnetometer rotation vector data.
43         /// </summary>
44         public SensorDataAccuracy Accuracy { get; private set; }
45
46         /// <summary>
47         /// Returns true or false based on whether magnetometer rotation vector sensor is supported by device.
48         /// </summary>
49         public static bool IsSupported
50         {
51             get
52             {
53                 Log.Info(Globals.LogTag, "Checking if the MagnetometerRotationVectorSensor is supported");
54                 return CheckIfSupported(SensorType.MagnetometerRotationVectorSensor, MagnetometerRVKey);
55             }
56         }
57
58         /// <summary>
59         /// Returns the number of magnetometer rotation vector sensors available on the device.
60         /// </summary>
61         public static int Count
62         {
63             get
64             {
65                 Log.Info(Globals.LogTag, "Getting the count of magnetometer rotation vector sensors");
66                 return GetCount();
67             }
68         }
69
70         /// <summary>
71         /// Initializes a new instance of the <see cref="Tizen.Sensor.MagnetometerRotationVectorSensor"/> class.
72         /// </summary>
73         /// <param name='index'>
74         /// Index. Default value for this is 0. Index refers to a particular magnetometer rotation vector sensor in case of multiple sensors
75         /// </param>
76         public MagnetometerRotationVectorSensor(int index = 0) : base(index)
77         {
78             Log.Info(Globals.LogTag, "Creating MagnetometerRotationVectorSensor object");
79         }
80
81         internal override SensorType GetSensorType()
82         {
83             return SensorType.MagnetometerRotationVectorSensor;
84         }
85
86         /// <summary>
87         /// Event Handler for storing the callback functions for event corresponding to change in magnetometer rotation vector sensor data.
88         /// </summary>
89
90         public event EventHandler<MagnetometerRotationVectorSensorDataUpdatedEventArgs> DataUpdated;
91
92         /// <summary>
93         /// Event handler for accuracy changed events.
94         /// </summary>
95         public event EventHandler<SensorAccuracyChangedEventArgs> AccuracyChanged
96         {
97             add
98             {
99                 if (_accuracyChanged == null)
100                 {
101                     AccuracyListenStart();
102                 }
103                 _accuracyChanged += value;
104             }
105             remove
106             {
107                 _accuracyChanged -= value;
108                 if (_accuracyChanged == null)
109                 {
110                     AccuracyListenStop();
111                 }
112             }
113         }
114
115         private static bool CheckIfSupported()
116         {
117             bool isSupported;
118             int error = Interop.SensorManager.SensorIsSupported(SensorType.MagnetometerRotationVectorSensor, out isSupported);
119             if (error != (int)SensorError.None)
120             {
121                 Log.Error(Globals.LogTag, "Error checking if magnetometer rotation vector sensor is supported");
122                 isSupported = false;
123             }
124             return isSupported;
125         }
126
127         private static int GetCount()
128         {
129             IntPtr list;
130             int count;
131             int error = Interop.SensorManager.GetSensorList(SensorType.MagnetometerRotationVectorSensor, out list, out count);
132             if (error != (int)SensorError.None)
133             {
134                 Log.Error(Globals.LogTag, "Error getting sensor list for magnetometer rotation vector");
135                 count = 0;
136             }
137             else
138                 Interop.Libc.Free(list);
139             return count;
140         }
141
142         protected override void EventListenStart()
143         {
144             int error = Interop.SensorListener.SetEventCallback(ListenerHandle, Interval, SensorEventCallback, IntPtr.Zero);
145             if (error != (int)SensorError.None)
146             {
147                 Log.Error(Globals.LogTag, "Error setting event callback for magnetometer rotation vector sensor");
148                 throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for magnetometer rotation vector");
149             }
150         }
151
152         protected override void EventListenStop()
153         {
154             int error = Interop.SensorListener.UnsetEventCallback(ListenerHandle);
155             if (error != (int)SensorError.None)
156             {
157                 Log.Error(Globals.LogTag, "Error unsetting event callback for magnetometer rotation vector sensor");
158                 throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for magnetometer rotation vector");
159             }
160         }
161
162         private void AccuracyListenStart()
163         {
164             int error = Interop.SensorListener.SetAccuracyCallback(ListenerHandle, Interval, AccuracyEventCallback, IntPtr.Zero);
165             if (error != (int)SensorError.None)
166             {
167                 Log.Error(Globals.LogTag, "Error setting accuracy event callback for magnetometer rotation vector sensor");
168                 throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set accuracy event callback for magnetometer rotation vector");
169             }
170         }
171
172         private void AccuracyListenStop()
173         {
174             int error = Interop.SensorListener.UnsetAccuracyCallback(ListenerHandle);
175             if (error != (int)SensorError.None)
176             {
177                 Log.Error(Globals.LogTag, "Error unsetting accuracy event callback for magnetometer rotation vector sensor");
178                 throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset accuracy event callback for magnetometer rotation vector");
179             }
180         }
181
182         private void SensorEventCallback(IntPtr sensorHandle, IntPtr sensorPtr, IntPtr data)
183         {
184             Interop.SensorEventStruct sensorData = Interop.IntPtrToEventStruct(sensorPtr);
185             TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
186             X = sensorData.values[0];
187             Y = sensorData.values[1];
188             Z = sensorData.values[2];
189             Accuracy = sensorData.accuracy;
190
191             DataUpdated?.Invoke(this, new MagnetometerRotationVectorSensorDataUpdatedEventArgs(sensorData.values, sensorData.accuracy));
192         }
193
194         private void AccuracyEventCallback(IntPtr sensorHandle, UInt64 timestamp, SensorDataAccuracy accuracy, IntPtr data)
195         {
196             TimeSpan = new TimeSpan((Int64)timestamp);
197             Accuracy = accuracy;
198             _accuracyChanged?.Invoke(this, new SensorAccuracyChangedEventArgs(new TimeSpan((Int64)timestamp), accuracy));
199         }
200     }
201 }