1 /* Copyright (c) 2017-2019 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 #include <loc_pla.h>
40 #include <log_util.h>
41 
42 enum SESSION_MODE {
43     SESSION_MODE_NONE = 0,
44     SESSION_MODE_ON_FULL,
45     SESSION_MODE_ON_FIX,
46     SESSION_MODE_ON_TRIP_COMPLETED
47 };
48 
49 enum REQUEST_TYPE {
50     REQUEST_TRACKING = 0,
51     REQUEST_SESSION,
52     REQUEST_GEOFENCE,
53     REQUEST_NIRESPONSE,
54     REQUEST_MAX,
55 };
56 
57 enum CTRL_REQUEST_TYPE {
58     CTRL_REQUEST_DELETEAIDINGDATA = 0,
59     CTRL_REQUEST_CONTROL,
60     CTRL_REQUEST_CONFIG_UPDATE,
61     CTRL_REQUEST_CONFIG_GET,
62     CTRL_REQUEST_MAX,
63 };
64 
65 class LocationAPIClientBase;
66 
67 class LocationAPIRequest {
68 public:
LocationAPIRequest()69     LocationAPIRequest() {}
~LocationAPIRequest()70     virtual ~LocationAPIRequest() {}
onResponse(LocationError,uint32_t)71     virtual void onResponse(LocationError /*error*/, uint32_t /*id*/) {}
onCollectiveResponse(size_t,LocationError *,uint32_t *)72     virtual void onCollectiveResponse(
73             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
74 };
75 
76 class RequestQueue {
77 public:
RequestQueue()78     RequestQueue(): mSession(0), mSessionArrayPtr(nullptr) {
79     }
~RequestQueue()80     virtual ~RequestQueue() {
81         reset((uint32_t)0);
82     }
setSession(uint32_t session)83     void inline setSession(uint32_t session) { mSession = session; }
setSessionArrayPtr(uint32_t * ptr)84     void inline setSessionArrayPtr(uint32_t* ptr) { mSessionArrayPtr = ptr; }
reset(uint32_t session)85     void reset(uint32_t session) {
86         LocationAPIRequest* request = nullptr;
87         while (!mQueue.empty()) {
88             request = mQueue.front();
89             mQueue.pop();
90             delete request;
91         }
92         mSession = session;
93     }
reset(uint32_t * sessionArrayPtr)94     void reset(uint32_t* sessionArrayPtr) {
95         reset((uint32_t)0);
96         mSessionArrayPtr = sessionArrayPtr;
97     }
push(LocationAPIRequest * request)98     void push(LocationAPIRequest* request) {
99         mQueue.push(request);
100     }
pop()101     LocationAPIRequest* pop() {
102         LocationAPIRequest* request = nullptr;
103         if (!mQueue.empty()) {
104             request = mQueue.front();
105             mQueue.pop();
106         }
107         return request;
108     }
getSession()109     uint32_t getSession() { return mSession; }
getSessionArrayPtr()110     uint32_t* getSessionArrayPtr() { return mSessionArrayPtr; }
111 private:
112     uint32_t mSession;
113     uint32_t* mSessionArrayPtr;
114     std::queue<LocationAPIRequest*> mQueue;
115 };
116 
117 class LocationAPIControlClient {
118 public:
119     LocationAPIControlClient();
120     virtual ~LocationAPIControlClient();
121     LocationAPIControlClient(const LocationAPIControlClient&) = delete;
122     LocationAPIControlClient& operator=(const LocationAPIControlClient&) = delete;
123 
124     LocationAPIRequest* getRequestBySession(uint32_t session);
125     LocationAPIRequest* getRequestBySessionArrayPtr(uint32_t* sessionArrayPtr);
126 
127     // LocationControlAPI
128     uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
129     uint32_t locAPIEnable(LocationTechnologyType techType);
130     void locAPIDisable();
131     uint32_t locAPIGnssUpdateConfig(GnssConfig config);
132     uint32_t locAPIGnssGetConfig(GnssConfigFlagsMask config);
getControlAPI()133     inline LocationControlAPI* getControlAPI() { return mLocationControlAPI; }
134 
135     // callbacks
136     void onCtrlResponseCb(LocationError error, uint32_t id);
137     void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
138 
onGnssDeleteAidingDataCb(LocationError)139     inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {}
onEnableCb(LocationError)140     inline virtual void onEnableCb(LocationError /*error*/) {}
onDisableCb(LocationError)141     inline virtual void onDisableCb(LocationError /*error*/) {}
onGnssUpdateConfigCb(size_t,LocationError *,uint32_t *)142     inline virtual void onGnssUpdateConfigCb(
143             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onGnssGetConfigCb(size_t,LocationError *,uint32_t *)144     inline virtual void onGnssGetConfigCb(
145             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
146 
147     class GnssDeleteAidingDataRequest : public LocationAPIRequest {
148     public:
GnssDeleteAidingDataRequest(LocationAPIControlClient & API)149         GnssDeleteAidingDataRequest(LocationAPIControlClient& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)150         inline void onResponse(LocationError error, uint32_t /*id*/) {
151             mAPI.onGnssDeleteAidingDataCb(error);
152         }
153         LocationAPIControlClient& mAPI;
154     };
155 
156     class EnableRequest : public LocationAPIRequest {
157     public:
EnableRequest(LocationAPIControlClient & API)158         EnableRequest(LocationAPIControlClient& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)159         inline void onResponse(LocationError error, uint32_t /*id*/) {
160             mAPI.onEnableCb(error);
161         }
162         LocationAPIControlClient& mAPI;
163     };
164 
165     class DisableRequest : public LocationAPIRequest {
166     public:
DisableRequest(LocationAPIControlClient & API)167         DisableRequest(LocationAPIControlClient& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)168         inline void onResponse(LocationError error, uint32_t /*id*/) {
169             mAPI.onDisableCb(error);
170         }
171         LocationAPIControlClient& mAPI;
172     };
173 
174     class GnssUpdateConfigRequest : public LocationAPIRequest {
175     public:
GnssUpdateConfigRequest(LocationAPIControlClient & API)176         GnssUpdateConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * ids)177         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
178             mAPI.onGnssUpdateConfigCb(count, errors, ids);
179         }
180         LocationAPIControlClient& mAPI;
181     };
182 
183     class GnssGetConfigRequest : public LocationAPIRequest {
184     public:
GnssGetConfigRequest(LocationAPIControlClient & API)185         GnssGetConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * ids)186         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
187             mAPI.onGnssGetConfigCb(count, errors, ids);
188         }
189         LocationAPIControlClient& mAPI;
190     };
191 
192 private:
193     pthread_mutex_t mMutex;
194     LocationControlAPI* mLocationControlAPI;
195     RequestQueue mRequestQueues[CTRL_REQUEST_MAX];
196     bool mEnabled;
197     GnssConfig mConfig;
198 };
199 
200 class LocationAPIClientBase {
201 public:
202     LocationAPIClientBase();
203     virtual ~LocationAPIClientBase();
204     LocationAPIClientBase(const LocationAPIClientBase&) = delete;
205     LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;
206 
207     void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
208     void removeSession(uint32_t session);
209     LocationAPIRequest* getRequestBySession(uint32_t session);
210 
211     // LocationAPI
212     uint32_t locAPIStartTracking(TrackingOptions& trackingOptions);
213     void locAPIStopTracking();
214     void locAPIUpdateTrackingOptions(TrackingOptions& trackingOptions);
215 
216     int32_t locAPIGetBatchSize();
217     uint32_t locAPIStartSession(
218             uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
219     uint32_t locAPIStopSession(uint32_t id);
220     uint32_t locAPIUpdateSessionOptions(
221             uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
222     uint32_t locAPIGetBatchedLocations(uint32_t id, size_t count);
223 
224     uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
225             GeofenceOption* options, GeofenceInfo* data);
226     void locAPIRemoveGeofences(size_t count, uint32_t* ids);
227     void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
228     void locAPIPauseGeofences(size_t count, uint32_t* ids);
229     void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask);
230     void locAPIRemoveAllGeofences();
231 
232     void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response);
233 
234     // callbacks
235     void onResponseCb(LocationError error, uint32_t id);
236     void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
237 
238     void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification);
239 
onCapabilitiesCb(LocationCapabilitiesMask)240     inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
onGnssNmeaCb(GnssNmeaNotification)241     inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
onGnssDataCb(GnssDataNotification)242     inline virtual void onGnssDataCb(GnssDataNotification /*gnssDataNotification*/) {}
onGnssMeasurementsCb(GnssMeasurementsNotification)243     inline virtual void onGnssMeasurementsCb(
244             GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
245 
onTrackingCb(Location)246     inline virtual void onTrackingCb(Location /*location*/) {}
onGnssSvCb(GnssSvNotification)247     inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {}
onStartTrackingCb(LocationError)248     inline virtual void onStartTrackingCb(LocationError /*error*/) {}
onStopTrackingCb(LocationError)249     inline virtual void onStopTrackingCb(LocationError /*error*/) {}
onUpdateTrackingOptionsCb(LocationError)250     inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {}
251 
onGnssLocationInfoCb(GnssLocationInfoNotification)252     inline virtual void onGnssLocationInfoCb(
253             GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}
254 
onBatchingCb(size_t,Location *,BatchingOptions)255     inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/,
256             BatchingOptions /*batchingOptions*/) {}
onBatchingStatusCb(BatchingStatusInfo,std::list<uint32_t> &)257     inline virtual void onBatchingStatusCb(BatchingStatusInfo /*batchingStatus*/,
258             std::list<uint32_t> &/*listOfCompletedTrips*/) {}
259     void beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
260             std::list<uint32_t> & tripCompletedList);
onStartBatchingCb(LocationError)261     inline virtual void onStartBatchingCb(LocationError /*error*/) {}
onStopBatchingCb(LocationError)262     inline virtual void onStopBatchingCb(LocationError /*error*/) {}
onUpdateBatchingOptionsCb(LocationError)263     inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {}
onGetBatchedLocationsCb(LocationError)264     inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {}
265 
onGeofenceBreachCb(GeofenceBreachNotification)266     inline virtual void onGeofenceBreachCb(
267             GeofenceBreachNotification /*geofenceBreachNotification*/) {}
onGeofenceStatusCb(GeofenceStatusNotification)268     inline virtual void onGeofenceStatusCb(
269             GeofenceStatusNotification /*geofenceStatusNotification*/) {}
onAddGeofencesCb(size_t,LocationError *,uint32_t *)270     inline virtual void onAddGeofencesCb(
271             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onRemoveGeofencesCb(size_t,LocationError *,uint32_t *)272     inline virtual void onRemoveGeofencesCb(
273             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onModifyGeofencesCb(size_t,LocationError *,uint32_t *)274     inline virtual void onModifyGeofencesCb(
275             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onPauseGeofencesCb(size_t,LocationError *,uint32_t *)276     inline virtual void onPauseGeofencesCb(
277             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onResumeGeofencesCb(size_t,LocationError *,uint32_t *)278     inline virtual void onResumeGeofencesCb(
279             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
280 
onGnssNiCb(uint32_t,GnssNiNotification)281     inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
onGnssNiResponseCb(LocationError)282     inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}
283 
onLocationSystemInfoCb(LocationSystemInfo)284     inline virtual void onLocationSystemInfoCb(LocationSystemInfo /*locationSystemInfo*/) {}
285 
286 private:
287     // private inner classes
288     typedef struct {
289         uint32_t id;
290         uint32_t trackingSession;
291         uint32_t batchingSession;
292         uint32_t sessionMode;
293     } SessionEntity;
294 
295     template<typename T>
296     class BiDict {
297     public:
BiDict()298         BiDict() {
299             pthread_mutex_init(&mBiDictMutex, nullptr);
300         }
~BiDict()301         virtual ~BiDict() {
302             pthread_mutex_destroy(&mBiDictMutex);
303         }
hasId(uint32_t id)304         bool hasId(uint32_t id) {
305             pthread_mutex_lock(&mBiDictMutex);
306             bool ret = (mForwardMap.find(id) != mForwardMap.end());
307             pthread_mutex_unlock(&mBiDictMutex);
308             return ret;
309         }
hasSession(uint32_t session)310         bool hasSession(uint32_t session) {
311             pthread_mutex_lock(&mBiDictMutex);
312             bool ret = (mBackwardMap.find(session) != mBackwardMap.end());
313             pthread_mutex_unlock(&mBiDictMutex);
314             return ret;
315         }
set(uint32_t id,uint32_t session,T & ext)316         void set(uint32_t id, uint32_t session, T& ext) {
317             pthread_mutex_lock(&mBiDictMutex);
318             mForwardMap[id] = session;
319             mBackwardMap[session] = id;
320             mExtMap[session] = ext;
321             pthread_mutex_unlock(&mBiDictMutex);
322         }
clear()323         void clear() {
324             pthread_mutex_lock(&mBiDictMutex);
325             mForwardMap.clear();
326             mBackwardMap.clear();
327             mExtMap.clear();
328             pthread_mutex_unlock(&mBiDictMutex);
329         }
rmById(uint32_t id)330         void rmById(uint32_t id) {
331             pthread_mutex_lock(&mBiDictMutex);
332             mBackwardMap.erase(mForwardMap[id]);
333             mExtMap.erase(mForwardMap[id]);
334             mForwardMap.erase(id);
335             pthread_mutex_unlock(&mBiDictMutex);
336         }
rmBySession(uint32_t session)337         void rmBySession(uint32_t session) {
338             pthread_mutex_lock(&mBiDictMutex);
339             mForwardMap.erase(mBackwardMap[session]);
340             mBackwardMap.erase(session);
341             mExtMap.erase(session);
342             pthread_mutex_unlock(&mBiDictMutex);
343         }
getId(uint32_t session)344         uint32_t getId(uint32_t session) {
345             pthread_mutex_lock(&mBiDictMutex);
346             uint32_t ret = 0;
347             auto it = mBackwardMap.find(session);
348             if (it != mBackwardMap.end()) {
349                 ret = it->second;
350             }
351             pthread_mutex_unlock(&mBiDictMutex);
352             return ret;
353         }
getSession(uint32_t id)354         uint32_t getSession(uint32_t id) {
355             pthread_mutex_lock(&mBiDictMutex);
356             uint32_t ret = 0;
357             auto it = mForwardMap.find(id);
358             if (it != mForwardMap.end()) {
359                 ret = it->second;
360             }
361             pthread_mutex_unlock(&mBiDictMutex);
362             return ret;
363         }
getExtById(uint32_t id)364         T getExtById(uint32_t id) {
365             pthread_mutex_lock(&mBiDictMutex);
366             T ret;
367             memset(&ret, 0, sizeof(T));
368             uint32_t session = mForwardMap[id];
369             if (session > 0) {
370                 auto it = mExtMap.find(session);
371                 if (it != mExtMap.end()) {
372                     ret = it->second;
373                 }
374             }
375             pthread_mutex_unlock(&mBiDictMutex);
376             return ret;
377         }
getExtBySession(uint32_t session)378         T getExtBySession(uint32_t session) {
379             pthread_mutex_lock(&mBiDictMutex);
380             T ret;
381             memset(&ret, 0, sizeof(T));
382             auto it = mExtMap.find(session);
383             if (it != mExtMap.end()) {
384                 ret = it->second;
385             }
386             pthread_mutex_unlock(&mBiDictMutex);
387             return ret;
388         }
getAllSessions()389         std::vector<uint32_t> getAllSessions() {
390             std::vector<uint32_t> ret;
391             pthread_mutex_lock(&mBiDictMutex);
392             for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) {
393                 ret.push_back(it->first);
394             }
395             pthread_mutex_unlock(&mBiDictMutex);
396             return ret;
397         }
398     private:
399         pthread_mutex_t mBiDictMutex;
400         // mForwarMap mapping id->session
401         std::map<uint32_t, uint32_t> mForwardMap;
402         // mBackwardMap mapping session->id
403         std::map<uint32_t, uint32_t> mBackwardMap;
404         // mExtMap mapping session->ext
405         std::map<uint32_t, T> mExtMap;
406     };
407 
408     class StartTrackingRequest : public LocationAPIRequest {
409     public:
StartTrackingRequest(LocationAPIClientBase & API)410         StartTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)411         inline void onResponse(LocationError error, uint32_t id) {
412             if (error != LOCATION_ERROR_SUCCESS) {
413                 mAPI.removeSession(id);
414             }
415             mAPI.onStartTrackingCb(error);
416         }
417         LocationAPIClientBase& mAPI;
418     };
419 
420     class StopTrackingRequest : public LocationAPIRequest {
421     public:
StopTrackingRequest(LocationAPIClientBase & API)422         StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)423         inline void onResponse(LocationError error, uint32_t id) {
424             mAPI.onStopTrackingCb(error);
425             if (error == LOCATION_ERROR_SUCCESS) {
426                 mAPI.removeSession(id);
427             }
428         }
429         LocationAPIClientBase& mAPI;
430     };
431 
432     class UpdateTrackingOptionsRequest : public LocationAPIRequest {
433     public:
UpdateTrackingOptionsRequest(LocationAPIClientBase & API)434         UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)435         inline void onResponse(LocationError error, uint32_t /*id*/) {
436             mAPI.onUpdateTrackingOptionsCb(error);
437         }
438         LocationAPIClientBase& mAPI;
439     };
440 
441     class StartBatchingRequest : public LocationAPIRequest {
442     public:
StartBatchingRequest(LocationAPIClientBase & API)443         StartBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)444         inline void onResponse(LocationError error, uint32_t id) {
445             if (error != LOCATION_ERROR_SUCCESS) {
446                 mAPI.removeSession(id);
447             }
448             mAPI.onStartBatchingCb(error);
449         }
450         LocationAPIClientBase& mAPI;
451     };
452 
453     class StopBatchingRequest : public LocationAPIRequest {
454     public:
StopBatchingRequest(LocationAPIClientBase & API)455         StopBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)456         inline void onResponse(LocationError error, uint32_t id) {
457             mAPI.onStopBatchingCb(error);
458             if (error == LOCATION_ERROR_SUCCESS) {
459                 mAPI.removeSession(id);
460             }
461         }
462         LocationAPIClientBase& mAPI;
463     };
464 
465     class UpdateBatchingOptionsRequest : public LocationAPIRequest {
466     public:
UpdateBatchingOptionsRequest(LocationAPIClientBase & API)467         UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)468         inline void onResponse(LocationError error, uint32_t /*id*/) {
469             mAPI.onUpdateBatchingOptionsCb(error);
470         }
471         LocationAPIClientBase& mAPI;
472     };
473 
474     class GetBatchedLocationsRequest : public LocationAPIRequest {
475     public:
GetBatchedLocationsRequest(LocationAPIClientBase & API)476         GetBatchedLocationsRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)477         inline void onResponse(LocationError error, uint32_t /*id*/) {
478             mAPI.onGetBatchedLocationsCb(error);
479         }
480         LocationAPIClientBase& mAPI;
481     };
482 
483     class AddGeofencesRequest : public LocationAPIRequest {
484     public:
AddGeofencesRequest(LocationAPIClientBase & API)485         AddGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)486         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
487             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
488             for (size_t i = 0; i < count; i++) {
489                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
490             }
491             LOC_LOGD("%s:]Returned geofence-id: %d in add geofence", __FUNCTION__, *ids);
492             mAPI.onAddGeofencesCb(count, errors, ids);
493             free(ids);
494         }
495         LocationAPIClientBase& mAPI;
496     };
497 
498     class RemoveGeofencesRequest : public LocationAPIRequest {
499     public:
RemoveGeofencesRequest(LocationAPIClientBase & API,BiDict<GeofenceBreachTypeMask> * removedGeofenceBiDict)500         RemoveGeofencesRequest(LocationAPIClientBase& API,
501                                BiDict<GeofenceBreachTypeMask>* removedGeofenceBiDict) :
502                                mAPI(API), mRemovedGeofenceBiDict(removedGeofenceBiDict) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)503         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
504             if (nullptr != mRemovedGeofenceBiDict) {
505                 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
506                 for (size_t i = 0; i < count; i++) {
507                     ids[i] = mRemovedGeofenceBiDict->getId(sessions[i]);
508                 }
509                 LOC_LOGD("%s:]Returned geofence-id: %d in remove geofence", __FUNCTION__, *ids);
510                 mAPI.onRemoveGeofencesCb(count, errors, ids);
511                 free(ids);
512                 delete(mRemovedGeofenceBiDict);
513             } else {
514                 LOC_LOGE("%s:%d] Unable to access removed geofences data.", __FUNCTION__, __LINE__);
515             }
516         }
517         LocationAPIClientBase& mAPI;
518         BiDict<GeofenceBreachTypeMask>* mRemovedGeofenceBiDict;
519     };
520 
521     class ModifyGeofencesRequest : public LocationAPIRequest {
522     public:
ModifyGeofencesRequest(LocationAPIClientBase & API)523         ModifyGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)524         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
525             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
526             for (size_t i = 0; i < count; i++) {
527                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
528             }
529             mAPI.onModifyGeofencesCb(count, errors, ids);
530             free(ids);
531         }
532         LocationAPIClientBase& mAPI;
533     };
534 
535     class PauseGeofencesRequest : public LocationAPIRequest {
536     public:
PauseGeofencesRequest(LocationAPIClientBase & API)537         PauseGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)538         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
539             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
540             for (size_t i = 0; i < count; i++) {
541                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
542             }
543             mAPI.onPauseGeofencesCb(count, errors, ids);
544             free(ids);
545         }
546         LocationAPIClientBase& mAPI;
547     };
548 
549     class ResumeGeofencesRequest : public LocationAPIRequest {
550     public:
ResumeGeofencesRequest(LocationAPIClientBase & API)551         ResumeGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)552         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
553             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
554             for (size_t i = 0; i < count; i++) {
555                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
556             }
557             mAPI.onResumeGeofencesCb(count, errors, ids);
558             free(ids);
559         }
560         LocationAPIClientBase& mAPI;
561     };
562 
563     class GnssNiResponseRequest : public LocationAPIRequest {
564     public:
GnssNiResponseRequest(LocationAPIClientBase & API)565         GnssNiResponseRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)566         inline void onResponse(LocationError error, uint32_t /*id*/) {
567             mAPI.onGnssNiResponseCb(error);
568         }
569         LocationAPIClientBase& mAPI;
570     };
571 
572 private:
573     pthread_mutex_t mMutex;
574 
575     geofenceBreachCallback mGeofenceBreachCallback;
576     batchingStatusCallback mBatchingStatusCallback;
577 
578     LocationAPI* mLocationAPI;
579 
580     RequestQueue mRequestQueues[REQUEST_MAX];
581     BiDict<GeofenceBreachTypeMask> mGeofenceBiDict;
582     BiDict<SessionEntity> mSessionBiDict;
583     int32_t mBatchSize;
584     bool mTracking;
585 };
586 
587 #endif /* LOCATION_API_CLINET_BASE_H */
588