123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985 |
- /* Copyright (c) 2013-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.
- *
- */
- /*
- Changes from Qualcomm Innovation Center are provided under the following license:
- Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted (subject to the limitations in the
- disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
- GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
- HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER 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_TAG "LocSvc_GeofenceAdapter"
- #include <GeofenceAdapter.h>
- #include "loc_log.h"
- #include <log_util.h>
- #include <string>
- using namespace loc_core;
- GeofenceAdapter::GeofenceAdapter() :
- LocAdapterBase(0,
- LocContext::getLocContext(LocContext::mLocationHalName),
- true /*isMaster*/, nullptr, true),
- mSystemPowerState(POWER_STATE_UNKNOWN)
- {
- LOC_LOGD("%s]: Constructor", __func__);
- // at last step, let us inform adapater base that we are done
- // with initialization, e.g.: ready to process handleEngineUpEvent
- doneInit();
- }
- void
- GeofenceAdapter::stopClientSessions(LocationAPI* client, bool eraseSession)
- {
- LOC_LOGD("%s]: client %p", __func__, client);
- for (auto it = mGeofenceIds.begin(); it != mGeofenceIds.end();) {
- uint32_t hwId = it->second;
- GeofenceKey key(it->first);
- if (client == key.client) {
- if (eraseSession)
- it = mGeofenceIds.erase(it);
- mLocApi->removeGeofence(hwId, key.id,
- new LocApiResponse(*getContext(),
- [this, hwId, eraseSession] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- auto it2 = mGeofences.find(hwId);
- if (it2 != mGeofences.end()) {
- if (eraseSession)
- mGeofences.erase(it2);
- } else {
- LOC_LOGE("%s]:geofence item to erase not found. hwId %u", __func__, hwId);
- }
- }
- }));
- continue;
- }
- ++it; // increment only when not erasing an iterator
- }
- }
- void
- GeofenceAdapter::updateClientsEventMask()
- {
- LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
- for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (it->second.geofenceBreachCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT;
- mask |= LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL;
- }
- if (it->second.geofenceStatusCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT;
- }
- }
- updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
- }
- LocationError
- GeofenceAdapter::getHwIdFromClient(LocationAPI* client, uint32_t clientId, uint32_t& hwId)
- {
- GeofenceKey key(client, clientId);
- auto it = mGeofenceIds.find(key);
- if (it != mGeofenceIds.end()) {
- hwId = it->second;
- return LOCATION_ERROR_SUCCESS;
- }
- return LOCATION_ERROR_ID_UNKNOWN;
- }
- LocationError
- GeofenceAdapter::getGeofenceKeyFromHwId(uint32_t hwId, GeofenceKey& key)
- {
- auto it = mGeofences.find(hwId);
- if (it != mGeofences.end()) {
- key = it->second.key;
- return LOCATION_ERROR_SUCCESS;
- }
- return LOCATION_ERROR_ID_UNKNOWN;
- }
- void
- GeofenceAdapter::handleEngineUpEvent()
- {
- struct MsgSSREvent : public LocMsg {
- GeofenceAdapter& mAdapter;
- inline MsgSSREvent(GeofenceAdapter& adapter) :
- LocMsg(),
- mAdapter(adapter) {}
- virtual void proc() const {
- mAdapter.setEngineCapabilitiesKnown(true);
- mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- if ((POWER_STATE_SUSPEND != mAdapter.mSystemPowerState) &&
- POWER_STATE_SHUTDOWN != mAdapter.mSystemPowerState) {
- mAdapter.restartGeofences();
- }
- for (auto msg: mAdapter.mPendingMsgs) {
- mAdapter.sendMsg(msg);
- }
- mAdapter.mPendingMsgs.clear();
- }
- };
- sendMsg(new MsgSSREvent(*this));
- }
- void
- GeofenceAdapter::restartGeofences()
- {
- if (mGeofences.empty()) {
- return;
- }
- GeofencesMap oldGeofences(mGeofences);
- mGeofences.clear();
- mGeofenceIds.clear();
- for (auto it = oldGeofences.begin(); it != oldGeofences.end(); it++) {
- GeofenceObject object = it->second;
- GeofenceOption options = {sizeof(GeofenceOption),
- object.breachMask,
- object.responsiveness,
- object.dwellTime,
- object.confidence};
- GeofenceInfo info = {sizeof(GeofenceInfo),
- object.latitude,
- object.longitude,
- object.radius};
- mLocApi->addGeofence(object.key.id,
- options,
- info,
- new LocApiResponseData<LocApiGeofenceData>(*getContext(),
- [this, object, options, info] (LocationError err, LocApiGeofenceData data) {
- if (LOCATION_ERROR_SUCCESS == err) {
- if (true == object.paused) {
- mLocApi->pauseGeofence(data.hwId, object.key.id,
- new LocApiResponse(*getContext(), [] (LocationError err __unused) {}));
- }
- saveGeofenceItem(object.key.client, object.key.id, data.hwId, options, info);
- }
- }));
- }
- }
- void
- GeofenceAdapter::reportResponse(LocationAPI* client, size_t count, LocationError* errs,
- uint32_t* ids)
- {
- IF_LOC_LOGD {
- std::string idsString = "[";
- std::string errsString = "[";
- if (NULL != ids && NULL != errs) {
- for (size_t i=0; i < count; ++i) {
- idsString += std::to_string(ids[i]) + " ";
- errsString += std::to_string(errs[i]) + " ";
- }
- }
- idsString += "]";
- errsString += "]";
- LOC_LOGD("%s]: client %p ids %s errs %s",
- __func__, client, idsString.c_str(), errsString.c_str());
- }
- auto it = mClientData.find(client);
- if (it != mClientData.end() && it->second.collectiveResponseCb != nullptr) {
- it->second.collectiveResponseCb(count, errs, ids);
- } else {
- LOC_LOGE("%s]: client %p response not found in info", __func__, client);
- }
- }
- uint32_t*
- GeofenceAdapter::addGeofencesCommand(LocationAPI* client, size_t count, GeofenceOption* options,
- GeofenceInfo* infos)
- {
- LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
- struct MsgAddGeofences : public LocMsg {
- GeofenceAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- size_t mCount;
- uint32_t* mIds;
- GeofenceOption* mOptions;
- GeofenceInfo* mInfos;
- inline MsgAddGeofences(GeofenceAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- size_t count,
- uint32_t* ids,
- GeofenceOption* options,
- GeofenceInfo* infos) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mCount(count),
- mIds(ids),
- mOptions(options),
- mInfos(infos) {}
- inline virtual void proc() const {
- LocationError* errs = new LocationError[mCount];
- if (nullptr == errs) {
- LOC_LOGE("%s]: new failed to allocate errs", __func__);
- return;
- }
- for (size_t i=0; i < mCount; ++i) {
- if (NULL == mIds || NULL == mOptions || NULL == mInfos) {
- errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
- mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient,
- mOptions = mOptions, mInfos = mInfos, mIds = mIds, &mApi = mApi,
- errs, i] (LocationError err __unused) {
- mApi.addGeofence(mIds[i], mOptions[i], mInfos[i],
- new LocApiResponseData<LocApiGeofenceData>(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mOptions = mOptions, mClient = mClient,
- mCount = mCount, mIds = mIds, mInfos = mInfos, errs, i]
- (LocationError err, LocApiGeofenceData data) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.saveGeofenceItem(mClient,
- mIds[i],
- data.hwId,
- mOptions[i],
- mInfos[i]);
- }
- errs[i] = err;
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- delete[] mOptions;
- delete[] mInfos;
- }
- }));
- }));
- }
- }
- }
- };
- if (0 == count) {
- return NULL;
- }
- uint32_t* ids = new uint32_t[count];
- if (nullptr == ids) {
- LOC_LOGE("%s]: new failed to allocate ids", __func__);
- return NULL;
- }
- if (NULL != ids) {
- for (size_t i=0; i < count; ++i) {
- ids[i] = generateSessionId();
- }
- }
- GeofenceOption* optionsCopy;
- if (options == NULL) {
- optionsCopy = NULL;
- } else {
- optionsCopy = new GeofenceOption[count];
- if (nullptr == optionsCopy) {
- LOC_LOGE("%s]: new failed to allocate optionsCopy", __func__);
- return NULL;
- }
- COPY_IF_NOT_NULL(optionsCopy, options, count);
- }
- GeofenceInfo* infosCopy;
- if (infos == NULL) {
- infosCopy = NULL;
- } else {
- infosCopy = new GeofenceInfo[count];
- if (nullptr == infosCopy) {
- LOC_LOGE("%s]: new failed to allocate infosCopy", __func__);
- return NULL;
- }
- COPY_IF_NOT_NULL(infosCopy, infos, count);
- }
- sendMsg(new MsgAddGeofences(*this, *mLocApi, client, count, ids, optionsCopy, infosCopy));
- return ids;
- }
- void
- GeofenceAdapter::removeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
- {
- LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
- struct MsgRemoveGeofences : public LocMsg {
- GeofenceAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- size_t mCount;
- uint32_t* mIds;
- inline MsgRemoveGeofences(GeofenceAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- size_t count,
- uint32_t* ids) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mCount(count),
- mIds(ids) {}
- inline virtual void proc() const {
- LocationError* errs = new LocationError[mCount];
- if (nullptr == errs) {
- LOC_LOGE("%s]: new failed to allocate errs", __func__);
- return;
- }
- for (size_t i=0; i < mCount; ++i) {
- mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
- &mApi = mApi, errs, i] (LocationError err __unused) {
- uint32_t hwId = 0;
- errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
- if (LOCATION_ERROR_SUCCESS == errs[i]) {
- mApi.removeGeofence(hwId, mIds[i],
- new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
- hwId, errs, i] (LocationError err ) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.removeGeofenceItem(hwId);
- }
- errs[i] = err;
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- }
- }));
- } else {
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- }
- }
- }));
- }
- }
- };
- if (0 == count) {
- return;
- }
- uint32_t* idsCopy = new uint32_t[count];
- if (nullptr == idsCopy) {
- LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
- return;
- }
- COPY_IF_NOT_NULL(idsCopy, ids, count);
- sendMsg(new MsgRemoveGeofences(*this, *mLocApi, client, count, idsCopy));
- }
- void
- GeofenceAdapter::pauseGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
- {
- LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
- struct MsgPauseGeofences : public LocMsg {
- GeofenceAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- size_t mCount;
- uint32_t* mIds;
- inline MsgPauseGeofences(GeofenceAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- size_t count,
- uint32_t* ids) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mCount(count),
- mIds(ids) {}
- inline virtual void proc() const {
- LocationError* errs = new LocationError[mCount];
- if (nullptr == errs) {
- LOC_LOGE("%s]: new failed to allocate errs", __func__);
- return;
- }
- for (size_t i=0; i < mCount; ++i) {
- mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
- &mApi = mApi, errs, i] (LocationError err __unused) {
- uint32_t hwId = 0;
- errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
- if (LOCATION_ERROR_SUCCESS == errs[i]) {
- mApi.pauseGeofence(hwId, mIds[i], new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
- hwId, errs, i] (LocationError err ) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.pauseGeofenceItem(hwId);
- }
- errs[i] = err;
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- }
- }));
- } else {
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- }
- }
- }));
- }
- }
- };
- if (0 == count) {
- return;
- }
- uint32_t* idsCopy = new uint32_t[count];
- if (nullptr == idsCopy) {
- LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
- return;
- }
- COPY_IF_NOT_NULL(idsCopy, ids, count);
- sendMsg(new MsgPauseGeofences(*this, *mLocApi, client, count, idsCopy));
- }
- void
- GeofenceAdapter::resumeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
- {
- LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
- struct MsgResumeGeofences : public LocMsg {
- GeofenceAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- size_t mCount;
- uint32_t* mIds;
- inline MsgResumeGeofences(GeofenceAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- size_t count,
- uint32_t* ids) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mCount(count),
- mIds(ids) {}
- inline virtual void proc() const {
- LocationError* errs = new LocationError[mCount];
- if (nullptr == errs) {
- LOC_LOGE("%s]: new failed to allocate errs", __func__);
- return;
- }
- for (size_t i=0; i < mCount; ++i) {
- mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
- &mApi = mApi, errs, i] (LocationError err __unused) {
- uint32_t hwId = 0;
- errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
- if (LOCATION_ERROR_SUCCESS == errs[i]) {
- mApi.resumeGeofence(hwId, mIds[i],
- new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, hwId,
- errs, mIds = mIds, i] (LocationError err ) {
- if (LOCATION_ERROR_SUCCESS == err) {
- errs[i] = err;
- mAdapter.resumeGeofenceItem(hwId);
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- }
- }
- }));
- } else {
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- }
- }
- }));
- }
- }
- };
- if (0 == count) {
- return;
- }
- uint32_t* idsCopy = new uint32_t[count];
- if (nullptr == idsCopy) {
- LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
- return;
- }
- COPY_IF_NOT_NULL(idsCopy, ids, count);
- sendMsg(new MsgResumeGeofences(*this, *mLocApi, client, count, idsCopy));
- }
- void
- GeofenceAdapter::modifyGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids,
- GeofenceOption* options)
- {
- LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
- struct MsgModifyGeofences : public LocMsg {
- GeofenceAdapter& mAdapter;
- LocApiBase& mApi;
- LocationAPI* mClient;
- size_t mCount;
- uint32_t* mIds;
- GeofenceOption* mOptions;
- inline MsgModifyGeofences(GeofenceAdapter& adapter,
- LocApiBase& api,
- LocationAPI* client,
- size_t count,
- uint32_t* ids,
- GeofenceOption* options) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mClient(client),
- mCount(count),
- mIds(ids),
- mOptions(options) {}
- inline virtual void proc() const {
- LocationError* errs = new LocationError[mCount];
- if (nullptr == errs) {
- LOC_LOGE("%s]: new failed to allocate errs", __func__);
- return;
- }
- for (size_t i=0; i < mCount; ++i) {
- if (NULL == mIds || NULL == mOptions) {
- errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
- mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
- &mApi = mApi, mOptions = mOptions, errs, i] (LocationError err __unused) {
- uint32_t hwId = 0;
- errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
- if (LOCATION_ERROR_SUCCESS == errs[i]) {
- mApi.modifyGeofence(hwId, mIds[i], mOptions[i],
- new LocApiResponse(*mAdapter.getContext(),
- [&mAdapter = mAdapter, mCount = mCount, mClient = mClient,
- mIds = mIds, mOptions = mOptions, hwId, errs, i]
- (LocationError err ) {
- if (LOCATION_ERROR_SUCCESS == err) {
- errs[i] = err;
- mAdapter.modifyGeofenceItem(hwId, mOptions[i]);
- }
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- delete[] mOptions;
- }
- }));
- } else {
- // Send aggregated response on last item and cleanup
- if (i == mCount-1) {
- mAdapter.reportResponse(mClient, mCount, errs, mIds);
- delete[] errs;
- delete[] mIds;
- delete[] mOptions;
- }
- }
- }));
- }
- }
- }
- };
- if (0 == count) {
- return;
- }
- uint32_t* idsCopy = new uint32_t[count];
- if (nullptr == idsCopy) {
- LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
- return;
- }
- COPY_IF_NOT_NULL(idsCopy, ids, count);
- GeofenceOption* optionsCopy;
- if (options == NULL) {
- optionsCopy = NULL;
- } else {
- optionsCopy = new GeofenceOption[count];
- if (nullptr == optionsCopy) {
- LOC_LOGE("%s]: new failed to allocate optionsCopy", __func__);
- return;
- }
- COPY_IF_NOT_NULL(optionsCopy, options, count);
- }
- sendMsg(new MsgModifyGeofences(*this, *mLocApi, client, count, idsCopy, optionsCopy));
- }
- void
- GeofenceAdapter::saveGeofenceItem(LocationAPI* client, uint32_t clientId, uint32_t hwId,
- const GeofenceOption& options, const GeofenceInfo& info)
- {
- LOC_LOGD("%s]: hwId %u client %p clientId %u", __func__, hwId, client, clientId);
- GeofenceKey key(client, clientId);
- GeofenceObject object = {key,
- options.breachTypeMask,
- options.responsiveness,
- options.dwellTime,
- options.confidence,
- info.latitude,
- info.longitude,
- info.radius,
- false};
- mGeofences[hwId] = object;
- mGeofenceIds[key] = hwId;
- dump();
- }
- void
- GeofenceAdapter::removeGeofenceItem(uint32_t hwId)
- {
- GeofenceKey key;
- LocationError err = getGeofenceKeyFromHwId(hwId, key);
- if (LOCATION_ERROR_SUCCESS != err) {
- LOC_LOGE("%s]: can not find the key for hwId %u", __func__, hwId);
- } else {
- auto it1 = mGeofenceIds.find(key);
- if (it1 != mGeofenceIds.end()) {
- mGeofenceIds.erase(it1);
- auto it2 = mGeofences.find(hwId);
- if (it2 != mGeofences.end()) {
- mGeofences.erase(it2);
- dump();
- } else {
- LOC_LOGE("%s]:geofence item to erase not found. hwId %u", __func__, hwId);
- }
- } else {
- LOC_LOGE("%s]: geofence item to erase not found. hwId %u", __func__, hwId);
- }
- }
- }
- void
- GeofenceAdapter::pauseGeofenceItem(uint32_t hwId)
- {
- auto it = mGeofences.find(hwId);
- if (it != mGeofences.end()) {
- it->second.paused = true;
- dump();
- } else {
- LOC_LOGE("%s]: geofence item to pause not found. hwId %u", __func__, hwId);
- }
- }
- void
- GeofenceAdapter::resumeGeofenceItem(uint32_t hwId)
- {
- auto it = mGeofences.find(hwId);
- if (it != mGeofences.end()) {
- it->second.paused = false;
- dump();
- } else {
- LOC_LOGE("%s]: geofence item to resume not found. hwId %u", __func__, hwId);
- }
- }
- void
- GeofenceAdapter::modifyGeofenceItem(uint32_t hwId, const GeofenceOption& options)
- {
- auto it = mGeofences.find(hwId);
- if (it != mGeofences.end()) {
- it->second.breachMask = options.breachTypeMask;
- it->second.responsiveness = options.responsiveness;
- it->second.dwellTime = options.dwellTime;
- it->second.confidence = options.confidence;
- dump();
- } else {
- LOC_LOGE("%s]: geofence item to modify not found. hwId %u", __func__, hwId);
- }
- }
- void
- GeofenceAdapter::geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
- GeofenceBreachType breachType, uint64_t timestamp)
- {
- IF_LOC_LOGD {
- std::string idsString = "[";
- if (NULL != hwIds) {
- for (size_t i=0; i < count; ++i) {
- idsString += std::to_string(hwIds[i]) + " ";
- }
- }
- idsString += "]";
- LOC_LOGD("%s]: breachType %u count %zu ids %s",
- __func__, breachType, count, idsString.c_str());
- }
- if (0 == count || NULL == hwIds)
- return;
- struct MsgGeofenceBreach : public LocMsg {
- GeofenceAdapter& mAdapter;
- size_t mCount;
- uint32_t* mHwIds;
- Location mLocation;
- GeofenceBreachType mBreachType;
- uint64_t mTimestamp;
- inline MsgGeofenceBreach(GeofenceAdapter& adapter,
- size_t count,
- uint32_t* hwIds,
- Location& location,
- GeofenceBreachType breachType,
- uint64_t timestamp) :
- LocMsg(),
- mAdapter(adapter),
- mCount(count),
- mHwIds(new uint32_t[count]),
- mLocation(location),
- mBreachType(breachType),
- mTimestamp(timestamp)
- {
- if (nullptr == mHwIds) {
- LOC_LOGE("%s]: new failed to allocate mHwIds", __func__);
- return;
- }
- COPY_IF_NOT_NULL(mHwIds, hwIds, mCount);
- }
- inline virtual ~MsgGeofenceBreach() {
- delete[] mHwIds;
- }
- inline virtual void proc() const {
- mAdapter.geofenceBreach(mCount, mHwIds, mLocation, mBreachType, mTimestamp);
- }
- };
- sendMsg(new MsgGeofenceBreach(*this, count, hwIds, location, breachType, timestamp));
- }
- void
- GeofenceAdapter::geofenceBreach(size_t count, uint32_t* hwIds, const Location& location,
- GeofenceBreachType breachType, uint64_t timestamp)
- {
- for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
- uint32_t* clientIds = new uint32_t[count];
- if (nullptr == clientIds) {
- return;
- }
- uint32_t index = 0;
- for (size_t i=0; i < count; ++i) {
- GeofenceKey key;
- LocationError err = getGeofenceKeyFromHwId(hwIds[i], key);
- if (LOCATION_ERROR_SUCCESS == err) {
- if (key.client == it->first) {
- clientIds[index++] = key.id;
- }
- }
- }
- if (index > 0 && it->second.geofenceBreachCb != nullptr) {
- GeofenceBreachNotification notify = {sizeof(GeofenceBreachNotification),
- index,
- clientIds,
- location,
- breachType,
- timestamp};
- it->second.geofenceBreachCb(notify);
- }
- delete[] clientIds;
- }
- }
- void
- GeofenceAdapter::geofenceStatusEvent(GeofenceStatusAvailable available)
- {
- LOC_LOGD("%s]: available %u ", __func__, available);
- struct MsgGeofenceStatus : public LocMsg {
- GeofenceAdapter& mAdapter;
- GeofenceStatusAvailable mAvailable;
- inline MsgGeofenceStatus(GeofenceAdapter& adapter,
- GeofenceStatusAvailable available) :
- LocMsg(),
- mAdapter(adapter),
- mAvailable(available) {}
- inline virtual void proc() const {
- mAdapter.geofenceStatus(mAvailable);
- }
- };
- sendMsg(new MsgGeofenceStatus(*this, available));
- }
- void
- GeofenceAdapter::geofenceStatus(GeofenceStatusAvailable available)
- {
- for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
- if (it->second.geofenceStatusCb != nullptr) {
- GeofenceStatusNotification notify = {sizeof(GeofenceStatusNotification),
- available,
- LOCATION_TECHNOLOGY_TYPE_GNSS};
- it->second.geofenceStatusCb(notify);
- }
- }
- }
- void
- GeofenceAdapter::updateSystemPowerStateCommand(PowerStateType powerState)
- {
- LOC_LOGD("%s]: powerState: %d", __func__, powerState);
- struct MsgUpdateSystemPowerState : public LocMsg {
- GeofenceAdapter& mAdapter;
- PowerStateType mPowerState;
- inline MsgUpdateSystemPowerState(GeofenceAdapter& adapter,
- PowerStateType powerState) :
- mAdapter(adapter),
- mPowerState(powerState) {}
- inline virtual void proc() const {
- mAdapter.updateSystemPowerState(mPowerState);
- }
- };
- sendMsg(new MsgUpdateSystemPowerState(*this, powerState));
- }
- void
- GeofenceAdapter::pauseOrResumeGeofences(bool pauseOrResume /*false - pause, true - resume*/)
- {
- for (auto it = mGeofenceIds.begin(); it != mGeofenceIds.end(); ++it) {
- uint32_t hwId = it->second;
- if (false == pauseOrResume) {
- mLocApi->pauseGeofence(it->second, it->first.id, new LocApiResponse(*getContext(),
- [&mAdapter = *this, hwId = hwId] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.pauseGeofenceItem(hwId);
- }
- }));
- } else {
- mLocApi->resumeGeofence(it->second, it->first.id, new LocApiResponse(*getContext(),
- [&mAdapter = *this, hwId = hwId] (LocationError err) {
- if (LOCATION_ERROR_SUCCESS == err) {
- mAdapter.resumeGeofenceItem(hwId);
- }
- }));
- }
- }
- }
- void
- GeofenceAdapter::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:
- pauseOrResumeGeofences(false /*pause*/);
- LOC_LOGd("Pause all geoFences -- powerState: %d", systemPowerState);
- break;
- case POWER_STATE_RESUME:
- pauseOrResumeGeofences(true /*resume*/);
- LOC_LOGd("Resume all geoFences -- powerState: %d", systemPowerState);
- break;
- default:
- break;
- } // switch
- }
- }
- void
- GeofenceAdapter::dump()
- {
- IF_LOC_LOGV {
- LOC_LOGV(
- "HAL | hwId | mask | respon | latitude | longitude | radius | paused | Id | client");
- for (auto it = mGeofences.begin(); it != mGeofences.end(); ++it) {
- uint32_t hwId = it->first;
- GeofenceObject object = it->second;
- LOC_LOGV(" | %5u | %4u | %6u | %8.2f | %9.2f | %6.2f | %6u | %04x | %p ",
- hwId, object.breachMask, object.responsiveness,
- object.latitude, object.longitude, object.radius,
- object.paused, object.key.id, object.key.client);
- }
- }
- }
|