12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115 |
- /* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation, nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #define LOG_NDEBUG 0
- #define LOG_TAG "LocSvc_BatchingAdapter"
- #include <loc_pla.h>
- #include <log_util.h>
- #include <LocContext.h>
- #include <BatchingAdapter.h>
- using namespace loc_core;
- BatchingAdapter::BatchingAdapter() :
- LocAdapterBase(0,
- LocContext::getLocContext(LocContext::mLocationHalName),
- false, nullptr, true),
- mOngoingTripDistance(0),
- mOngoingTripTBFInterval(0),
- mTripWithOngoingTBFDropped(false),
- mTripWithOngoingTripDistanceDropped(false),
- mSystemPowerState(POWER_STATE_UNKNOWN),
- mBatchingTimeout(0),
- mBatchingAccuracy(1),
- mBatchSize(0),
- mTripBatchSize(0)
- {
- LOC_LOGD("%s]: Constructor", __func__);
- readConfigCommand();
- setConfigCommand();
- // at last step, let us inform adapater base that we are done
- // with initialization, e.g.: ready to process handleEngineUpEvent
- doneInit();
- }
- void
- BatchingAdapter::readConfigCommand()
- {
- LOC_LOGD("%s]: ", __func__);
- struct MsgReadConfig : public LocMsg {
- BatchingAdapter& mAdapter;
- inline MsgReadConfig(BatchingAdapter& adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- inline virtual void proc() const {
- uint32_t batchingTimeout = 0;
- uint32_t batchingAccuracy = 0;
- uint32_t batchSize = 0;
- uint32_t tripBatchSize = 0;
- static const loc_param_s_type batching_conf_param_table[] =
- {
- {"BATCH_SIZE", &batchSize, NULL, 'n'},
- {"OUTDOOR_TRIP_BATCH_SIZE", &tripBatchSize, NULL, 'n'},
- {"BATCH_SESSION_TIMEOUT", &batchingTimeout, NULL, 'n'},
- {"ACCURACY", &batchingAccuracy, NULL, 'n'},
- };
- UTIL_READ_CONF(LOC_PATH_BATCHING_CONF, batching_conf_param_table);
- LOC_LOGD("%s]: batchSize %u tripBatchSize %u batchingAccuracy %u batchingTimeout %u ",
- __func__, batchSize, tripBatchSize, batchingAccuracy, batchingTimeout);
- mAdapter.setBatchSize(batchSize);
- mAdapter.setTripBatchSize(tripBatchSize);
- mAdapter.setBatchingTimeout(batchingTimeout);
- mAdapter.setBatchingAccuracy(batchingAccuracy);
- }
- };
- sendMsg(new MsgReadConfig(*this));
- }
- void
- BatchingAdapter::setConfigCommand()
- {
- LOC_LOGD("%s]: ", __func__);
- struct MsgSetConfig : public LocMsg {
- BatchingAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgSetConfig(BatchingAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- inline virtual void proc() const {
- mApi.setBatchSize(mAdapter.getBatchSize());
- mApi.setTripBatchSize(mAdapter.getTripBatchSize());
- }
- };
- sendMsg(new MsgSetConfig(*this, *mLocApi));
- }
- void
- BatchingAdapter::stopClientSessions(LocationAPI* client, bool eraseSession)
- {
- LOC_LOGD("%s]: client %p", __func__, client);
- typedef struct pairKeyBatchMode {
- LocationAPI* client;
- uint32_t id;
- BatchingMode batchingMode;
- inline pairKeyBatchMode(LocationAPI* _client, uint32_t _id, BatchingMode _bMode) :
- client(_client), id(_id), batchingMode(_bMode) {}
- } pairKeyBatchMode;
- std::vector<pairKeyBatchMode> vBatchingClient;
- for (auto it : mBatchingSessions) {
- if (client == it.first.client) {
- vBatchingClient.emplace_back(it.first.client, it.first.id, it.second.batchingMode);
- }
- }
- for (auto keyBatchingMode : vBatchingClient) {
- if (keyBatchingMode.batchingMode != BATCHING_MODE_TRIP) {
- stopBatching(keyBatchingMode.client, keyBatchingMode.id, eraseSession);
- } else {
- stopTripBatchingMultiplex(keyBatchingMode.client, keyBatchingMode.id, eraseSession);
- }
- }
- }
- void
- BatchingAdapter::updateClientsEventMask()
- {
- LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- // we don't register LOC_API_ADAPTER_BIT_BATCH_FULL until we
- // start batching with ROUTINE or TRIP option
- if (it->second.batchingCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_BATCH_STATUS;
- }
- }
- if (autoReportBatchingSessionsCount() > 0) {
- mask |= LOC_API_ADAPTER_BIT_BATCH_FULL;
- }
- updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
- }
- void
- BatchingAdapter::handleEngineUpEvent()
- {
- struct MsgSSREvent : public LocMsg {
- BatchingAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgSSREvent(BatchingAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- virtual void proc() const {
- mAdapter.setEngineCapabilitiesKnown(true);
- mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- mApi.setBatchSize(mAdapter.getBatchSize());
- mApi.setTripBatchSize(mAdapter.getTripBatchSize());
- if ((POWER_STATE_SUSPEND != mAdapter.mSystemPowerState) &&
- POWER_STATE_SHUTDOWN != mAdapter.mSystemPowerState) {
- mAdapter.restartSessions();
- }
- for (auto msg: mAdapter.mPendingMsgs) {
- mAdapter.sendMsg(msg);
- }
- mAdapter.mPendingMsgs.clear();
- }
- };
- sendMsg(new MsgSSREvent(*this, *mLocApi));
- }
- void
- BatchingAdapter::restartSessions()
- {
- LOC_LOGD("%s]: ", __func__);
- if (autoReportBatchingSessionsCount() > 0) {
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_ENABLED);
- }
- for (auto it = mBatchingSessions.begin();
- it != mBatchingSessions.end(); ++it) {
- if (it->second.batchingMode != BATCHING_MODE_TRIP) {
- mLocApi->startBatching(it->first.id, it->second,
- getBatchingAccuracy(), getBatchingTimeout(),
- new LocApiResponse(*getContext(),
- [] (LocationError /*err*/) {}));
- }
- }
- if (mTripSessions.size() > 0) {
- // restart outdoor trip batching session if any.
- mOngoingTripDistance = 0;
- mOngoingTripTBFInterval = 0;
- // record the min trip distance and min tbf interval of all ongoing sessions
- for (auto tripSession : mTripSessions) {
- TripSessionStatus &tripSessStatus = tripSession.second;
- if ((0 == mOngoingTripDistance) ||
- (mOngoingTripDistance >
- (tripSessStatus.tripDistance - tripSessStatus.accumulatedDistanceThisTrip))) {
- mOngoingTripDistance = tripSessStatus.tripDistance -
- tripSessStatus.accumulatedDistanceThisTrip;
- }
- if ((0 == mOngoingTripTBFInterval) ||
- (mOngoingTripTBFInterval > tripSessStatus.tripTBFInterval)) {
- mOngoingTripTBFInterval = tripSessStatus.tripTBFInterval;
- }
- // reset the accumulatedDistanceOngoingBatch for each session
- tripSessStatus.accumulatedDistanceOngoingBatch = 0;
- }
- mLocApi->startOutdoorTripBatching(mOngoingTripDistance, mOngoingTripTBFInterval,
- getBatchingTimeout(), new LocApiResponse(*getContext(), [this] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS != err) {
- mOngoingTripDistance = 0;
- mOngoingTripTBFInterval = 0;
- }
- printTripReport();
- }));
- }
- }
- bool
- BatchingAdapter::hasBatchingCallback(LocationAPI* client)
- {
- auto it = mClientData.find(client);
- return (it != mClientData.end() && it->second.batchingCb);
- }
- bool
- BatchingAdapter::isBatchingSession(LocationAPI* client, uint32_t sessionId)
- {
- LocationSessionKey key(client, sessionId);
- return (mBatchingSessions.find(key) != mBatchingSessions.end());
- }
- bool
- BatchingAdapter::isTripSession(uint32_t sessionId) {
- return (mTripSessions.find(sessionId) != mTripSessions.end());
- }
- void
- BatchingAdapter::saveBatchingSession(LocationAPI* client, uint32_t sessionId,
- const BatchingOptions& batchingOptions)
- {
- LocationSessionKey key(client, sessionId);
- mBatchingSessions[key] = batchingOptions;
- }
- void
- BatchingAdapter::eraseBatchingSession(LocationAPI* client, uint32_t sessionId)
- {
- LocationSessionKey key(client, sessionId);
- auto it = mBatchingSessions.find(key);
- if (it != mBatchingSessions.end()) {
- mBatchingSessions.erase(it);
- }
- }
- void
- BatchingAdapter::reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId)
- {
- LOC_LOGD("%s]: client %p id %u err %u", __func__, client, sessionId, err);
- auto it = mClientData.find(client);
- if (it != mClientData.end() &&
- it->second.responseCb != nullptr) {
- it->second.responseCb(err, sessionId);
- } else {
- LOC_LOGE("%s]: client %p id %u not found in data", __func__, client, sessionId);
- }
- }
- uint32_t
- BatchingAdapter::autoReportBatchingSessionsCount()
- {
- uint32_t count = 0;
- for (auto batchingSession: mBatchingSessions) {
- if (batchingSession.second.batchingMode != BATCHING_MODE_NO_AUTO_REPORT) {
- count++;
- }
- }
- count += mTripSessions.size();
- return count;
- }
- uint32_t
- BatchingAdapter::startBatchingCommand(
- LocationAPI* client, BatchingOptions& batchOptions)
- {
- uint32_t sessionId = generateSessionId();
- LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u Batching Mode %d",
- __func__, client, sessionId, batchOptions.minInterval, batchOptions.minDistance,
- batchOptions.mode,batchOptions.batchingMode);
- struct MsgStartBatching : public LocMsg {
- BatchingAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- BatchingOptions mBatchingOptions;
- inline MsgStartBatching(BatchingAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId,
- BatchingOptions batchOptions) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId),
- mBatchingOptions(batchOptions) {}
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(new MsgStartBatching(*this));
- return;
- }
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mAdapter.hasBatchingCallback(mClient)) {
- err = LOCATION_ERROR_CALLBACK_MISSING;
- } else if (0 == mBatchingOptions.size) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else if (!ContextBase::isMessageSupported(
- LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
- err = LOCATION_ERROR_NOT_SUPPORTED;
- }
- if (LOCATION_ERROR_SUCCESS == err) {
- if (mBatchingOptions.batchingMode == BATCHING_MODE_ROUTINE ||
- mBatchingOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
- mAdapter.startBatching(mClient, mSessionId, mBatchingOptions);
- } else if (mBatchingOptions.batchingMode == BATCHING_MODE_TRIP) {
- mAdapter.startTripBatchingMultiplex(mClient, mSessionId, mBatchingOptions);
- } else {
- mAdapter.reportResponse(mClient, LOCATION_ERROR_INVALID_PARAMETER, mSessionId);
- }
- }
- }
- };
- sendMsg(new MsgStartBatching(*this, *mLocApi, client, sessionId, batchOptions));
- return sessionId;
- }
- void
- BatchingAdapter::startBatching(LocationAPI* client, uint32_t sessionId,
- const BatchingOptions& batchingOptions)
- {
- if (batchingOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT &&
- 0 == autoReportBatchingSessionsCount()) {
- // if there is currenty no batching sessions interested in batch full event, then this
- // new session will need to register for batch full event
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_ENABLED);
- }
- // Assume start will be OK, remove session if not
- saveBatchingSession(client, sessionId, batchingOptions);
- mLocApi->startBatching(sessionId, batchingOptions, getBatchingAccuracy(), getBatchingTimeout(),
- new LocApiResponse(*getContext(),
- [this, client, sessionId, batchingOptions] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS != err) {
- eraseBatchingSession(client, sessionId);
- }
- if (LOCATION_ERROR_SUCCESS != err &&
- batchingOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT &&
- 0 == autoReportBatchingSessionsCount()) {
- // if we fail to start batching and we have already registered batch full event
- // we need to undo that since no sessions are now interested in batch full event
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_DISABLED);
- }
- reportResponse(client, err, sessionId);
- }));
- }
- void
- BatchingAdapter::updateBatchingOptionsCommand(LocationAPI* client, uint32_t id,
- BatchingOptions& batchOptions)
- {
- LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u batchMode %u",
- __func__, client, id, batchOptions.minInterval,
- batchOptions.minDistance, batchOptions.mode,
- batchOptions.batchingMode);
- struct MsgUpdateBatching : public LocMsg {
- BatchingAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- BatchingOptions mBatchOptions;
- inline MsgUpdateBatching(BatchingAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId,
- BatchingOptions batchOptions) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId),
- mBatchOptions(batchOptions) {}
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(new MsgUpdateBatching(*this));
- return;
- }
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
- err = LOCATION_ERROR_ID_UNKNOWN;
- } else if ((0 == mBatchOptions.size) ||
- (mBatchOptions.batchingMode > BATCHING_MODE_NO_AUTO_REPORT)) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- }
- if (LOCATION_ERROR_SUCCESS == err) {
- if (!mAdapter.isTripSession(mSessionId)) {
- mAdapter.stopBatching(mClient, mSessionId, true, mBatchOptions);
- } else {
- mAdapter.stopTripBatchingMultiplex(mClient, mSessionId, true, mBatchOptions);
- }
- }
- }
- };
- sendMsg(new MsgUpdateBatching(*this, *mLocApi, client, id, batchOptions));
- }
- void
- BatchingAdapter::stopBatchingCommand(LocationAPI* client, uint32_t id)
- {
- LOC_LOGD("%s]: client %p id %u", __func__, client, id);
- struct MsgStopBatching : public LocMsg {
- BatchingAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- inline MsgStopBatching(BatchingAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId) {}
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(new MsgStopBatching(*this));
- return;
- }
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
- err = LOCATION_ERROR_ID_UNKNOWN;
- }
- if (LOCATION_ERROR_SUCCESS == err) {
- if (mAdapter.isTripSession(mSessionId)) {
- mAdapter.stopTripBatchingMultiplex(mClient, mSessionId);
- } else {
- mAdapter.stopBatching(mClient, mSessionId);
- }
- }
- }
- };
- sendMsg(new MsgStopBatching(*this, *mLocApi, client, id));
- }
- void
- BatchingAdapter::stopBatching(LocationAPI* client, uint32_t sessionId, bool restartNeeded,
- const BatchingOptions& batchOptions, bool eraseSession)
- {
- LocationSessionKey key(client, sessionId);
- auto it = mBatchingSessions.find(key);
- if (it != mBatchingSessions.end()) {
- auto flpOptions = it->second;
- // Assume stop will be OK, restore session if not
- if (eraseSession)
- eraseBatchingSession(client, sessionId);
- mLocApi->stopBatching(sessionId,
- new LocApiResponse(*getContext(),
- [this, client, sessionId, flpOptions, restartNeeded, batchOptions, eraseSession]
- (LocationError err) {
- if (LOCATION_ERROR_SUCCESS != err) {
- if (eraseSession)
- saveBatchingSession(client, sessionId, batchOptions);
- } else {
- // if stopBatching is success, unregister for batch full event if this was the last
- // batching session that is interested in batch full event
- if (0 == autoReportBatchingSessionsCount() &&
- flpOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT) {
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_DISABLED);
- }
- if (restartNeeded) {
- if (batchOptions.batchingMode == BATCHING_MODE_ROUTINE ||
- batchOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
- startBatching(client, sessionId, batchOptions);
- } else if (batchOptions.batchingMode == BATCHING_MODE_TRIP) {
- startTripBatchingMultiplex(client, sessionId, batchOptions);
- }
- }
- }
- reportResponse(client, err, sessionId);
- }));
- }
- }
- void
- BatchingAdapter::getBatchedLocationsCommand(LocationAPI* client, uint32_t id, size_t count)
- {
- LOC_LOGD("%s]: client %p id %u count %zu", __func__, client, id, count);
- struct MsgGetBatchedLocations : public LocMsg {
- BatchingAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- uint32_t mSessionId;
- size_t mCount;
- inline MsgGetBatchedLocations(BatchingAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- uint32_t sessionId,
- size_t count) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mSessionId(sessionId),
- mCount(count) {}
- inline virtual void proc() const {
- if (!mAdapter.isEngineCapabilitiesKnown()) {
- mAdapter.mPendingMsgs.push_back(new MsgGetBatchedLocations(*this));
- return;
- }
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mAdapter.hasBatchingCallback(mClient)) {
- err = LOCATION_ERROR_CALLBACK_MISSING;
- } else if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
- err = LOCATION_ERROR_ID_UNKNOWN;
- }
- if (LOCATION_ERROR_SUCCESS == err) {
- if (mAdapter.isTripSession(mSessionId)) {
- mApi.getBatchedTripLocations(mCount, 0,
- new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mSessionId = mSessionId,
- mClient = mClient] (LocationError err) {
- mAdapter.reportResponse(mClient, err, mSessionId);
- }));
- } else {
- mApi.getBatchedLocations(mCount, new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mSessionId = mSessionId,
- mClient = mClient] (LocationError err) {
- mAdapter.reportResponse(mClient, err, mSessionId);
- }));
- }
- } else {
- mAdapter.reportResponse(mClient, err, mSessionId);
- }
- }
- };
- sendMsg(new MsgGetBatchedLocations(*this, *mLocApi, client, id, count));
- }
- void
- BatchingAdapter::reportLocationsEvent(const Location* locations, size_t count,
- BatchingMode batchingMode)
- {
- LOC_LOGD("%s]: count %zu batchMode %d", __func__, count, batchingMode);
- struct MsgReportLocations : public LocMsg {
- BatchingAdapter& mAdapter;
- Location* mLocations;
- size_t mCount;
- BatchingMode mBatchingMode;
- inline MsgReportLocations(BatchingAdapter& adapter,
- const Location* locations,
- size_t count,
- BatchingMode batchingMode) :
- LocMsg(),
- mAdapter(adapter),
- mLocations(new Location[count]),
- mCount(count),
- mBatchingMode(batchingMode)
- {
- if (nullptr == mLocations) {
- LOC_LOGE("%s]: new failed to allocate mLocations", __func__);
- return;
- }
- for (size_t i=0; i < mCount; ++i) {
- mLocations[i] = locations[i];
- }
- }
- inline virtual ~MsgReportLocations() {
- if (nullptr != mLocations)
- delete[] mLocations;
- }
- inline virtual void proc() const {
- mAdapter.reportLocations(mLocations, mCount, mBatchingMode);
- }
- };
- sendMsg(new MsgReportLocations(*this, locations, count, batchingMode));
- }
- void
- BatchingAdapter::reportLocations(Location* locations, size_t count, BatchingMode batchingMode)
- {
- BatchingOptions batchOptions = {sizeof(BatchingOptions), batchingMode};
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.batchingCb) {
- it->second.batchingCb(count, locations, batchOptions);
- }
- }
- }
- void
- BatchingAdapter::reportCompletedTripsEvent(uint32_t accumulated_distance)
- {
- struct MsgReportCompletedTrips : public LocMsg {
- BatchingAdapter& mAdapter;
- uint32_t mAccumulatedDistance;
- inline MsgReportCompletedTrips(BatchingAdapter& adapter,
- uint32_t accumulated_distance) :
- LocMsg(),
- mAdapter(adapter),
- mAccumulatedDistance(accumulated_distance)
- {
- }
- inline virtual ~MsgReportCompletedTrips() {
- }
- inline virtual void proc() const {
- // Check if any trips are completed
- std::list<uint32_t> completedTripsList;
- completedTripsList.clear();
- for(auto itt = mAdapter.mTripSessions.begin(); itt != mAdapter.mTripSessions.end();)
- {
- TripSessionStatus &tripSession = itt->second;
- tripSession.accumulatedDistanceThisTrip =
- tripSession.accumulatedDistanceOnTripRestart
- + (mAccumulatedDistance - tripSession.accumulatedDistanceOngoingBatch);
- if (tripSession.tripDistance <= tripSession.accumulatedDistanceThisTrip) {
- // trip is completed
- completedTripsList.push_back(itt->first);
- itt = mAdapter.mTripSessions.erase(itt);
- if (tripSession.tripTBFInterval == mAdapter.mOngoingTripTBFInterval) {
- // trip with ongoing TBF interval is completed
- mAdapter.mTripWithOngoingTBFDropped = true;
- }
- if (tripSession.tripDistance == mAdapter.mOngoingTripDistance) {
- // trip with ongoing trip distance is completed
- mAdapter.mTripWithOngoingTripDistanceDropped = true;
- }
- } else {
- itt++;
- }
- }
- if (completedTripsList.size() > 0) {
- mAdapter.reportBatchStatusChange(BATCHING_STATUS_TRIP_COMPLETED,
- completedTripsList);
- mAdapter.restartTripBatching(false, mAccumulatedDistance, 0);
- } else {
- mAdapter.printTripReport();
- }
- }
- };
- LOC_LOGD("%s]: Accumulated Distance so far: %u",
- __func__, accumulated_distance);
- sendMsg(new MsgReportCompletedTrips(*this, accumulated_distance));
- }
- void
- BatchingAdapter::reportBatchStatusChange(BatchingStatus batchStatus,
- std::list<uint32_t> & completedTripsList)
- {
- BatchingStatusInfo batchStatusInfo =
- {sizeof(BatchingStatusInfo), batchStatus};
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.batchingStatusCb) {
- it->second.batchingStatusCb(batchStatusInfo, completedTripsList);
- }
- }
- }
- void
- BatchingAdapter::reportBatchStatusChangeEvent(BatchingStatus batchStatus)
- {
- struct MsgReportBatchStatus : public LocMsg {
- BatchingAdapter& mAdapter;
- BatchingStatus mBatchStatus;
- inline MsgReportBatchStatus(BatchingAdapter& adapter,
- BatchingStatus batchStatus) :
- LocMsg(),
- mAdapter(adapter),
- mBatchStatus(batchStatus)
- {
- }
- inline virtual ~MsgReportBatchStatus() {
- }
- inline virtual void proc() const {
- std::list<uint32_t> tempList;
- tempList.clear();
- mAdapter.reportBatchStatusChange(mBatchStatus, tempList);
- }
- };
- sendMsg(new MsgReportBatchStatus(*this, batchStatus));
- }
- void
- BatchingAdapter::startTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
- const BatchingOptions& batchingOptions)
- {
- if (mTripSessions.size() == 0) {
- // if there is currenty no batching sessions interested in batch full event, then this
- // new session will need to register for batch full event
- if (0 == autoReportBatchingSessionsCount()) {
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_ENABLED);
- }
- // Assume start will be OK, remove session if not
- saveBatchingSession(client, sessionId, batchingOptions);
- mTripSessions[sessionId] = { 0, 0, 0, batchingOptions.minDistance,
- batchingOptions.minInterval};
- mLocApi->startOutdoorTripBatching(batchingOptions.minDistance,
- batchingOptions.minInterval, getBatchingTimeout(), new LocApiResponse(*getContext(),
- [this, client, sessionId, batchingOptions] (LocationError err) {
- if (err == LOCATION_ERROR_SUCCESS) {
- mOngoingTripDistance = batchingOptions.minDistance;
- mOngoingTripTBFInterval = batchingOptions.minInterval;
- LOC_LOGD("%s] New Trip started ...", __func__);
- printTripReport();
- } else {
- eraseBatchingSession(client, sessionId);
- mTripSessions.erase(sessionId);
- // if we fail to start batching and we have already registered batch full event
- // we need to undo that since no sessions are now interested in batch full event
- if (0 == autoReportBatchingSessionsCount()) {
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_DISABLED);
- }
- }
- reportResponse(client, err, sessionId);
- }));
- } else {
- // query accumulated distance
- mLocApi->queryAccumulatedTripDistance(
- new LocApiResponseData<LocApiBatchData>(*getContext(),
- [this, batchingOptions, sessionId, client]
- (LocationError err, LocApiBatchData data) {
- uint32_t accumulatedDistanceOngoingBatch = 0;
- uint32_t numOfBatchedPositions = 0;
- uint32_t ongoingTripDistance = mOngoingTripDistance;
- uint32_t ongoingTripInterval = mOngoingTripTBFInterval;
- bool needsRestart = false;
- // check if TBF of new session is lesser than ongoing TBF interval
- if (ongoingTripInterval > batchingOptions.minInterval) {
- ongoingTripInterval = batchingOptions.minInterval;
- needsRestart = true;
- }
- accumulatedDistanceOngoingBatch = data.accumulatedDistance;
- numOfBatchedPositions = data.numOfBatchedPositions;
- TripSessionStatus newTripSession = { accumulatedDistanceOngoingBatch, 0, 0,
- batchingOptions.minDistance,
- batchingOptions.minInterval};
- if (err != LOCATION_ERROR_SUCCESS) {
- // unable to query accumulated distance, assume remaining distance in
- // ongoing batch is mongoingTripDistance.
- if (batchingOptions.minDistance < ongoingTripDistance) {
- ongoingTripDistance = batchingOptions.minDistance;
- needsRestart = true;
- }
- } else {
- // compute the remaining distance
- uint32_t ongoing_trip_remaining_distance = ongoingTripDistance -
- accumulatedDistanceOngoingBatch;
- // check if new trip distance is lesser than the ongoing batch remaining distance
- if (batchingOptions.minDistance < ongoing_trip_remaining_distance) {
- ongoingTripDistance = batchingOptions.minDistance;
- needsRestart = true;
- } else if (needsRestart == true) {
- // needsRestart is anyways true , may be because of lesser TBF of new session.
- ongoingTripDistance = ongoing_trip_remaining_distance;
- }
- mTripSessions[sessionId] = newTripSession;
- LOC_LOGD("%s] New Trip started ...", __func__);
- printTripReport();
- }
- if (needsRestart) {
- mOngoingTripDistance = ongoingTripDistance;
- mOngoingTripTBFInterval = ongoingTripInterval;
- // reset the accumulatedDistanceOngoingBatch for each session,
- // and record the total accumulated distance so far for the session.
- for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
- TripSessionStatus &tripSessStatus = itt->second;
- tripSessStatus.accumulatedDistanceOngoingBatch = 0;
- tripSessStatus.accumulatedDistanceOnTripRestart =
- tripSessStatus.accumulatedDistanceThisTrip;
- }
- mLocApi->reStartOutdoorTripBatching(ongoingTripDistance, ongoingTripInterval,
- getBatchingTimeout(), new LocApiResponse(*getContext(),
- [this, client, sessionId] (LocationError err) {
- if (err != LOCATION_ERROR_SUCCESS) {
- LOC_LOGE("%s] New Trip restart failed!", __func__);
- }
- reportResponse(client, err, sessionId);
- }));
- } else {
- reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
- }
- }));
- }
- }
- void
- BatchingAdapter::stopTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
- bool restartNeeded, const BatchingOptions& batchOptions, bool eraseSession)
- {
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (mTripSessions.size() == 1) {
- mLocApi->stopOutdoorTripBatching(true, new LocApiResponse(*getContext(),
- [this, restartNeeded, client, sessionId, batchOptions, eraseSession]
- (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- // if stopOutdoorTripBatching is success, unregister for batch full event if this
- // was the last batching session that is interested in batch full event
- if (1 == autoReportBatchingSessionsCount()) {
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_DISABLED);
- }
- }
- stopTripBatchingMultiplexCommon(err, client, sessionId, restartNeeded,
- batchOptions, eraseSession);
- }));
- return;
- }
- stopTripBatchingMultiplexCommon(err, client, sessionId, restartNeeded,
- batchOptions, eraseSession);
- }
- void
- BatchingAdapter::stopTripBatchingMultiplexCommon(LocationError err, LocationAPI* client,
- uint32_t sessionId, bool restartNeeded, const BatchingOptions& batchOptions,
- bool eraseSession)
- {
- auto itt = mTripSessions.find(sessionId);
- TripSessionStatus tripSess = itt->second;
- if (tripSess.tripTBFInterval == mOngoingTripTBFInterval) {
- // trip with ongoing trip interval is stopped
- mTripWithOngoingTBFDropped = true;
- }
- if (tripSess.tripDistance == mOngoingTripDistance) {
- // trip with ongoing trip distance is stopped
- mTripWithOngoingTripDistanceDropped = true;
- }
- if (eraseSession)
- mTripSessions.erase(sessionId);
- if (mTripSessions.size() == 0) {
- mOngoingTripDistance = 0;
- mOngoingTripTBFInterval = 0;
- } else {
- restartTripBatching(true);
- }
- if (restartNeeded) {
- eraseBatchingSession(client, sessionId);
- if (batchOptions.batchingMode == BATCHING_MODE_ROUTINE ||
- batchOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
- startBatching(client, sessionId, batchOptions);
- } else if (batchOptions.batchingMode == BATCHING_MODE_TRIP) {
- startTripBatchingMultiplex(client, sessionId, batchOptions);
- }
- }
- reportResponse(client, err, sessionId);
- }
- void
- BatchingAdapter::restartTripBatching(bool queryAccumulatedDistance, uint32_t accDist,
- uint32_t numbatchedPos)
- {
- // does batch need restart with new trip distance / TBF interval
- uint32_t minRemainingDistance = 0;
- uint32_t minTBFInterval = 0;
- // if no more trips left, stop the ongoing trip
- if (mTripSessions.size() == 0) {
- mLocApi->stopOutdoorTripBatching(true, new LocApiResponse(*getContext(),
- [] (LocationError /*err*/) {}));
- mOngoingTripDistance = 0;
- mOngoingTripTBFInterval = 0;
- // unregister for batch full event if there are no more
- // batching session that is interested in batch full event
- if (0 == autoReportBatchingSessionsCount()) {
- updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
- LOC_REGISTRATION_MASK_DISABLED);
- }
- return;
- }
- // record the min trip distance and min tbf interval of all ongoing sessions
- for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
- TripSessionStatus tripSessStatus = itt->second;
- if ((minRemainingDistance == 0) ||
- (minRemainingDistance > (tripSessStatus.tripDistance
- - tripSessStatus.accumulatedDistanceThisTrip))) {
- minRemainingDistance = tripSessStatus.tripDistance -
- tripSessStatus.accumulatedDistanceThisTrip;
- }
- if ((minTBFInterval == 0) ||
- (minTBFInterval > tripSessStatus.tripTBFInterval)) {
- minTBFInterval = tripSessStatus.tripTBFInterval;
- }
- }
- mLocApi->queryAccumulatedTripDistance(
- new LocApiResponseData<LocApiBatchData>(*getContext(),
- [this, queryAccumulatedDistance, minRemainingDistance, minTBFInterval, accDist,
- numbatchedPos] (LocationError /*err*/, LocApiBatchData data) {
- bool needsRestart = false;
- uint32_t ongoingTripDistance = mOngoingTripDistance;
- uint32_t ongoingTripInterval = mOngoingTripTBFInterval;
- uint32_t accumulatedDistance = accDist;
- uint32_t numOfBatchedPositions = numbatchedPos;
- if (queryAccumulatedDistance) {
- accumulatedDistance = data.accumulatedDistance;
- numOfBatchedPositions = data.numOfBatchedPositions;
- }
- if ((!mTripWithOngoingTripDistanceDropped) &&
- (ongoingTripDistance - accumulatedDistance != 0)) {
- // if ongoing trip is already not completed still,
- // check the min distance against the remaining distance
- if (minRemainingDistance <
- (ongoingTripDistance - accumulatedDistance)) {
- ongoingTripDistance = minRemainingDistance;
- needsRestart = true;
- }
- } else if (minRemainingDistance != 0) {
- // else if ongoing trip is already completed / dropped,
- // use the minRemainingDistance of ongoing sessions
- ongoingTripDistance = minRemainingDistance;
- needsRestart = true;
- }
- if ((minTBFInterval < ongoingTripInterval) ||
- ((minTBFInterval != ongoingTripInterval) &&
- (mTripWithOngoingTBFDropped))) {
- ongoingTripInterval = minTBFInterval;
- needsRestart = true;
- }
- if (needsRestart) {
- mLocApi->reStartOutdoorTripBatching(ongoingTripDistance, ongoingTripInterval,
- getBatchingTimeout(), new LocApiResponse(*getContext(),
- [this, accumulatedDistance, ongoingTripDistance, ongoingTripInterval]
- (LocationError err) {
- if (err == LOCATION_ERROR_SUCCESS) {
- for(auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
- TripSessionStatus &tripSessStatus = itt->second;
- tripSessStatus.accumulatedDistanceThisTrip =
- tripSessStatus.accumulatedDistanceOnTripRestart +
- (accumulatedDistance -
- tripSessStatus.accumulatedDistanceOngoingBatch);
- tripSessStatus.accumulatedDistanceOngoingBatch = 0;
- tripSessStatus.accumulatedDistanceOnTripRestart =
- tripSessStatus.accumulatedDistanceThisTrip;
- }
- mOngoingTripDistance = ongoingTripDistance;
- mOngoingTripTBFInterval = ongoingTripInterval;
- }
- }));
- }
- }));
- }
- void
- BatchingAdapter::updateSystemPowerStateCommand(PowerStateType powerState)
- {
- LOC_LOGD("%s]: powerState: %d", __func__, powerState);
- struct MsgUpdateSystemPowerState : public LocMsg {
- BatchingAdapter& mAdapter;
- PowerStateType mPowerState;
- inline MsgUpdateSystemPowerState(BatchingAdapter& adapter,
- PowerStateType powerState) :
- mAdapter(adapter),
- mPowerState(powerState) {}
- inline virtual void proc() const {
- mAdapter.updateSystemPowerState(mPowerState);
- }
- };
- sendMsg(new MsgUpdateSystemPowerState(*this, powerState));
- }
- void
- BatchingAdapter::suspendBatchingSessions()
- {
- for (auto it = mBatchingSessions.begin(); it != mBatchingSessions.end(); ++it) {
- LocationSessionKey key(it->first);
- stopClientSessions(key.client, false);
- }
- }
- void
- BatchingAdapter::updateSystemPowerState(PowerStateType systemPowerState)
- {
- if (POWER_STATE_UNKNOWN != systemPowerState) {
- mSystemPowerState = systemPowerState;
- /*Manage active GNSS sessions based on power event*/
- switch (systemPowerState){
- case POWER_STATE_SUSPEND:
- case POWER_STATE_SHUTDOWN:
- suspendBatchingSessions();
- LOC_LOGd("Suspending all Batching session -- powerState: %d", systemPowerState);
- break;
- case POWER_STATE_RESUME:
- restartSessions();
- LOC_LOGd("Re-starting all Batching session -- powerState: %d", systemPowerState);
- break;
- default:
- break;
- } // switch
- }
- }
- void
- BatchingAdapter::printTripReport()
- {
- IF_LOC_LOGD {
- LOC_LOGD("Ongoing Trip Distance = %u, Ongoing Trip TBF Interval = %u",
- mOngoingTripDistance, mOngoingTripTBFInterval);
- for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
- TripSessionStatus tripSessStatus = itt->second;
- LOC_LOGD("tripDistance:%u tripTBFInterval:%u"
- " trip accumulated Distance:%u"
- " trip accumualted distance ongoing batch:%u"
- " trip accumulated distance on trip restart %u \r\n",
- tripSessStatus.tripDistance, tripSessStatus.tripTBFInterval,
- tripSessStatus.accumulatedDistanceThisTrip,
- tripSessStatus.accumulatedDistanceOngoingBatch,
- tripSessStatus.accumulatedDistanceOnTripRestart);
- }
- }
- }
|