b072e3a3a00eb99f48f237bedce0ba5dca2dca8c
[platform/core/csapi/tizenfx.git] / src / Tizen.Location.Geofence / Tizen.Location.Geofence / GeofenceManager.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.Location.Geofence
20 {
21     /// <summary>
22     /// This Geofence Manager API provides service related to geofence(geo-fence).
23     /// A geofence is a virtual perimeter for a real-world geographic area.
24     /// This API provides functions to set geofence with geopoint, MAC address of Wi-Fi and Bluetooth address.
25     /// And, notifications on events like changing in service status are provided.
26     /// <list type="ul">There are two kinds of places and fences:
27     /// <item>Public places and fences that are created by MyPlace app can be used by all apps.</item>
28     /// <item>Private places and fences that are created by specified app can be used by the same app.</item>
29     /// </list>
30     /// <list>Notifications can be received about the following events:
31     /// <item>Zone in when a device enters a specific area</item>
32     /// <item>Zone out when a device exits a specific area</item>
33     /// <item>Results and errors for each event requested to geofence module</item>
34     /// </list>
35     /// </summary>
36     public class GeofenceManager : IDisposable
37     {
38         private bool _disposed = false;
39
40         internal IntPtr Handle
41         {
42             get;
43             set;
44         }
45
46         /// <summary>
47         /// Creates a new geofence manager.
48         /// </summary>
49         /// <exception cref="OutOfMemoryException">Incase of OutOfMemory condition.</exception>
50         /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
51         /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
52         public GeofenceManager()
53         {
54             IntPtr handle;
55             GeofenceError ret = (GeofenceError) Interop.GeofenceManager.Create(out handle);
56             if(ret != GeofenceError.None)
57             {
58                 throw GeofenceErrorFactory.CreateException(ret, "Failed to create Geofence Manager instance");
59             }
60
61             Handle = handle;
62         }
63
64         ~GeofenceManager()
65         {
66             Dispose(false);
67         }
68
69         /// <summary>
70         /// Checks whether the geofence manager is available or not.
71         /// </summary>
72         public static bool IsSupported
73         {
74             get
75             {
76                 bool ret = false;
77                 GeofenceError res= (GeofenceError)Interop.GeofenceManager.IsSupported(out ret);
78                 if(res != GeofenceError.None)
79                 {
80                     Tizen.Log.Error(GeofenceErrorFactory.LogTag, "Failed to get IsSupported feature for Geofence manager");
81                 }
82
83                 return ret;
84             }
85         }
86
87         /// <summary>
88         /// Starts the geofencing service.
89         /// </summary>
90         /// <param name="geofenceId">The specified geofence id.</param>
91         /// <privilege>http://tizen.org/privilege/location</privilege>
92         /// <remarks>
93         /// When the location service is enabled, the StateChanged event is invoked and the service starts.
94         /// </remarks>
95         /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
96         /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
97         /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
98         /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
99         public void Start(int geofenceId)
100         {
101             GeofenceError ret = (GeofenceError)Interop.GeofenceManager.Start(Handle, geofenceId);
102             if (ret != GeofenceError.None)
103             {
104                 throw GeofenceErrorFactory.CreateException(ret, "Failed to start service for "  + geofenceId);
105             }
106         }
107
108         /// <summary>
109         /// Stops the geofenceing service.
110         /// </summary>
111         /// <param name="geofenceId">The specified geofence id.</param>
112         /// <privilege>http://tizen.org/privilege/location</privilege>
113         /// <remarks>
114         /// This function initiates the process of stopping the service.
115         /// You can stop and start the geofence manager as needed.
116         /// </remarks>
117         /// <exception cref="ArgumentException">Incase of Invalid parameter.</exception>
118         /// <exception cref="InvalidOperationException">Incase of any System error.</exception>
119         /// <exception cref="UnauthorizedAccessException">Incase of Privileges are not defined.</exception>
120         /// <exception cref="NotSupportedException">Incase of Geofence is not supported.</exception>
121         public void Stop(int geofenceId)
122         {
123             GeofenceError ret = (GeofenceError)Interop.GeofenceManager.Stop(Handle, geofenceId);
124             if (ret != GeofenceError.None)
125             {
126                 throw GeofenceErrorFactory.CreateException(ret, "Failed to stop service for " + geofenceId);
127             }
128         }
129
130         private static readonly Interop.GeofenceManager.StateChangedCallback s_stateChangedCallback = (int fenceId, GeofenceState state, IntPtr data) =>
131          {
132              GeofenceStateEventArgs evenArgs = new GeofenceStateEventArgs(fenceId, state);
133              s_stateChanged?.Invoke(null, evenArgs);
134              return true;
135          };
136
137         private static event EventHandler<GeofenceStateEventArgs> s_stateChanged = null;
138
139         /// <summary>
140         /// Invokes when a device enters or exits the given geofence, If this event is registered.
141         /// </summary>
142         /// <remarks>
143         /// Call to Start() will invoke this event.
144         /// </remarks>
145         /// <exception cref="NotSupportedException">Incase of feature Not supported.</exception>
146         public event EventHandler<GeofenceStateEventArgs> StateChanged
147         {
148             add
149             {
150                 if(s_stateChanged == null)
151                 {
152                     GeofenceError ret = (GeofenceError)Interop.GeofenceManager.SetStateChangedCB(Handle, s_stateChangedCallback, IntPtr.Zero);
153                     if (ret != GeofenceError.None)
154                     {
155                         throw GeofenceErrorFactory.CreateException(ret, "Failed to register state change callback");
156                     }
157                 }
158                 s_stateChanged += value;
159             }
160             remove
161             {
162                 s_stateChanged -= value;
163                 if (s_stateChanged == null)
164                 {
165                     GeofenceError ret = (GeofenceError)Interop.GeofenceManager.UnsetStateChangedCB(Handle);
166                     if (ret != GeofenceError.None)
167                     {
168                         throw GeofenceErrorFactory.CreateException(ret, "Failed to unregister state change callback");
169                     }
170                 }
171             }
172         }
173
174         private static readonly Interop.GeofenceManager.ProximityStateChangedCallback s_proximityChangedCallback = (int fenceId, ProximityState state, ProximityProvider provider, IntPtr data) =>
175         {
176             ProximityStateEventArgs evenArgs = new ProximityStateEventArgs(fenceId, state, provider);
177             s_proximityChanged?.Invoke(null, evenArgs);
178             return true;
179         };
180
181         private static event EventHandler<ProximityStateEventArgs> s_proximityChanged;
182
183         /// <summary>
184         /// Called when a proximity state of device is changed.
185         /// </summary>
186         /// <remarks>
187         /// Call to Start() will invoke this event.
188         /// </remarks>
189         /// <exception cref="NotSupportedException">Incase of feature Not supported.</exception>
190         public event EventHandler<ProximityStateEventArgs> ProximityChanged
191         {
192             add
193             {
194                 if (s_proximityChanged == null)
195                 {
196                     GeofenceError ret = (GeofenceError)Interop.GeofenceManager.SetProximityStateCB(Handle, s_proximityChangedCallback, IntPtr.Zero);
197                     if (ret != GeofenceError.None)
198                     {
199                         throw GeofenceErrorFactory.CreateException(ret, "Failed to register proximity change callback");
200                     }
201                     s_proximityChanged += value;
202                 }
203             }
204             remove
205             {
206                 s_proximityChanged -= value;
207                 if (s_proximityChanged == null)
208                 {
209                     GeofenceError ret = (GeofenceError)Interop.GeofenceManager.UnsetProximityStateCB(Handle);
210                     if (ret != GeofenceError.None)
211                     {
212                         throw GeofenceErrorFactory.CreateException(ret, "Failed to un register proximity change callback");
213                     }
214                 }
215             }
216         }
217
218         private static readonly Interop.GeofenceManager.GeofenceEventCallback s_geofenceEventCallback = (int placeId, int fenceId, GeofenceError error, GeoFenceEventType eventType, IntPtr data) =>
219         {
220             GeofenceResponseEventArgs evenArgs = new GeofenceResponseEventArgs(placeId, fenceId, error, eventType);
221             s_geofenceEventChanged?.Invoke(null, evenArgs);
222             return true;
223         };
224
225         private static event EventHandler<GeofenceResponseEventArgs> s_geofenceEventChanged;
226
227         /// <summary>
228         /// Called when the some event occurs in geofence and place such as add, update, etc..
229         /// The events of public geofence is also received if there are public geofences.
230         /// </summary>
231         /// <remarks>
232         /// Call to Start() will invoke this event.
233         /// The value of place_id or geofence_id is -1 when the place id or geofence id is not assigned.
234         /// </remarks>
235         /// <exception cref="NotSupportedException">Incase of feature Not supported.</exception>
236         public event EventHandler<GeofenceResponseEventArgs> GeoFenceEventChanged
237         {
238             add
239             {
240                 if (s_geofenceEventChanged == null)
241                 {
242                     GeofenceError ret = (GeofenceError)Interop.GeofenceManager.SetGeofenceEventCB(Handle, s_geofenceEventCallback, IntPtr.Zero);
243                     if (ret != GeofenceError.None)
244                     {
245                         throw GeofenceErrorFactory.CreateException(ret, "Failed to register geofence event change callback");
246                     }
247                     s_geofenceEventChanged += value;
248                 }
249             }
250             remove
251             {
252                 s_geofenceEventChanged -= value;
253                 if (s_geofenceEventChanged == null)
254                 {
255                     GeofenceError ret = (GeofenceError)Interop.GeofenceManager.UnsetGeofenceEventCB(Handle);
256                     if (ret != GeofenceError.None)
257                     {
258                         throw GeofenceErrorFactory.CreateException(ret, "Failed to unregister geofence event change callback");
259                     }
260                 }
261             }
262         }
263
264         /// <summary>
265         /// Overloaded Dispose API for destroying the GeofenceManager Handle.
266         /// </summary>
267         public void Dispose()
268         {
269             Dispose(true);
270             GC.SuppressFinalize(this);
271         }
272
273         private void Dispose(bool disposing)
274         {
275             if (_disposed)
276                 return;
277
278             if (Handle != IntPtr.Zero)
279             {
280                 Interop.GeofenceManager.Destroy(Handle);
281                 Handle = IntPtr.Zero;
282             }
283
284             _disposed = true;
285         }
286     }
287 }