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 40enum SESSION_MODE { 41 SESSION_MODE_NONE = 0, 42 SESSION_MODE_ON_FULL, 43 SESSION_MODE_ON_FIX, 44}; 45 46enum 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 57class LocationAPIClientBase 58{ 59public: 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 104 inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {} 105 inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {} 106 inline virtual void onGnssMeasurementsCb( 107 GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {} 108 109 inline virtual void onTrackingCb(Location /*location*/) {} 110 inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {} 111 inline virtual void onStartTrackingCb(LocationError /*error*/) {} 112 inline virtual void onStopTrackingCb(LocationError /*error*/) {} 113 inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {} 114 115 inline virtual void onGnssLocationInfoCb( 116 GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {} 117 118 inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/) {} 119 inline virtual void onStartBatchingCb(LocationError /*error*/) {} 120 inline virtual void onStopBatchingCb(LocationError /*error*/) {} 121 inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {} 122 inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {} 123 124 inline virtual void onGeofenceBreachCb( 125 GeofenceBreachNotification /*geofenceBreachNotification*/) {} 126 inline virtual void onGeofenceStatusCb( 127 GeofenceStatusNotification /*geofenceStatusNotification*/) {} 128 inline virtual void onAddGeofencesCb( 129 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 130 inline virtual void onRemoveGeofencesCb( 131 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 132 inline virtual void onModifyGeofencesCb( 133 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 134 inline virtual void onPauseGeofencesCb( 135 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 136 inline virtual void onResumeGeofencesCb( 137 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 138 139 inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {} 140 inline virtual void onGnssNiResponseCb(LocationError /*error*/) {} 141 inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {} 142 143 inline virtual void onEnableCb(LocationError /*error*/) {} 144 inline virtual void onDisableCb(LocationError /*error*/) {} 145 inline virtual void onGnssUpdateConfigCb( 146 size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} 147 148private: 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: 159 BiDict() { 160 pthread_mutex_init(&mBiDictMutex, nullptr); 161 } 162 ~BiDict() { 163 pthread_mutex_destroy(&mBiDictMutex); 164 } 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 } 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 } 178 void clear() { 179 pthread_mutex_lock(&mBiDictMutex); 180 mForwardMap.clear(); 181 mBackwardMap.clear(); 182 mTypeMap.clear(); 183 pthread_mutex_unlock(&mBiDictMutex); 184 } 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 } 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 } 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 } 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 } 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 } 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: 250 LocationAPIRequest(LocationAPIClientBase& API) : mAPI(API) {} 251 virtual ~LocationAPIRequest() {} 252 virtual void onResponse(LocationError /*error*/) {}; 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: 260 StartTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 261 inline void onResponse(LocationError error) { 262 mAPI.onStartTrackingCb(error); 263 } 264 }; 265 266 class StopTrackingRequest : public LocationAPIRequest { 267 public: 268 StopTrackingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 269 inline void onResponse(LocationError error) { 270 mAPI.onStopTrackingCb(error); 271 } 272 }; 273 274 class UpdateTrackingOptionsRequest : public LocationAPIRequest { 275 public: 276 UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 277 inline void onResponse(LocationError error) { 278 mAPI.onUpdateTrackingOptionsCb(error); 279 } 280 }; 281 282 class StartBatchingRequest : public LocationAPIRequest { 283 public: 284 StartBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 285 inline void onResponse(LocationError error) { 286 mAPI.onStartBatchingCb(error); 287 } 288 }; 289 290 class StopBatchingRequest : public LocationAPIRequest { 291 public: 292 StopBatchingRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 293 inline void onResponse(LocationError error) { 294 mAPI.onStopBatchingCb(error); 295 } 296 }; 297 298 class UpdateBatchingOptionsRequest : public LocationAPIRequest { 299 public: 300 UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 301 inline void onResponse(LocationError error) { 302 mAPI.onUpdateBatchingOptionsCb(error); 303 } 304 }; 305 306 class GetBatchedLocationsRequest : public LocationAPIRequest { 307 public: 308 GetBatchedLocationsRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 309 inline void onResponse(LocationError error) { 310 mAPI.onGetBatchedLocationsCb(error); 311 } 312 }; 313 314 class AddGeofencesRequest : public LocationAPIRequest { 315 public: 316 AddGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 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: 329 RemoveGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 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: 343 ModifyGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 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: 356 PauseGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 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: 369 ResumeGeofencesRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 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: 382 GnssNiResponseRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 383 inline void onResponse(LocationError error) { 384 mAPI.onGnssNiResponseCb(error); 385 } 386 }; 387 388 class GnssDeleteAidingDataRequest : public LocationAPIRequest { 389 public: 390 GnssDeleteAidingDataRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 391 inline void onResponse(LocationError error) { 392 mAPI.onGnssDeleteAidingDataCb(error); 393 } 394 }; 395 396 class EnableRequest : public LocationAPIRequest { 397 public: 398 EnableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 399 inline void onResponse(LocationError error) { 400 mAPI.onEnableCb(error); 401 } 402 }; 403 404 class DisableRequest : public LocationAPIRequest { 405 public: 406 DisableRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 407 inline void onResponse(LocationError error) { 408 mAPI.onDisableCb(error); 409 } 410 }; 411 412 class GnssUpdateConfigRequest : public LocationAPIRequest { 413 public: 414 GnssUpdateConfigRequest(LocationAPIClientBase& API) : LocationAPIRequest(API) {} 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: 422 RequestQueue(uint32_t session): mSession(session) { 423 } 424 ~RequestQueue() { 425 LocationAPIRequest* request = nullptr; 426 while (!mQueue.empty()) { 427 request = mQueue.front(); 428 mQueue.pop(); 429 delete request; 430 } 431 } 432 void push(LocationAPIRequest* request) { 433 mQueue.push(request); 434 } 435 LocationAPIRequest* pop() { 436 LocationAPIRequest* request = nullptr; 437 if (!mQueue.empty()) { 438 request = mQueue.front(); 439 mQueue.pop(); 440 } 441 return request; 442 } 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 451private: 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 467 GnssConfig mConfig; 468}; 469 470#endif /* LOCATION_API_CLINET_BASE_H */ 471