1 /* Copyright (c) 2017-2020 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     LocationAPIClientBase(const LocationAPIClientBase&) = delete;
204     LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;
205 
206     void destroy();
207     void onLocationApiDestroyCompleteCb();
208 
209     void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
210     void removeSession(uint32_t session);
211     LocationAPIRequest* getRequestBySession(uint32_t session);
212 
213     // LocationAPI
214     uint32_t locAPIStartTracking(TrackingOptions& trackingOptions);
215     void locAPIStopTracking();
216     void locAPIUpdateTrackingOptions(TrackingOptions& trackingOptions);
217 
218     int32_t locAPIGetBatchSize();
219     uint32_t locAPIStartSession(
220             uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
221     uint32_t locAPIStopSession(uint32_t id);
222     uint32_t locAPIUpdateSessionOptions(
223             uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
224     uint32_t locAPIGetBatchedLocations(uint32_t id, size_t count);
225 
226     uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
227             GeofenceOption* options, GeofenceInfo* data);
228     void locAPIRemoveGeofences(size_t count, uint32_t* ids);
229     void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
230     void locAPIPauseGeofences(size_t count, uint32_t* ids);
231     void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask);
232     void locAPIRemoveAllGeofences();
233 
234     void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response);
235 
236     // callbacks
237     void onResponseCb(LocationError error, uint32_t id);
238     void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
239 
240     void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification);
241 
onCapabilitiesCb(LocationCapabilitiesMask)242     inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
onGnssNmeaCb(GnssNmeaNotification)243     inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
onGnssDataCb(GnssDataNotification)244     inline virtual void onGnssDataCb(GnssDataNotification /*gnssDataNotification*/) {}
onGnssMeasurementsCb(GnssMeasurementsNotification)245     inline virtual void onGnssMeasurementsCb(
246             GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
247 
onTrackingCb(Location)248     inline virtual void onTrackingCb(Location /*location*/) {}
onGnssSvCb(GnssSvNotification)249     inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {}
onStartTrackingCb(LocationError)250     inline virtual void onStartTrackingCb(LocationError /*error*/) {}
onStopTrackingCb(LocationError)251     inline virtual void onStopTrackingCb(LocationError /*error*/) {}
onUpdateTrackingOptionsCb(LocationError)252     inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {}
253 
onGnssLocationInfoCb(GnssLocationInfoNotification)254     inline virtual void onGnssLocationInfoCb(
255             GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}
256 
onBatchingCb(size_t,Location *,BatchingOptions)257     inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/,
258             BatchingOptions /*batchingOptions*/) {}
onBatchingStatusCb(BatchingStatusInfo,std::list<uint32_t> &)259     inline virtual void onBatchingStatusCb(BatchingStatusInfo /*batchingStatus*/,
260             std::list<uint32_t> &/*listOfCompletedTrips*/) {}
261     void beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
262             std::list<uint32_t> & tripCompletedList);
onStartBatchingCb(LocationError)263     inline virtual void onStartBatchingCb(LocationError /*error*/) {}
onStopBatchingCb(LocationError)264     inline virtual void onStopBatchingCb(LocationError /*error*/) {}
onUpdateBatchingOptionsCb(LocationError)265     inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {}
onGetBatchedLocationsCb(LocationError)266     inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {}
267 
onGeofenceBreachCb(GeofenceBreachNotification)268     inline virtual void onGeofenceBreachCb(
269             GeofenceBreachNotification /*geofenceBreachNotification*/) {}
onGeofenceStatusCb(GeofenceStatusNotification)270     inline virtual void onGeofenceStatusCb(
271             GeofenceStatusNotification /*geofenceStatusNotification*/) {}
onAddGeofencesCb(size_t,LocationError *,uint32_t *)272     inline virtual void onAddGeofencesCb(
273             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onRemoveGeofencesCb(size_t,LocationError *,uint32_t *)274     inline virtual void onRemoveGeofencesCb(
275             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onModifyGeofencesCb(size_t,LocationError *,uint32_t *)276     inline virtual void onModifyGeofencesCb(
277             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onPauseGeofencesCb(size_t,LocationError *,uint32_t *)278     inline virtual void onPauseGeofencesCb(
279             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
onResumeGeofencesCb(size_t,LocationError *,uint32_t *)280     inline virtual void onResumeGeofencesCb(
281             size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
282 
onGnssNiCb(uint32_t,GnssNiNotification)283     inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
onGnssNiResponseCb(LocationError)284     inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}
285 
onLocationSystemInfoCb(LocationSystemInfo)286     inline virtual void onLocationSystemInfoCb(LocationSystemInfo /*locationSystemInfo*/) {}
287 
288 protected:
289     virtual ~LocationAPIClientBase();
290 
291 private:
292     // private inner classes
293     typedef struct {
294         uint32_t id;
295         uint32_t trackingSession;
296         uint32_t batchingSession;
297         uint32_t sessionMode;
298     } SessionEntity;
299 
300     template<typename T>
301     class BiDict {
302     public:
BiDict()303         BiDict() {
304             pthread_mutex_init(&mBiDictMutex, nullptr);
305         }
~BiDict()306         virtual ~BiDict() {
307             pthread_mutex_destroy(&mBiDictMutex);
308         }
hasId(uint32_t id)309         bool hasId(uint32_t id) {
310             pthread_mutex_lock(&mBiDictMutex);
311             bool ret = (mForwardMap.find(id) != mForwardMap.end());
312             pthread_mutex_unlock(&mBiDictMutex);
313             return ret;
314         }
hasSession(uint32_t session)315         bool hasSession(uint32_t session) {
316             pthread_mutex_lock(&mBiDictMutex);
317             bool ret = (mBackwardMap.find(session) != mBackwardMap.end());
318             pthread_mutex_unlock(&mBiDictMutex);
319             return ret;
320         }
set(uint32_t id,uint32_t session,T & ext)321         void set(uint32_t id, uint32_t session, T& ext) {
322             pthread_mutex_lock(&mBiDictMutex);
323             mForwardMap[id] = session;
324             mBackwardMap[session] = id;
325             mExtMap[session] = ext;
326             pthread_mutex_unlock(&mBiDictMutex);
327         }
clear()328         void clear() {
329             pthread_mutex_lock(&mBiDictMutex);
330             mForwardMap.clear();
331             mBackwardMap.clear();
332             mExtMap.clear();
333             pthread_mutex_unlock(&mBiDictMutex);
334         }
rmById(uint32_t id)335         void rmById(uint32_t id) {
336             pthread_mutex_lock(&mBiDictMutex);
337             mBackwardMap.erase(mForwardMap[id]);
338             mExtMap.erase(mForwardMap[id]);
339             mForwardMap.erase(id);
340             pthread_mutex_unlock(&mBiDictMutex);
341         }
rmBySession(uint32_t session)342         void rmBySession(uint32_t session) {
343             pthread_mutex_lock(&mBiDictMutex);
344             mForwardMap.erase(mBackwardMap[session]);
345             mBackwardMap.erase(session);
346             mExtMap.erase(session);
347             pthread_mutex_unlock(&mBiDictMutex);
348         }
getId(uint32_t session)349         uint32_t getId(uint32_t session) {
350             pthread_mutex_lock(&mBiDictMutex);
351             uint32_t ret = 0;
352             auto it = mBackwardMap.find(session);
353             if (it != mBackwardMap.end()) {
354                 ret = it->second;
355             }
356             pthread_mutex_unlock(&mBiDictMutex);
357             return ret;
358         }
getSession(uint32_t id)359         uint32_t getSession(uint32_t id) {
360             pthread_mutex_lock(&mBiDictMutex);
361             uint32_t ret = 0;
362             auto it = mForwardMap.find(id);
363             if (it != mForwardMap.end()) {
364                 ret = it->second;
365             }
366             pthread_mutex_unlock(&mBiDictMutex);
367             return ret;
368         }
getExtById(uint32_t id)369         T getExtById(uint32_t id) {
370             pthread_mutex_lock(&mBiDictMutex);
371             T ret;
372             memset(&ret, 0, sizeof(T));
373             uint32_t session = mForwardMap[id];
374             if (session > 0) {
375                 auto it = mExtMap.find(session);
376                 if (it != mExtMap.end()) {
377                     ret = it->second;
378                 }
379             }
380             pthread_mutex_unlock(&mBiDictMutex);
381             return ret;
382         }
getExtBySession(uint32_t session)383         T getExtBySession(uint32_t session) {
384             pthread_mutex_lock(&mBiDictMutex);
385             T ret;
386             memset(&ret, 0, sizeof(T));
387             auto it = mExtMap.find(session);
388             if (it != mExtMap.end()) {
389                 ret = it->second;
390             }
391             pthread_mutex_unlock(&mBiDictMutex);
392             return ret;
393         }
getAllSessions()394         std::vector<uint32_t> getAllSessions() {
395             std::vector<uint32_t> ret;
396             pthread_mutex_lock(&mBiDictMutex);
397             for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) {
398                 ret.push_back(it->first);
399             }
400             pthread_mutex_unlock(&mBiDictMutex);
401             return ret;
402         }
403     private:
404         pthread_mutex_t mBiDictMutex;
405         // mForwarMap mapping id->session
406         std::map<uint32_t, uint32_t> mForwardMap;
407         // mBackwardMap mapping session->id
408         std::map<uint32_t, uint32_t> mBackwardMap;
409         // mExtMap mapping session->ext
410         std::map<uint32_t, T> mExtMap;
411     };
412 
413     class StartTrackingRequest : public LocationAPIRequest {
414     public:
StartTrackingRequest(LocationAPIClientBase & API)415         StartTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)416         inline void onResponse(LocationError error, uint32_t id) {
417             if (error != LOCATION_ERROR_SUCCESS) {
418                 mAPI.removeSession(id);
419             }
420             mAPI.onStartTrackingCb(error);
421         }
422         LocationAPIClientBase& mAPI;
423     };
424 
425     class StopTrackingRequest : public LocationAPIRequest {
426     public:
StopTrackingRequest(LocationAPIClientBase & API)427         StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)428         inline void onResponse(LocationError error, uint32_t id) {
429             mAPI.onStopTrackingCb(error);
430             if (error == LOCATION_ERROR_SUCCESS) {
431                 mAPI.removeSession(id);
432             }
433         }
434         LocationAPIClientBase& mAPI;
435     };
436 
437     class UpdateTrackingOptionsRequest : public LocationAPIRequest {
438     public:
UpdateTrackingOptionsRequest(LocationAPIClientBase & API)439         UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)440         inline void onResponse(LocationError error, uint32_t /*id*/) {
441             mAPI.onUpdateTrackingOptionsCb(error);
442         }
443         LocationAPIClientBase& mAPI;
444     };
445 
446     class StartBatchingRequest : public LocationAPIRequest {
447     public:
StartBatchingRequest(LocationAPIClientBase & API)448         StartBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)449         inline void onResponse(LocationError error, uint32_t id) {
450             if (error != LOCATION_ERROR_SUCCESS) {
451                 mAPI.removeSession(id);
452             }
453             mAPI.onStartBatchingCb(error);
454         }
455         LocationAPIClientBase& mAPI;
456     };
457 
458     class StopBatchingRequest : public LocationAPIRequest {
459     public:
StopBatchingRequest(LocationAPIClientBase & API)460         StopBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t id)461         inline void onResponse(LocationError error, uint32_t id) {
462             mAPI.onStopBatchingCb(error);
463             if (error == LOCATION_ERROR_SUCCESS) {
464                 mAPI.removeSession(id);
465             }
466         }
467         LocationAPIClientBase& mAPI;
468     };
469 
470     class UpdateBatchingOptionsRequest : public LocationAPIRequest {
471     public:
UpdateBatchingOptionsRequest(LocationAPIClientBase & API)472         UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)473         inline void onResponse(LocationError error, uint32_t /*id*/) {
474             mAPI.onUpdateBatchingOptionsCb(error);
475         }
476         LocationAPIClientBase& mAPI;
477     };
478 
479     class GetBatchedLocationsRequest : public LocationAPIRequest {
480     public:
GetBatchedLocationsRequest(LocationAPIClientBase & API)481         GetBatchedLocationsRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)482         inline void onResponse(LocationError error, uint32_t /*id*/) {
483             mAPI.onGetBatchedLocationsCb(error);
484         }
485         LocationAPIClientBase& mAPI;
486     };
487 
488     class AddGeofencesRequest : public LocationAPIRequest {
489     public:
AddGeofencesRequest(LocationAPIClientBase & API)490         AddGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)491         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
492             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
493             for (size_t i = 0; i < count; i++) {
494                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
495             }
496             LOC_LOGD("%s:]Returned geofence-id: %d in add geofence", __FUNCTION__, *ids);
497             mAPI.onAddGeofencesCb(count, errors, ids);
498             free(ids);
499         }
500         LocationAPIClientBase& mAPI;
501     };
502 
503     class RemoveGeofencesRequest : public LocationAPIRequest {
504     public:
RemoveGeofencesRequest(LocationAPIClientBase & API,BiDict<GeofenceBreachTypeMask> * removedGeofenceBiDict)505         RemoveGeofencesRequest(LocationAPIClientBase& API,
506                                BiDict<GeofenceBreachTypeMask>* removedGeofenceBiDict) :
507                                mAPI(API), mRemovedGeofenceBiDict(removedGeofenceBiDict) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)508         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
509             if (nullptr != mRemovedGeofenceBiDict) {
510                 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
511                 for (size_t i = 0; i < count; i++) {
512                     ids[i] = mRemovedGeofenceBiDict->getId(sessions[i]);
513                 }
514                 LOC_LOGD("%s:]Returned geofence-id: %d in remove geofence", __FUNCTION__, *ids);
515                 mAPI.onRemoveGeofencesCb(count, errors, ids);
516                 free(ids);
517                 delete(mRemovedGeofenceBiDict);
518             } else {
519                 LOC_LOGE("%s:%d] Unable to access removed geofences data.", __FUNCTION__, __LINE__);
520             }
521         }
522         LocationAPIClientBase& mAPI;
523         BiDict<GeofenceBreachTypeMask>* mRemovedGeofenceBiDict;
524     };
525 
526     class ModifyGeofencesRequest : public LocationAPIRequest {
527     public:
ModifyGeofencesRequest(LocationAPIClientBase & API)528         ModifyGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)529         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
530             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
531             for (size_t i = 0; i < count; i++) {
532                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
533             }
534             mAPI.onModifyGeofencesCb(count, errors, ids);
535             free(ids);
536         }
537         LocationAPIClientBase& mAPI;
538     };
539 
540     class PauseGeofencesRequest : public LocationAPIRequest {
541     public:
PauseGeofencesRequest(LocationAPIClientBase & API)542         PauseGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)543         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
544             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
545             for (size_t i = 0; i < count; i++) {
546                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
547             }
548             mAPI.onPauseGeofencesCb(count, errors, ids);
549             free(ids);
550         }
551         LocationAPIClientBase& mAPI;
552     };
553 
554     class ResumeGeofencesRequest : public LocationAPIRequest {
555     public:
ResumeGeofencesRequest(LocationAPIClientBase & API)556         ResumeGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)557         inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
558             uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
559             for (size_t i = 0; i < count; i++) {
560                 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
561             }
562             mAPI.onResumeGeofencesCb(count, errors, ids);
563             free(ids);
564         }
565         LocationAPIClientBase& mAPI;
566     };
567 
568     class GnssNiResponseRequest : public LocationAPIRequest {
569     public:
GnssNiResponseRequest(LocationAPIClientBase & API)570         GnssNiResponseRequest(LocationAPIClientBase& API) : mAPI(API) {}
onResponse(LocationError error,uint32_t)571         inline void onResponse(LocationError error, uint32_t /*id*/) {
572             mAPI.onGnssNiResponseCb(error);
573         }
574         LocationAPIClientBase& mAPI;
575     };
576 
577 private:
578     pthread_mutex_t mMutex;
579 
580     geofenceBreachCallback mGeofenceBreachCallback;
581     batchingStatusCallback mBatchingStatusCallback;
582 
583     LocationAPI* mLocationAPI;
584 
585     RequestQueue mRequestQueues[REQUEST_MAX];
586     BiDict<GeofenceBreachTypeMask> mGeofenceBiDict;
587     BiDict<SessionEntity> mSessionBiDict;
588     int32_t mBatchSize;
589     bool mTracking;
590 };
591 
592 #endif /* LOCATION_API_CLINET_BASE_H */
593