• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2017 The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef LOCATION_API_CLINET_BASE_H
30 #define LOCATION_API_CLINET_BASE_H
31 
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <pthread.h>
35 #include <queue>
36 #include <map>
37 
38 #include "LocationAPI.h"
39 
40 enum SESSION_MODE {
41     SESSION_MODE_NONE = 0,
42     SESSION_MODE_ON_FULL,
43     SESSION_MODE_ON_FIX,
44 };
45 
46 enum REQUEST_TYPE {
47     REQUEST_TRACKING = 0,
48     REQUEST_BATCHING,
49     REQUEST_GEOFENCE,
50     REQUEST_NIRESPONSE,
51     REQUEST_DELETEAIDINGDATA,
52     REQUEST_CONTROL,
53     REQUEST_CONFIG,
54     REQUEST_MAX,
55 };
56 
57 class LocationAPIClientBase
58 {
59 public:
60     LocationAPIClientBase();
61     virtual ~LocationAPIClientBase();
62     LocationAPIClientBase(const LocationAPIClientBase&) = delete;
63     LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;
64 
65     void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
66 
67     // LocationAPI
68     uint32_t locAPIStartTracking(LocationOptions& options);
69     void locAPIStopTracking();
70     void locAPIUpdateTrackingOptions(LocationOptions& options);
71 
72     int32_t locAPIGetBatchSize();
73     uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode,
74             LocationOptions& options);
75     uint32_t locAPIStopSession(uint32_t id);
76     uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
77             LocationOptions& options);
78     void locAPIGetBatchedLocations(size_t count);
79 
80     uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
81             GeofenceOption* options, GeofenceInfo* data);
82     void locAPIRemoveGeofences(size_t count, uint32_t* ids);
83     void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
84     void locAPIPauseGeofences(size_t count, uint32_t* ids);
85     void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask);
86     void locAPIRemoveAllGeofences();
87 
88     void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response);
89     uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
90 
91     uint32_t locAPIEnable(LocationTechnologyType techType);
92     void locAPIDisable();
93     uint32_t locAPIGnssUpdateConfig(GnssConfig config);
94 
95     // callbacks
96     void onResponseCb(LocationError error, uint32_t id);
97     void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
98 
99     void onCtrlResponseCb(LocationError error, uint32_t id);
100     void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
101 
102     void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification);
103 
onCapabilitiesCb(LocationCapabilitiesMask)104     inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
onGnssNmeaCb(GnssNmeaNotification)105     inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
onGnssMeasurementsCb(GnssMeasurementsNotification)106     inline virtual void onGnssMeasurementsCb(
107             GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
108 
onTrackingCb(Location)109     inline virtual void onTrackingCb(Location /*location*/) {}
onGnssSvCb(GnssSvNotification)110     inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {}
onStartTrackingCb(LocationError)111     inline virtual void onStartTrackingCb(LocationError /*error*/) {}
onStopTrackingCb(LocationError)112     inline virtual void onStopTrackingCb(LocationError /*error*/) {}
onUpdateTrackingOptionsCb(LocationError)113     inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {}
114 
onGnssLocationInfoCb(GnssLocationInfoNotification)115     inline virtual void onGnssLocationInfoCb(
116             GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}
117 
onBatchingCb(size_t,Location *)118     inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/) {}
onStartBatchingCb(LocationError)119     inline virtual void onStartBatchingCb(LocationError /*error*/) {}
onStopBatchingCb(LocationError)120     inline virtual void onStopBatchingCb(LocationError /*error*/) {}
onUpdateBatchingOptionsCb(LocationError)121     inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {}
onGetBatchedLocationsCb(LocationError)122     inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {}
123 
onGeofenceBreachCb(GeofenceBreachNotification)124     inline virtual void onGeofenceBreachCb(
125             GeofenceBreachNotification /*geofenceBreachNotification*/) {}
onGeofenceStatusCb(GeofenceStatusNotification)126     inline virtual void onGeofenceStatusCb(
127             GeofenceStatusNotification /*geofenceStatusNotification*/) {}
onAddGeofencesCb(size_t,LocationError *,uint32_t *)128     inline virtual void onAddGeofencesCb(
129             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onRemoveGeofencesCb(size_t,LocationError *,uint32_t *)130     inline virtual void onRemoveGeofencesCb(
131             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onModifyGeofencesCb(size_t,LocationError *,uint32_t *)132     inline virtual void onModifyGeofencesCb(
133             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onPauseGeofencesCb(size_t,LocationError *,uint32_t *)134     inline virtual void onPauseGeofencesCb(
135             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onResumeGeofencesCb(size_t,LocationError *,uint32_t *)136     inline virtual void onResumeGeofencesCb(
137             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
138 
onGnssNiCb(uint32_t,GnssNiNotification)139     inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
onGnssNiResponseCb(LocationError)140     inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}
onGnssDeleteAidingDataCb(LocationError)141     inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {}
142 
onEnableCb(LocationError)143     inline virtual void onEnableCb(LocationError /*error*/) {}
onDisableCb(LocationError)144     inline virtual void onDisableCb(LocationError /*error*/) {}
onGnssUpdateConfigCb(size_t,LocationError *,uint32_t *)145     inline virtual void onGnssUpdateConfigCb(
146             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
147 
148 private:
149     // private inner classes
150     typedef struct {
151         uint32_t id;
152         uint32_t trackingSession;
153         uint32_t batchingSession;
154         uint32_t sessionMode;
155     } SessionEntity;
156 
157     class BiDict {
158     public:
BiDict()159         BiDict() {
160             pthread_mutex_init(&mBiDictMutex, nullptr);
161         }
~BiDict()162         ~BiDict() {
163             pthread_mutex_destroy(&mBiDictMutex);
164         }
hasId(uint32_t id)165         bool hasId(uint32_t id) {
166             pthread_mutex_lock(&mBiDictMutex);
167             bool ret = (mForwardMap.find(id) != mForwardMap.end());
168             pthread_mutex_unlock(&mBiDictMutex);
169             return ret;
170         }
set(uint32_t id,uint32_t session,uint32_t type)171         void set(uint32_t id, uint32_t session, uint32_t type) {
172             pthread_mutex_lock(&mBiDictMutex);
173             mForwardMap[id] = session;
174             mBackwardMap[session] = id;
175             mTypeMap[session] = type;
176             pthread_mutex_unlock(&mBiDictMutex);
177         }
clear()178         void clear() {
179             pthread_mutex_lock(&mBiDictMutex);
180             mForwardMap.clear();
181             mBackwardMap.clear();
182             mTypeMap.clear();
183             pthread_mutex_unlock(&mBiDictMutex);
184         }
rmById(uint32_t id)185         void rmById(uint32_t id) {
186             pthread_mutex_lock(&mBiDictMutex);
187             mBackwardMap.erase(mForwardMap[id]);
188             mTypeMap.erase(mForwardMap[id]);
189             mForwardMap.erase(id);
190             pthread_mutex_unlock(&mBiDictMutex);
191         }
rmBySession(uint32_t session)192         void rmBySession(uint32_t session) {
193             pthread_mutex_lock(&mBiDictMutex);
194             mForwardMap.erase(mBackwardMap[session]);
195             mBackwardMap.erase(session);
196             mTypeMap.erase(session);
197             pthread_mutex_unlock(&mBiDictMutex);
198         }
getId(uint32_t session)199         uint32_t getId(uint32_t session) {
200             pthread_mutex_lock(&mBiDictMutex);
201             uint32_t ret = 0;
202             auto it = mBackwardMap.find(session);
203             if (it != mBackwardMap.end()) {
204                 ret = it->second;
205             }
206             pthread_mutex_unlock(&mBiDictMutex);
207             return ret;
208         }
getSession(uint32_t id)209         uint32_t getSession(uint32_t id) {
210             pthread_mutex_lock(&mBiDictMutex);
211             uint32_t ret = 0;
212             auto it = mForwardMap.find(id);
213             if (it != mForwardMap.end()) {
214                 ret = it->second;
215             }
216             pthread_mutex_unlock(&mBiDictMutex);
217             return ret;
218         }
getType(uint32_t session)219         uint32_t getType(uint32_t session) {
220             pthread_mutex_lock(&mBiDictMutex);
221             uint32_t ret = 0;
222             auto it = mTypeMap.find(session);
223             if (it != mTypeMap.end()) {
224                 ret = it->second;
225             }
226             pthread_mutex_unlock(&mBiDictMutex);
227             return ret;
228         }
getAllSessions()229         std::vector<uint32_t> getAllSessions() {
230             std::vector<uint32_t> ret;
231             pthread_mutex_lock(&mBiDictMutex);
232             for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) {
233                 ret.push_back(it->first);
234             }
235             pthread_mutex_unlock(&mBiDictMutex);
236             return ret;
237         }
238     private:
239         pthread_mutex_t mBiDictMutex;
240         // mForwarMap mapping id->session
241         std::map<uint32_t, uint32_t> mForwardMap;
242         // mBackwardMap mapping session->id
243         std::map<uint32_t, uint32_t> mBackwardMap;
244         // mTypeMap mapping session->type
245         std::map<uint32_t, uint32_t> mTypeMap;
246     };
247 
248     class LocationAPIRequest {
249     public:
LocationAPIRequest(LocationAPIClientBase & API)250         LocationAPIRequest(LocationAPIClientBase& API) : mAPI(API) {}
~LocationAPIRequest()251         virtual ~LocationAPIRequest() {}
onResponse(LocationError)252         virtual void onResponse(LocationError /*error*/) {};
onCollectiveResponse(size_t,LocationError *,uint32_t *)253         virtual void onCollectiveResponse(
254                 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {};
255         LocationAPIClientBase& mAPI;
256     };
257 
258     class StartTrackingRequest : public LocationAPIRequest {
259     public:
StartTrackingRequest(LocationAPIClientBase & API)260         StartTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)261         inline void onResponse(LocationError error) {
262             mAPI.onStartTrackingCb(error);
263         }
264     };
265 
266     class StopTrackingRequest : public LocationAPIRequest {
267     public:
StopTrackingRequest(LocationAPIClientBase & API)268         StopTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)269         inline void onResponse(LocationError error) {
270             mAPI.onStopTrackingCb(error);
271         }
272     };
273 
274     class UpdateTrackingOptionsRequest : public LocationAPIRequest {
275     public:
UpdateTrackingOptionsRequest(LocationAPIClientBase & API)276         UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)277         inline void onResponse(LocationError error) {
278             mAPI.onUpdateTrackingOptionsCb(error);
279         }
280     };
281 
282     class StartBatchingRequest : public LocationAPIRequest {
283     public:
StartBatchingRequest(LocationAPIClientBase & API)284         StartBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)285         inline void onResponse(LocationError error) {
286             mAPI.onStartBatchingCb(error);
287         }
288     };
289 
290     class StopBatchingRequest : public LocationAPIRequest {
291     public:
StopBatchingRequest(LocationAPIClientBase & API)292         StopBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)293         inline void onResponse(LocationError error) {
294             mAPI.onStopBatchingCb(error);
295         }
296     };
297 
298     class UpdateBatchingOptionsRequest : public LocationAPIRequest {
299     public:
UpdateBatchingOptionsRequest(LocationAPIClientBase & API)300         UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)301         inline void onResponse(LocationError error) {
302             mAPI.onUpdateBatchingOptionsCb(error);
303         }
304     };
305 
306     class GetBatchedLocationsRequest : public LocationAPIRequest {
307     public:
GetBatchedLocationsRequest(LocationAPIClientBase & API)308         GetBatchedLocationsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)309         inline void onResponse(LocationError error) {
310             mAPI.onGetBatchedLocationsCb(error);
311         }
312     };
313 
314     class AddGeofencesRequest : public LocationAPIRequest {
315     public:
AddGeofencesRequest(LocationAPIClientBase & API)316         AddGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)317         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
318             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
319             for (size_t i = 0; i < count; i++) {
320                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
321             }
322             mAPI.onAddGeofencesCb(count, errors, ids);
323             free(ids);
324         }
325     };
326 
327     class RemoveGeofencesRequest : public LocationAPIRequest {
328     public:
RemoveGeofencesRequest(LocationAPIClientBase & API)329         RemoveGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)330         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
331             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
332             for (size_t i = 0; i < count; i++) {
333                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
334                 mAPI.mGeofenceBiDict.rmBySession(sessions[i]);
335             }
336             mAPI.onRemoveGeofencesCb(count, errors, ids);
337             free(ids);
338         }
339     };
340 
341     class ModifyGeofencesRequest : public LocationAPIRequest {
342     public:
ModifyGeofencesRequest(LocationAPIClientBase & API)343         ModifyGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)344         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
345             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
346             for (size_t i = 0; i < count; i++) {
347                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
348             }
349             mAPI.onModifyGeofencesCb(count, errors, ids);
350             free(ids);
351         }
352     };
353 
354     class PauseGeofencesRequest : public LocationAPIRequest {
355     public:
PauseGeofencesRequest(LocationAPIClientBase & API)356         PauseGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)357         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
358             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
359             for (size_t i = 0; i < count; i++) {
360                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
361             }
362             mAPI.onPauseGeofencesCb(count, errors, ids);
363             free(ids);
364         }
365     };
366 
367     class ResumeGeofencesRequest : public LocationAPIRequest {
368     public:
ResumeGeofencesRequest(LocationAPIClientBase & API)369         ResumeGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)370         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
371             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
372             for (size_t i = 0; i < count; i++) {
373                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
374             }
375             mAPI.onResumeGeofencesCb(count, errors, ids);
376             free(ids);
377         }
378     };
379 
380     class GnssNiResponseRequest : public LocationAPIRequest {
381     public:
GnssNiResponseRequest(LocationAPIClientBase & API)382         GnssNiResponseRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)383         inline void onResponse(LocationError error) {
384             mAPI.onGnssNiResponseCb(error);
385         }
386     };
387 
388     class GnssDeleteAidingDataRequest : public LocationAPIRequest {
389     public:
GnssDeleteAidingDataRequest(LocationAPIClientBase & API)390         GnssDeleteAidingDataRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)391         inline void onResponse(LocationError error) {
392             mAPI.onGnssDeleteAidingDataCb(error);
393         }
394     };
395 
396     class EnableRequest : public LocationAPIRequest {
397     public:
EnableRequest(LocationAPIClientBase & API)398         EnableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)399         inline void onResponse(LocationError error) {
400             mAPI.onEnableCb(error);
401         }
402     };
403 
404     class DisableRequest : public LocationAPIRequest {
405     public:
DisableRequest(LocationAPIClientBase & API)406         DisableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onResponse(LocationError error)407         inline void onResponse(LocationError error) {
408             mAPI.onDisableCb(error);
409         }
410     };
411 
412     class GnssUpdateConfigRequest : public LocationAPIRequest {
413     public:
GnssUpdateConfigRequest(LocationAPIClientBase & API)414         GnssUpdateConfigRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * ids)415         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
416             mAPI.onGnssUpdateConfigCb(count, errors, ids);
417         }
418     };
419 
420     class RequestQueue {
421     public:
RequestQueue(uint32_t session)422         RequestQueue(uint32_t session): mSession(session) {
423         }
~RequestQueue()424         ~RequestQueue() {
425             LocationAPIRequest* request = nullptr;
426             while (!mQueue.empty()) {
427                 request = mQueue.front();
428                 mQueue.pop();
429                 delete request;
430             }
431         }
push(LocationAPIRequest * request)432         void push(LocationAPIRequest* request) {
433             mQueue.push(request);
434         }
pop()435         LocationAPIRequest* pop() {
436             LocationAPIRequest* request = nullptr;
437             if (!mQueue.empty()) {
438                 request = mQueue.front();
439                 mQueue.pop();
440             }
441             return request;
442         }
getSession()443         uint32_t getSession() { return mSession; }
444     private:
445         uint32_t mSession;
446         std::queue<LocationAPIRequest*> mQueue;
447     };
448 
449     LocationAPIRequest* getRequestBySession(uint32_t session);
450 
451 private:
452     pthread_mutex_t mMutex;
453 
454     trackingCallback mTrackingCallback;
455     batchingCallback mBatchingCallback;
456     geofenceBreachCallback mGeofenceBreachCallback;
457 
458     LocationAPI* mLocationAPI;
459     LocationControlAPI* mLocationControlAPI;
460 
461     BiDict mGeofenceBiDict;
462     RequestQueue* mRequestQueues[REQUEST_MAX];
463     std::map<uint32_t, SessionEntity> mSessionMap;
464     int32_t mBatchSize;
465     bool mEnabled;
466     bool mTracking;
467 
468     GnssConfig mConfig;
469 };
470 
471 #endif /* LOCATION_API_CLINET_BASE_H */
472