[Sensor] Modify implementation using new native API (#1367)
[platform/core/csapi/tizenfx.git] / src / Tizen.Sensor / Tizen.Sensor / Plugins / Pedometer.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
19 namespace Tizen.Sensor
20 {
21     /// <summary>
22     /// The Pedometer Sensor class is used for registering callbacks for the pedometer and getting the pedometer data.
23     /// </summary>
24     /// <since_tizen> 3 </since_tizen>
25     public sealed class Pedometer : Sensor
26     {
27         private static string PedometerKey = "http://tizen.org/feature/sensor.pedometer";
28
29         /// <summary>
30         /// Gets the step count.
31         /// </summary>
32         /// <since_tizen> 3 </since_tizen>
33         /// <value> The step count. </value>
34         public uint StepCount { get; private set; } = 0;
35
36         /// <summary>
37         /// Gets the walking step count.
38         /// </summary>
39         /// <since_tizen> 3 </since_tizen>
40         /// <value> The walk step count. </value>
41         public uint WalkStepCount { get; private set; } = 0;
42
43         /// <summary>
44         /// Gets the running step count.
45         /// </summary>
46         /// <since_tizen> 3 </since_tizen>
47         /// <value> The run step count. </value>
48         public uint RunStepCount { get; private set; } = 0;
49
50         /// <summary>
51         /// Gets the moving distance.
52         /// </summary>
53         /// <since_tizen> 3 </since_tizen>
54         /// <value> The moving distance. </value>
55         public float MovingDistance { get; private set; } = 0;
56
57         /// <summary>
58         /// Gets the calorie burned.
59         /// </summary>
60         /// <since_tizen> 3 </since_tizen>
61         /// <value> The calorie burned. </value>
62         public float CalorieBurned { get; private set; } = 0;
63
64         /// <summary>
65         /// Gets the last speed.
66         /// </summary>
67         /// <since_tizen> 3 </since_tizen>
68         /// <value> The last speed. </value>
69         public float LastSpeed { get; private set; } = 0;
70
71         /// <summary>
72         /// Gets the last stepping frequency.
73         /// </summary>
74         /// <since_tizen> 3 </since_tizen>
75         /// <value> The last stepping frequency. </value>
76         public float LastSteppingFrequency { get; private set; } = 0;
77
78         /// <summary>
79         /// Gets the last step status.
80         /// </summary>
81         /// <since_tizen> 3 </since_tizen>
82         /// <value> The last step status. </value>
83         public PedometerState LastStepStatus { get; private set; } = PedometerState.Unknown;
84
85         /// <summary>
86         /// Returns true or false based on whether the pedometer sensor is supported by the device.
87         /// </summary>
88         /// <since_tizen> 3 </since_tizen>
89         /// <value><c>true</c> if supported; otherwise <c>false</c>.</value>
90         public static bool IsSupported
91         {
92             get
93             {
94                 Log.Info(Globals.LogTag, "Checking if the Pedometer sensor is supported");
95                 return CheckIfSupported(SensorType.Pedometer, PedometerKey);
96             }
97         }
98
99         /// <summary>
100         /// Returns the number of pedometer sensors available on the device.
101         /// </summary>
102         /// <since_tizen> 3 </since_tizen>
103         /// <value> The count of pedometer sensors. </value>
104         public static int Count
105         {
106             get
107             {
108                 Log.Info(Globals.LogTag, "Getting the count of pedometer sensors");
109                 return GetCount();
110             }
111         }
112
113         /// <summary>
114         /// Initializes a new instance of the <see cref="Tizen.Sensor.Pedometer"/> class.
115         /// </summary>
116         /// <since_tizen> 3 </since_tizen>
117         /// <privilege>http://tizen.org/privilege/healthinfo</privilege>
118         /// <privlevel>public</privlevel>
119         /// <feature>http://tizen.org/feature/sensor.pedometer</feature>
120         /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
121         /// <exception cref="NotSupportedException">Thrown when the sensor is not supported.</exception>
122         /// <exception cref="UnauthorizedAccessException">Thrown when the application has no privilege to use the sensor.</exception>
123         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
124         /// <param name='index'>
125         /// Index. Default value for this is 0. Index refers to a particular pedometer sensor in case of multiple sensors.
126         /// </param>
127         public Pedometer(uint index = 0) : base(index)
128         {
129             Log.Info(Globals.LogTag, "Creating Pedometer object");
130         }
131
132         internal override SensorType GetSensorType()
133         {
134             return SensorType.Pedometer;
135         }
136
137         /// <summary>
138         /// An event handler for storing the callback functions for the event corresponding to the change in the pedometer sensor data.
139         /// </summary>
140         /// <since_tizen> 3 </since_tizen>
141
142         public event EventHandler<PedometerDataUpdatedEventArgs> DataUpdated;
143
144         private static int GetCount()
145         {
146             IntPtr list;
147             int count;
148             int error = Interop.SensorManager.GetSensorList(SensorType.Pedometer, out list, out count);
149             if (error != (int)SensorError.None)
150             {
151                 Log.Error(Globals.LogTag, "Error getting sensor list for pedometer");
152                 count = 0;
153             }
154             else
155                 Interop.Libc.Free(list);
156             return count;
157         }
158
159         /// <summary>
160         /// Read pedometer sensor data synchronously.
161         /// </summary>
162         internal override void ReadData()
163         {
164             Interop.SensorEventStruct pedoSensorData;
165             int error = Interop.SensorListener.ReadData(ListenerHandle, out pedoSensorData);
166             if (error != (int)SensorError.None)
167             {
168                 Log.Error(Globals.LogTag, "Error reading pedometer sensor data");
169                 throw SensorErrorFactory.CheckAndThrowException(error, "Reading pedometer sensor data failed");
170             }
171
172             StepCount = (uint)pedoSensorData.values[0];
173             WalkStepCount = (uint)pedoSensorData.values[1];
174             RunStepCount = (uint)pedoSensorData.values[2];
175             MovingDistance = pedoSensorData.values[3];
176             CalorieBurned = pedoSensorData.values[4];
177             LastSpeed = pedoSensorData.values[5];
178             LastSteppingFrequency = pedoSensorData.values[6];
179             LastStepStatus = (PedometerState)pedoSensorData.values[7];
180         }
181
182         private static Interop.SensorListener.SensorEventsCallback _callback;
183
184         internal override void EventListenStart()
185         {
186             _callback = (IntPtr sensorHandle, IntPtr eventPtr, uint events_count, IntPtr data) => {
187                 updateBatchEvents(eventPtr, events_count);
188                 Interop.SensorEventStruct sensorData = latestEvent();
189
190                 TimeSpan = new TimeSpan((Int64)sensorData.timestamp);
191                 StepCount = (uint)sensorData.values[0];
192                 WalkStepCount = (uint)sensorData.values[1];
193                 RunStepCount = (uint)sensorData.values[2];
194                 MovingDistance = sensorData.values[3];
195                 CalorieBurned = sensorData.values[4];
196                 LastSpeed = sensorData.values[5];
197                 LastSteppingFrequency = sensorData.values[6];
198                 LastStepStatus = (PedometerState)sensorData.values[7];
199
200                 DataUpdated?.Invoke(this, new PedometerDataUpdatedEventArgs(sensorData.values));
201             };
202
203             int error = Interop.SensorListener.SetEventsCallback(ListenerHandle, _callback, IntPtr.Zero);
204             if (error != (int)SensorError.None)
205             {
206                 Log.Error(Globals.LogTag, "Error setting event callback for pedometer sensor");
207                 throw SensorErrorFactory.CheckAndThrowException(error, "Unable to set event callback for pedometer");
208             }
209         }
210
211         internal override void EventListenStop()
212         {
213             int error = Interop.SensorListener.UnsetEventsCallback(ListenerHandle);
214             if (error != (int)SensorError.None)
215             {
216                 Log.Error(Globals.LogTag, "Error unsetting event callback for pedometer sensor");
217                 throw SensorErrorFactory.CheckAndThrowException(error, "Unable to unset event callback for pedometer");
218             }
219         }
220     }
221 }