diff --git a/location/LocationAPIClientBase.cpp b/location/LocationAPIClientBase.cpp index 56ac9cc3..b89b68cb 100644 --- a/location/LocationAPIClientBase.cpp +++ b/location/LocationAPIClientBase.cpp @@ -176,7 +176,7 @@ void LocationAPIControlClient::onCtrlResponseCb(LocationError error, uint32_t id } LocationAPIRequest* request = getRequestBySession(id); if (request) { - request->onResponse(error); + request->onResponse(error, id); delete request; } } @@ -366,7 +366,7 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session pthread_mutex_lock(&mMutex); if (mLocationAPI) { - if (mSessionMap.find(id) != mSessionMap.end()) { + if (mSessionBiDict.hasId(id)) { LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id); retVal = LOCATION_ERROR_ALREADY_STARTED; } else { @@ -376,21 +376,22 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session if (sessionMode == SESSION_MODE_ON_FIX) { trackingSession = mLocationAPI->startTracking(options); LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession); - mRequestQueues[REQUEST_TRACKING].reset(trackingSession); - mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this)); + mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this)); } else if (sessionMode == SESSION_MODE_ON_FULL) { batchingSession = mLocationAPI->startBatching(options); LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession); - mRequestQueues[REQUEST_BATCHING].reset(batchingSession); - mRequestQueues[REQUEST_BATCHING].push(new StartBatchingRequest(*this)); + mRequestQueues[REQUEST_SESSION].setSession(batchingSession); + mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this)); } + uint32_t session = + (sessionMode == SESSION_MODE_ON_FULL) ? batchingSession : trackingSession; SessionEntity entity; entity.id = id; entity.trackingSession = trackingSession; entity.batchingSession = batchingSession; entity.sessionMode = sessionMode; - mSessionMap[id] = entity; + mSessionBiDict.set(id, session, entity); retVal = LOCATION_ERROR_SUCCESS; } @@ -407,31 +408,21 @@ uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id) pthread_mutex_lock(&mMutex); if (mLocationAPI) { - if (mSessionMap.find(id) != mSessionMap.end()) { - SessionEntity entity = mSessionMap[id]; + if (mSessionBiDict.hasId(id)) { + SessionEntity entity = mSessionBiDict.getExtById(id); uint32_t trackingSession = entity.trackingSession; uint32_t batchingSession = entity.batchingSession; uint32_t sMode = entity.sessionMode; - mSessionMap.erase(id); - if (sMode == SESSION_MODE_ON_FIX) { - if (mRequestQueues[REQUEST_TRACKING].getSession() == trackingSession) { - mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this)); - mLocationAPI->stopTracking(trackingSession); - } else { - LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, - mRequestQueues[REQUEST_TRACKING].getSession()); - } + mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this)); + mLocationAPI->stopTracking(trackingSession); } else if (sMode == SESSION_MODE_ON_FULL) { - if (mRequestQueues[REQUEST_BATCHING].getSession() == batchingSession) { - mRequestQueues[REQUEST_BATCHING].push(new StopBatchingRequest(*this)); - mLocationAPI->stopBatching(batchingSession); - } else { - LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, - mRequestQueues[REQUEST_BATCHING].getSession()); - } + mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this)); + mLocationAPI->stopBatching(batchingSession); + } else { + LOC_LOGE("%s:%d] unknown mode %d.", __FUNCTION__, __LINE__, sMode); } retVal = LOCATION_ERROR_SUCCESS; @@ -452,79 +443,68 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t pthread_mutex_lock(&mMutex); if (mLocationAPI) { - if (mSessionMap.find(id) != mSessionMap.end()) { - SessionEntity& entity = mSessionMap[id]; + if (mSessionBiDict.hasId(id)) { + SessionEntity entity = mSessionBiDict.getExtById(id); uint32_t trackingSession = entity.trackingSession; uint32_t batchingSession = entity.batchingSession; uint32_t sMode = entity.sessionMode; if (sessionMode == SESSION_MODE_ON_FIX) { + // we only add an UpdateTrackingOptionsRequest to mRequestQueues[REQUEST_SESSION], + // even if this update request will stop batching and then start tracking. + mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this)); if (sMode == SESSION_MODE_ON_FIX) { - if (mRequestQueues[REQUEST_TRACKING].getSession() == trackingSession) { - mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this)); - mLocationAPI->updateTrackingOptions(trackingSession, options); - } else { - LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, - mRequestQueues[REQUEST_TRACKING].getSession()); - } + mLocationAPI->updateTrackingOptions(trackingSession, options); } else if (sMode == SESSION_MODE_ON_FULL) { // stop batching - { - if (mRequestQueues[REQUEST_BATCHING].getSession() == batchingSession) { - mRequestQueues[REQUEST_BATCHING].push(new StopBatchingRequest(*this)); - mLocationAPI->stopBatching(batchingSession); - batchingSession = 0; - } else { - LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, - mRequestQueues[REQUEST_BATCHING].getSession()); - } - } + // batchingSession will be removed from mSessionBiDict soon, + // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION]. + mLocationAPI->stopBatching(batchingSession); + batchingSession = 0; + mRequestQueues[REQUEST_SESSION].setSession(batchingSession); + // start tracking - { - trackingSession = mLocationAPI->startTracking(options); - LOC_LOGI("%s:%d] start new session: %d", - __FUNCTION__, __LINE__, trackingSession); - mRequestQueues[REQUEST_TRACKING].reset(trackingSession); - mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this)); - } + trackingSession = mLocationAPI->startTracking(options); + LOC_LOGI("%s:%d] start new session: %d", + __FUNCTION__, __LINE__, trackingSession); + } else { + LOC_LOGE("%s:%d] unknown mode %d", __FUNCTION__, __LINE__, sMode); } } else if (sessionMode == SESSION_MODE_ON_FULL) { + // we only add an UpdateBatchingOptionsRequest to mRequestQueues[REQUEST_SESSION], + // even if this update request will stop tracking and then start batching. + mRequestQueues[REQUEST_SESSION].push(new UpdateBatchingOptionsRequest(*this)); if (sMode == SESSION_MODE_ON_FIX) { // stop tracking - { - if (mRequestQueues[REQUEST_TRACKING].getSession() == trackingSession) { - mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this)); - mLocationAPI->stopTracking(trackingSession); - trackingSession = 0; - } else { - LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, - mRequestQueues[REQUEST_TRACKING].getSession()); - } - } + // trackingSession will be removed from mSessionBiDict soon, + // so we don't need to add a new request to mRequestQueues[REQUEST_SESSION]. + mLocationAPI->stopTracking(trackingSession); + trackingSession = 0; + // start batching - { - batchingSession = mLocationAPI->startBatching(options); - LOC_LOGI("%s:%d] start new session: %d", - __FUNCTION__, __LINE__, batchingSession); - mRequestQueues[REQUEST_BATCHING].reset(batchingSession); - mRequestQueues[REQUEST_BATCHING].push(new StartBatchingRequest(*this)); - } + batchingSession = mLocationAPI->startBatching(options); + LOC_LOGI("%s:%d] start new session: %d", + __FUNCTION__, __LINE__, batchingSession); + mRequestQueues[REQUEST_SESSION].setSession(batchingSession); } else if (sMode == SESSION_MODE_ON_FULL) { - if (mRequestQueues[REQUEST_BATCHING].getSession() == batchingSession) { - mRequestQueues[REQUEST_BATCHING].push( - new UpdateBatchingOptionsRequest(*this)); - mLocationAPI->updateBatchingOptions(batchingSession, options); - } else { - LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, - mRequestQueues[REQUEST_BATCHING].getSession()); - } + mLocationAPI->updateBatchingOptions(batchingSession, options); + } else { + LOC_LOGE("%s:%d] unknown mode %d", __FUNCTION__, __LINE__, sMode); } + + } else { + LOC_LOGE("%s:%d] unknown mode %d.", __FUNCTION__, __LINE__, sessionMode); } + uint32_t session = + (sessionMode == SESSION_MODE_ON_FULL) ? batchingSession : trackingSession; entity.trackingSession = trackingSession; entity.batchingSession = batchingSession; entity.sessionMode = sessionMode; + // remove the old values from mSessionBiDict before we add a new one. + mSessionBiDict.rmById(id); + mSessionBiDict.set(id, session, entity); retVal = LOCATION_ERROR_SUCCESS; } else { @@ -542,9 +522,9 @@ void LocationAPIClientBase::locAPIGetBatchedLocations(size_t count) pthread_mutex_lock(&mMutex); if (mLocationAPI) { uint32_t session = 0; - session = mRequestQueues[REQUEST_BATCHING].getSession(); + session = mRequestQueues[REQUEST_SESSION].getSession(); if (session > 0) { - mRequestQueues[REQUEST_BATCHING].push(new GetBatchedLocationsRequest(*this)); + mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this)); mLocationAPI->getBatchedLocations(session, count); } else { LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session); @@ -785,7 +765,7 @@ void LocationAPIClientBase::beforeGeofenceBreachCb( for (size_t i = 0; i < n; i++) { uint32_t id = mGeofenceBiDict.getId(geofenceBreachNotification.ids[i]); GeofenceBreachTypeMask type = - mGeofenceBiDict.getType(geofenceBreachNotification.ids[i]); + mGeofenceBiDict.getExtBySession(geofenceBreachNotification.ids[i]); // if type == 0, we will not head into the fllowing block anyway. // so we don't need to check id and type if ((geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER && @@ -823,7 +803,7 @@ void LocationAPIClientBase::onResponseCb(LocationError error, uint32_t id) } LocationAPIRequest* request = getRequestBySession(id); if (request) { - request->onResponse(error); + request->onResponse(error, id); delete request; } } @@ -850,17 +830,31 @@ void LocationAPIClientBase::onCollectiveResponseCb( } } +void LocationAPIClientBase::removeSession(uint32_t session) { + if (mSessionBiDict.hasSession(session)) { + mSessionBiDict.rmBySession(session); + } +} + LocationAPIRequest* LocationAPIClientBase::getRequestBySession(uint32_t session) { pthread_mutex_lock(&mMutex); LocationAPIRequest* request = nullptr; for (int i = 0; i < REQUEST_MAX; i++) { if (i != REQUEST_GEOFENCE && + i != REQUEST_SESSION && mRequestQueues[i].getSession() == session) { request = mRequestQueues[i].pop(); break; } } + if (request == nullptr) { + // Can't find a request with correct session, + // try to find it from mSessionBiDict + if (mSessionBiDict.hasSession(session)) { + request = mRequestQueues[REQUEST_SESSION].pop(); + } + } pthread_mutex_unlock(&mMutex); return request; } diff --git a/location/LocationAPIClientBase.h b/location/LocationAPIClientBase.h index 354e51ff..19d585ad 100644 --- a/location/LocationAPIClientBase.h +++ b/location/LocationAPIClientBase.h @@ -45,7 +45,7 @@ enum SESSION_MODE { enum REQUEST_TYPE { REQUEST_TRACKING = 0, - REQUEST_BATCHING, + REQUEST_SESSION, REQUEST_GEOFENCE, REQUEST_NIRESPONSE, REQUEST_MAX, @@ -64,7 +64,7 @@ class LocationAPIRequest { public: LocationAPIRequest() {} virtual ~LocationAPIRequest() {} - virtual void onResponse(LocationError /*error*/) {} + virtual void onResponse(LocationError /*error*/, uint32_t /*id*/) {} virtual void onCollectiveResponse( size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {} }; @@ -76,6 +76,7 @@ public: virtual ~RequestQueue() { reset(0); } + void inline setSession(uint32_t session) { mSession = session; } void reset(uint32_t session) { LocationAPIRequest* request = nullptr; while (!mQueue.empty()) { @@ -130,7 +131,7 @@ public: class GnssDeleteAidingDataRequest : public LocationAPIRequest { public: GnssDeleteAidingDataRequest(LocationAPIControlClient& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onGnssDeleteAidingDataCb(error); } LocationAPIControlClient& mAPI; @@ -139,7 +140,7 @@ public: class EnableRequest : public LocationAPIRequest { public: EnableRequest(LocationAPIControlClient& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onEnableCb(error); } LocationAPIControlClient& mAPI; @@ -148,7 +149,7 @@ public: class DisableRequest : public LocationAPIRequest { public: DisableRequest(LocationAPIControlClient& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onDisableCb(error); } LocationAPIControlClient& mAPI; @@ -179,6 +180,7 @@ public: LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete; void locAPISetCallbacks(LocationCallbacks& locationCallbacks); + void removeSession(uint32_t session); LocationAPIRequest* getRequestBySession(uint32_t session); // LocationAPI @@ -257,6 +259,7 @@ private: uint32_t sessionMode; } SessionEntity; + template class BiDict { public: BiDict() { @@ -271,24 +274,30 @@ private: pthread_mutex_unlock(&mBiDictMutex); return ret; } - void set(uint32_t id, uint32_t session, uint32_t type) { + bool hasSession(uint32_t session) { + pthread_mutex_lock(&mBiDictMutex); + bool ret = (mBackwardMap.find(session) != mBackwardMap.end()); + pthread_mutex_unlock(&mBiDictMutex); + return ret; + } + void set(uint32_t id, uint32_t session, T& ext) { pthread_mutex_lock(&mBiDictMutex); mForwardMap[id] = session; mBackwardMap[session] = id; - mTypeMap[session] = type; + mExtMap[session] = ext; pthread_mutex_unlock(&mBiDictMutex); } void clear() { pthread_mutex_lock(&mBiDictMutex); mForwardMap.clear(); mBackwardMap.clear(); - mTypeMap.clear(); + mExtMap.clear(); pthread_mutex_unlock(&mBiDictMutex); } void rmById(uint32_t id) { pthread_mutex_lock(&mBiDictMutex); mBackwardMap.erase(mForwardMap[id]); - mTypeMap.erase(mForwardMap[id]); + mExtMap.erase(mForwardMap[id]); mForwardMap.erase(id); pthread_mutex_unlock(&mBiDictMutex); } @@ -296,7 +305,7 @@ private: pthread_mutex_lock(&mBiDictMutex); mForwardMap.erase(mBackwardMap[session]); mBackwardMap.erase(session); - mTypeMap.erase(session); + mExtMap.erase(session); pthread_mutex_unlock(&mBiDictMutex); } uint32_t getId(uint32_t session) { @@ -319,11 +328,26 @@ private: pthread_mutex_unlock(&mBiDictMutex); return ret; } - uint32_t getType(uint32_t session) { + T getExtById(uint32_t id) { pthread_mutex_lock(&mBiDictMutex); - uint32_t ret = 0; - auto it = mTypeMap.find(session); - if (it != mTypeMap.end()) { + T ret; + memset(&ret, 0, sizeof(T)); + uint32_t session = mForwardMap[id]; + if (session > 0) { + auto it = mExtMap.find(session); + if (it != mExtMap.end()) { + ret = it->second; + } + } + pthread_mutex_unlock(&mBiDictMutex); + return ret; + } + T getExtBySession(uint32_t session) { + pthread_mutex_lock(&mBiDictMutex); + T ret; + memset(&ret, 0, sizeof(T)); + auto it = mExtMap.find(session); + if (it != mExtMap.end()) { ret = it->second; } pthread_mutex_unlock(&mBiDictMutex); @@ -344,14 +368,14 @@ private: std::map mForwardMap; // mBackwardMap mapping session->id std::map mBackwardMap; - // mTypeMap mapping session->type - std::map mTypeMap; + // mExtMap mapping session->ext + std::map mExtMap; }; class StartTrackingRequest : public LocationAPIRequest { public: StartTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onStartTrackingCb(error); } LocationAPIClientBase& mAPI; @@ -360,8 +384,11 @@ private: class StopTrackingRequest : public LocationAPIRequest { public: StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t id) { mAPI.onStopTrackingCb(error); + if (error == LOCATION_ERROR_SUCCESS) { + mAPI.removeSession(id); + } } LocationAPIClientBase& mAPI; }; @@ -369,7 +396,7 @@ private: class UpdateTrackingOptionsRequest : public LocationAPIRequest { public: UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onUpdateTrackingOptionsCb(error); } LocationAPIClientBase& mAPI; @@ -378,7 +405,7 @@ private: class StartBatchingRequest : public LocationAPIRequest { public: StartBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onStartBatchingCb(error); } LocationAPIClientBase& mAPI; @@ -387,8 +414,11 @@ private: class StopBatchingRequest : public LocationAPIRequest { public: StopBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t id) { mAPI.onStopBatchingCb(error); + if (error == LOCATION_ERROR_SUCCESS) { + mAPI.removeSession(id); + } } LocationAPIClientBase& mAPI; }; @@ -396,7 +426,7 @@ private: class UpdateBatchingOptionsRequest : public LocationAPIRequest { public: UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onUpdateBatchingOptionsCb(error); } LocationAPIClientBase& mAPI; @@ -405,7 +435,7 @@ private: class GetBatchedLocationsRequest : public LocationAPIRequest { public: GetBatchedLocationsRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onGetBatchedLocationsCb(error); } LocationAPIClientBase& mAPI; @@ -485,7 +515,7 @@ private: class GnssNiResponseRequest : public LocationAPIRequest { public: GnssNiResponseRequest(LocationAPIClientBase& API) : mAPI(API) {} - inline void onResponse(LocationError error) { + inline void onResponse(LocationError error, uint32_t /*id*/) { mAPI.onGnssNiResponseCb(error); } LocationAPIClientBase& mAPI; @@ -499,8 +529,8 @@ private: LocationAPI* mLocationAPI; RequestQueue mRequestQueues[REQUEST_MAX]; - BiDict mGeofenceBiDict; - std::map mSessionMap; + BiDict mGeofenceBiDict; + BiDict mSessionBiDict; int32_t mBatchSize; };