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_MAX, 54 }; 55 56 class LocationAPIClientBase 57 { 58 public: 59 LocationAPIClientBase(); 60 virtual ~LocationAPIClientBase(); 61 LocationAPIClientBase(const LocationAPIClientBase&) = delete; 62 LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete; 63 64 void locAPISetCallbacks(LocationCallbacks& locationCallbacks); 65 66 // LocationAPI 67 uint32_t locAPIStartTracking(LocationOptions& options); 68 void locAPIStopTracking(); 69 void locAPIUpdateTrackingOptions(LocationOptions& options); 70 71 int32_t locAPIGetBatchSize(); 72 uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode, 73 LocationOptions& options); 74 uint32_t locAPIStopSession(uint32_t id); 75 uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode, 76 LocationOptions& options); 77 void locAPIGetBatchedLocations(size_t count); 78 79 uint32_t locAPIAddGeofences(size_t count, uint32_t* ids, 80 GeofenceOption* options, GeofenceInfo* data); 81 void locAPIRemoveGeofences(size_t count, uint32_t* ids); 82 void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options); 83 void locAPIPauseGeofences(size_t count, uint32_t* ids); 84 void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask); 85 void locAPIRemoveAllGeofences(); 86 87 void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response); 88 uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data); 89 90 uint32_t locAPIEnable(LocationTechnologyType techType); 91 void locAPIDisable(); 92 uint32_t locAPIGnssUpdateConfig(GnssConfig config); 93 94 // callbacks 95 void onResponseCb(LocationError error, uint32_t id); 96 void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids); 97 98 void onCtrlResponseCb(LocationError error, uint32_t id); 99 void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids); 100 101 void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification); 102 onCapabilitiesCb(LocationCapabilitiesMask)103 inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {} onGnssNmeaCb(GnssNmeaNotification)104 inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {} onGnssMeasurementsCb(GnssMeasurementsNotification)105 inline virtual void onGnssMeasurementsCb( 106 GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {} 107 onTrackingCb(Location)108 inline virtual void onTrackingCb(Location /*location*/) {} onGnssSvCb(GnssSvNotification)109 inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {} onStartTrackingCb(LocationError)110 inline virtual void onStartTrackingCb(LocationError /*error*/) {} onStopTrackingCb(LocationError)111 inline virtual void onStopTrackingCb(LocationError /*error*/) {} onUpdateTrackingOptionsCb(LocationError)112 inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {} 113 onGnssLocationInfoCb(GnssLocationInfoNotification)114 inline virtual void onGnssLocationInfoCb( 115 GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {} 116 onBatchingCb(size_t,Location *)117 inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/) {} onStartBatchingCb(LocationError)118 inline virtual void onStartBatchingCb(LocationError /*error*/) {} onStopBatchingCb(LocationError)119 inline virtual void onStopBatchingCb(LocationError /*error*/) {} onUpdateBatchingOptionsCb(LocationError)120 inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {} onGetBatchedLocationsCb(LocationError)121 inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {} 122 onGeofenceBreachCb(GeofenceBreachNotification)123 inline virtual void onGeofenceBreachCb( 124 GeofenceBreachNotification /*geofenceBreachNotification*/) {} onGeofenceStatusCb(GeofenceStatusNotification)125 inline virtual void onGeofenceStatusCb( 126 GeofenceStatusNotification /*geofenceStatusNotification*/) {} onAddGeofencesCb(size_t,LocationError *,uint32_t *)127 inline virtual void onAddGeofencesCb( 128 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onRemoveGeofencesCb(size_t,LocationError *,uint32_t *)129 inline virtual void onRemoveGeofencesCb( 130 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onModifyGeofencesCb(size_t,LocationError *,uint32_t *)131 inline virtual void onModifyGeofencesCb( 132 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onPauseGeofencesCb(size_t,LocationError *,uint32_t *)133 inline virtual void onPauseGeofencesCb( 134 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} onResumeGeofencesCb(size_t,LocationError *,uint32_t *)135 inline virtual void onResumeGeofencesCb( 136 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 137 onGnssNiCb(uint32_t,GnssNiNotification)138 inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {} onGnssNiResponseCb(LocationError)139 inline virtual void onGnssNiResponseCb(LocationError /*error*/) {} onGnssDeleteAidingDataCb(LocationError)140 inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {} 141 onEnableCb(LocationError)142 inline virtual void onEnableCb(LocationError /*error*/) {} onDisableCb(LocationError)143 inline virtual void onDisableCb(LocationError /*error*/) {} onGnssUpdateConfigCb(size_t,LocationError *,uint32_t *)144 inline virtual void onGnssUpdateConfigCb( 145 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 146 147 private: 148 // private inner classes 149 typedef struct { 150 uint32_t id; 151 uint32_t trackingSession; 152 uint32_t batchingSession; 153 uint32_t sessionMode; 154 } SessionEntity; 155 156 class BiDict { 157 public: BiDict()158 BiDict() { 159 pthread_mutex_init(&mBiDictMutex, nullptr); 160 } ~BiDict()161 ~BiDict() { 162 pthread_mutex_destroy(&mBiDictMutex); 163 } hasId(uint32_t id)164 bool hasId(uint32_t id) { 165 pthread_mutex_lock(&mBiDictMutex); 166 bool ret = (mForwardMap.find(id) != mForwardMap.end()); 167 pthread_mutex_unlock(&mBiDictMutex); 168 return ret; 169 } set(uint32_t id,uint32_t session,uint32_t type)170 void set(uint32_t id, uint32_t session, uint32_t type) { 171 pthread_mutex_lock(&mBiDictMutex); 172 mForwardMap[id] = session; 173 mBackwardMap[session] = id; 174 mTypeMap[session] = type; 175 pthread_mutex_unlock(&mBiDictMutex); 176 } clear()177 void clear() { 178 pthread_mutex_lock(&mBiDictMutex); 179 mForwardMap.clear(); 180 mBackwardMap.clear(); 181 mTypeMap.clear(); 182 pthread_mutex_unlock(&mBiDictMutex); 183 } rmById(uint32_t id)184 void rmById(uint32_t id) { 185 pthread_mutex_lock(&mBiDictMutex); 186 mBackwardMap.erase(mForwardMap[id]); 187 mTypeMap.erase(mForwardMap[id]); 188 mForwardMap.erase(id); 189 pthread_mutex_unlock(&mBiDictMutex); 190 } rmBySession(uint32_t session)191 void rmBySession(uint32_t session) { 192 pthread_mutex_lock(&mBiDictMutex); 193 mForwardMap.erase(mBackwardMap[session]); 194 mBackwardMap.erase(session); 195 mTypeMap.erase(session); 196 pthread_mutex_unlock(&mBiDictMutex); 197 } getId(uint32_t session)198 uint32_t getId(uint32_t session) { 199 pthread_mutex_lock(&mBiDictMutex); 200 uint32_t ret = mBackwardMap[session]; 201 pthread_mutex_unlock(&mBiDictMutex); 202 return ret; 203 } getSession(uint32_t id)204 uint32_t getSession(uint32_t id) { 205 pthread_mutex_lock(&mBiDictMutex); 206 uint32_t ret = mForwardMap[id]; 207 pthread_mutex_unlock(&mBiDictMutex); 208 return ret; 209 } getType(uint32_t session)210 uint32_t getType(uint32_t session) { 211 pthread_mutex_lock(&mBiDictMutex); 212 uint32_t ret = mTypeMap[session]; 213 pthread_mutex_unlock(&mBiDictMutex); 214 return ret; 215 } getAllSessions()216 std::vector<uint32_t> getAllSessions() { 217 std::vector<uint32_t> ret; 218 pthread_mutex_lock(&mBiDictMutex); 219 for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) { 220 ret.push_back(it->first); 221 } 222 pthread_mutex_unlock(&mBiDictMutex); 223 return ret; 224 } 225 private: 226 pthread_mutex_t mBiDictMutex; 227 // mForwarMap mapping id->session 228 std::map<uint32_t, uint32_t> mForwardMap; 229 // mBackwardMap mapping session->id 230 std::map<uint32_t, uint32_t> mBackwardMap; 231 // mTypeMap mapping session->type 232 std::map<uint32_t, uint32_t> mTypeMap; 233 }; 234 235 class LocationAPIRequest { 236 public: LocationAPIRequest(LocationAPIClientBase & API)237 LocationAPIRequest(LocationAPIClientBase& API) : mAPI(API) {} ~LocationAPIRequest()238 virtual ~LocationAPIRequest() {} onResponse(LocationError)239 virtual void onResponse(LocationError /*error*/) {}; onCollectiveResponse(size_t,LocationError *,uint32_t *)240 virtual void onCollectiveResponse( 241 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}; 242 LocationAPIClientBase& mAPI; 243 }; 244 245 class StartTrackingRequest : public LocationAPIRequest { 246 public: StartTrackingRequest(LocationAPIClientBase & API)247 StartTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)248 inline void onResponse(LocationError error) { 249 mAPI.onStartTrackingCb(error); 250 } 251 }; 252 253 class StopTrackingRequest : public LocationAPIRequest { 254 public: StopTrackingRequest(LocationAPIClientBase & API)255 StopTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)256 inline void onResponse(LocationError error) { 257 mAPI.onStopTrackingCb(error); 258 } 259 }; 260 261 class UpdateTrackingOptionsRequest : public LocationAPIRequest { 262 public: UpdateTrackingOptionsRequest(LocationAPIClientBase & API)263 UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)264 inline void onResponse(LocationError error) { 265 mAPI.onUpdateTrackingOptionsCb(error); 266 } 267 }; 268 269 class StartBatchingRequest : public LocationAPIRequest { 270 public: StartBatchingRequest(LocationAPIClientBase & API)271 StartBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)272 inline void onResponse(LocationError error) { 273 mAPI.onStartBatchingCb(error); 274 } 275 }; 276 277 class StopBatchingRequest : public LocationAPIRequest { 278 public: StopBatchingRequest(LocationAPIClientBase & API)279 StopBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)280 inline void onResponse(LocationError error) { 281 mAPI.onStopBatchingCb(error); 282 } 283 }; 284 285 class UpdateBatchingOptionsRequest : public LocationAPIRequest { 286 public: UpdateBatchingOptionsRequest(LocationAPIClientBase & API)287 UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)288 inline void onResponse(LocationError error) { 289 mAPI.onUpdateBatchingOptionsCb(error); 290 } 291 }; 292 293 class GetBatchedLocationsRequest : public LocationAPIRequest { 294 public: GetBatchedLocationsRequest(LocationAPIClientBase & API)295 GetBatchedLocationsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)296 inline void onResponse(LocationError error) { 297 mAPI.onGetBatchedLocationsCb(error); 298 } 299 }; 300 301 class AddGeofencesRequest : public LocationAPIRequest { 302 public: AddGeofencesRequest(LocationAPIClientBase & API)303 AddGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)304 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 305 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 306 for (size_t i = 0; i < count; i++) { 307 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 308 } 309 mAPI.onAddGeofencesCb(count, errors, ids); 310 free(ids); 311 } 312 }; 313 314 class RemoveGeofencesRequest : public LocationAPIRequest { 315 public: RemoveGeofencesRequest(LocationAPIClientBase & API)316 RemoveGeofencesRequest(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 mAPI.mGeofenceBiDict.rmBySession(sessions[i]); 322 } 323 mAPI.onRemoveGeofencesCb(count, errors, ids); 324 free(ids); 325 } 326 }; 327 328 class ModifyGeofencesRequest : public LocationAPIRequest { 329 public: ModifyGeofencesRequest(LocationAPIClientBase & API)330 ModifyGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * sessions)331 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) { 332 uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count); 333 for (size_t i = 0; i < count; i++) { 334 ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]); 335 } 336 mAPI.onModifyGeofencesCb(count, errors, ids); 337 free(ids); 338 } 339 }; 340 341 class PauseGeofencesRequest : public LocationAPIRequest { 342 public: PauseGeofencesRequest(LocationAPIClientBase & API)343 PauseGeofencesRequest(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.onPauseGeofencesCb(count, errors, ids); 350 free(ids); 351 } 352 }; 353 354 class ResumeGeofencesRequest : public LocationAPIRequest { 355 public: ResumeGeofencesRequest(LocationAPIClientBase & API)356 ResumeGeofencesRequest(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.onResumeGeofencesCb(count, errors, ids); 363 free(ids); 364 } 365 }; 366 367 class GnssNiResponseRequest : public LocationAPIRequest { 368 public: GnssNiResponseRequest(LocationAPIClientBase & API)369 GnssNiResponseRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)370 inline void onResponse(LocationError error) { 371 mAPI.onGnssNiResponseCb(error); 372 } 373 }; 374 375 class GnssDeleteAidingDataRequest : public LocationAPIRequest { 376 public: GnssDeleteAidingDataRequest(LocationAPIClientBase & API)377 GnssDeleteAidingDataRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)378 inline void onResponse(LocationError error) { 379 mAPI.onGnssDeleteAidingDataCb(error); 380 } 381 }; 382 383 class EnableRequest : public LocationAPIRequest { 384 public: EnableRequest(LocationAPIClientBase & API)385 EnableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)386 inline void onResponse(LocationError error) { 387 mAPI.onEnableCb(error); 388 } 389 }; 390 391 class DisableRequest : public LocationAPIRequest { 392 public: DisableRequest(LocationAPIClientBase & API)393 DisableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onResponse(LocationError error)394 inline void onResponse(LocationError error) { 395 mAPI.onDisableCb(error); 396 } 397 }; 398 399 class GnssUpdateConfigRequest : public LocationAPIRequest { 400 public: GnssUpdateConfigRequest(LocationAPIClientBase & API)401 GnssUpdateConfigRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} onCollectiveResponse(size_t count,LocationError * errors,uint32_t * ids)402 inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) { 403 mAPI.onGnssUpdateConfigCb(count, errors, ids); 404 } 405 }; 406 407 class RequestQueue { 408 public: RequestQueue(uint32_t session)409 RequestQueue(uint32_t session): mSession(session) { 410 } ~RequestQueue()411 ~RequestQueue() { 412 LocationAPIRequest* request = nullptr; 413 while (!mQueue.empty()) { 414 request = mQueue.front(); 415 mQueue.pop(); 416 delete request; 417 } 418 } push(LocationAPIRequest * request)419 void push(LocationAPIRequest* request) { 420 mQueue.push(request); 421 } pop()422 LocationAPIRequest* pop() { 423 LocationAPIRequest* request = nullptr; 424 if (!mQueue.empty()) { 425 request = mQueue.front(); 426 mQueue.pop(); 427 } 428 return request; 429 } getSession()430 uint32_t getSession() { return mSession; } 431 private: 432 uint32_t mSession; 433 std::queue<LocationAPIRequest*> mQueue; 434 }; 435 436 LocationAPIRequest* getRequestBySession(uint32_t session); 437 LocationAPIRequest* getGeofencesRequest(); 438 439 private: 440 pthread_mutex_t mMutex; 441 442 trackingCallback mTrackingCallback; 443 batchingCallback mBatchingCallback; 444 geofenceBreachCallback mGeofenceBreachCallback; 445 446 LocationAPI* mLocationAPI; 447 LocationControlAPI* mLocationControlAPI; 448 449 BiDict mGeofenceBiDict; 450 RequestQueue* mRequestQueues[REQUEST_MAX]; 451 std::map<uint32_t, SessionEntity> mSessionMap; 452 int32_t mBatchSize; 453 454 GnssConfig mConfig; 455 }; 456 457 #endif /* LOCATION_API_CLINET_BASE_H */ 458