From 44d5c9e2cf9f1ce0670be5bedd1e415cd5c3e739 Mon Sep 17 00:00:00 2001 From: kleidione Freitas Date: Thu, 24 Mar 2022 09:16:43 -0300 Subject: veux: Merge common tree to veux - Ref: https://github.com/xiaomi-sm6375-devs/android_device_xiaomi_sm6375-common Signed-off-by: kleidione --- gps/location/LocationAPI.cpp | 976 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 976 insertions(+) create mode 100644 gps/location/LocationAPI.cpp (limited to 'gps/location/LocationAPI.cpp') diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp new file mode 100644 index 0000000..3a50c46 --- /dev/null +++ b/gps/location/LocationAPI.cpp @@ -0,0 +1,976 @@ +/* Copyright (c) 2017-2020 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_LocationAPI" + +#include +#include +#include +#include +#include +#include +#include + +typedef const GnssInterface* (getGnssInterface)(); +typedef const GeofenceInterface* (getGeofenceInterface)(); +typedef const BatchingInterface* (getBatchingInterface)(); +typedef void (createOSFramework)(); +typedef void (destroyOSFramework)(); + +// GTP services +typedef uint32_t (setOptInStatusGetter)(bool userConsent, responseCallback* callback); +typedef void (enableProviderGetter)(); +typedef void (disableProviderGetter)(); +typedef void (getSingleNetworkLocationGetter)(trackingCallback* callback); +typedef void (stopNetworkLocationGetter)(trackingCallback* callback); + +typedef struct { + // bit mask of the adpaters that we need to wait for the removeClientCompleteCallback + // before we invoke the registered locationApiDestroyCompleteCallback + LocationAdapterTypeMask waitAdapterMask; + locationApiDestroyCompleteCallback destroyCompleteCb; +} LocationAPIDestroyCbData; + +// This is the map for the client that has requested destroy with +// destroy callback provided. +typedef std::map + LocationClientDestroyCbMap; + +typedef std::map LocationClientMap; +typedef struct { + LocationClientMap clientData; + LocationClientDestroyCbMap destroyClientData; + LocationControlAPI* controlAPI; + LocationControlCallbacks controlCallbacks; + GnssInterface* gnssInterface; + GeofenceInterface* geofenceInterface; + BatchingInterface* batchingInterface; +} LocationAPIData; + +static LocationAPIData gData = {}; +static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER; +static bool gGnssLoadFailed = false; +static bool gBatchingLoadFailed = false; +static bool gGeofenceLoadFailed = false; +static uint32_t gOSFrameworkRefCount = 0; + +template +static const T1* loadLocationInterface(const char* library, const char* name) { + void* libhandle = nullptr; + T2* getter = (T2*)dlGetSymFromLib(libhandle, library, name); + if (nullptr == getter) { + return (const T1*) getter; + }else { + return (*getter)(); + } +} + +static void createOSFrameworkInstance() { + void* libHandle = nullptr; + createOSFramework* getter = (createOSFramework*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "createOSFramework"); + if (getter != nullptr) { + (*getter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +static void destroyOSFrameworkInstance() { + void* libHandle = nullptr; + destroyOSFramework* getter = (destroyOSFramework*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "destroyOSFramework"); + if (getter != nullptr) { + (*getter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks) +{ + return (locationCallbacks.gnssLocationInfoCb != nullptr || + locationCallbacks.engineLocationsInfoCb != nullptr || + locationCallbacks.gnssSvCb != nullptr || + locationCallbacks.gnssNmeaCb != nullptr || + locationCallbacks.gnssDataCb != nullptr || + locationCallbacks.gnssMeasurementsCb != nullptr); +} + +static bool isGnssClient(LocationCallbacks& locationCallbacks) +{ + return (locationCallbacks.gnssNiCb != nullptr || + locationCallbacks.trackingCb != nullptr || + locationCallbacks.gnssLocationInfoCb != nullptr || + locationCallbacks.engineLocationsInfoCb != nullptr || + locationCallbacks.gnssSvCb != nullptr || + locationCallbacks.gnssNmeaCb != nullptr || + locationCallbacks.gnssDataCb != nullptr || + locationCallbacks.gnssMeasurementsCb != nullptr || + locationCallbacks.locationSystemInfoCb != nullptr); +} + +static bool isBatchingClient(LocationCallbacks& locationCallbacks) +{ + return (locationCallbacks.batchingCb != nullptr); +} + +static bool isGeofenceClient(LocationCallbacks& locationCallbacks) +{ + return (locationCallbacks.geofenceBreachCb != nullptr || + locationCallbacks.geofenceStatusCb != nullptr); +} + + +void LocationAPI::onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType) +{ + bool invokeCallback = false; + locationApiDestroyCompleteCallback destroyCompleteCb; + LOC_LOGd("adatper type %x", adapterType); + pthread_mutex_lock(&gDataMutex); + auto it = gData.destroyClientData.find(this); + if (it != gData.destroyClientData.end()) { + it->second.waitAdapterMask &= ~adapterType; + if (it->second.waitAdapterMask == 0) { + invokeCallback = true; + destroyCompleteCb = it->second.destroyCompleteCb; + gData.destroyClientData.erase(it); + } + } + pthread_mutex_unlock(&gDataMutex); + + if (invokeCallback) { + LOC_LOGd("invoke client destroy cb"); + if (!destroyCompleteCb) { + (destroyCompleteCb) (); + } + + delete this; + } +} + +void onGnssRemoveClientCompleteCb (LocationAPI* client) +{ + client->onRemoveClientCompleteCb (LOCATION_ADAPTER_GNSS_TYPE_BIT); +} + +void onBatchingRemoveClientCompleteCb (LocationAPI* client) +{ + client->onRemoveClientCompleteCb (LOCATION_ADAPTER_BATCHING_TYPE_BIT); +} + +void onGeofenceRemoveClientCompleteCb (LocationAPI* client) +{ + client->onRemoveClientCompleteCb (LOCATION_ADAPTER_GEOFENCE_TYPE_BIT); +} + +LocationAPI* +LocationAPI::createInstance (LocationCallbacks& locationCallbacks) +{ + if (nullptr == locationCallbacks.capabilitiesCb || + nullptr == locationCallbacks.responseCb || + nullptr == locationCallbacks.collectiveResponseCb) { + LOC_LOGe("missing mandatory callback, return null"); + return NULL; + } + + LocationAPI* newLocationAPI = new LocationAPI(); + bool requestedCapabilities = false; + + pthread_mutex_lock(&gDataMutex); + + gOSFrameworkRefCount++; + if (1 == gOSFrameworkRefCount) { + createOSFrameworkInstance(); + } + + if (isGnssClient(locationCallbacks)) { + if (NULL == gData.gnssInterface && !gGnssLoadFailed) { + gData.gnssInterface = + (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); + if (NULL == gData.gnssInterface) { + gGnssLoadFailed = true; + LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__); + } else { + gData.gnssInterface->initialize(); + } + } + if (NULL != gData.gnssInterface) { + gData.gnssInterface->addClient(newLocationAPI, locationCallbacks); + if (!requestedCapabilities) { + gData.gnssInterface->requestCapabilities(newLocationAPI); + requestedCapabilities = true; + } + } + } + + if (isBatchingClient(locationCallbacks)) { + if (NULL == gData.batchingInterface && !gBatchingLoadFailed) { + gData.batchingInterface = + (BatchingInterface*)loadLocationInterface("libbatching.so", "getBatchingInterface"); + if (NULL == gData.batchingInterface) { + gBatchingLoadFailed = true; + LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__); + } else { + gData.batchingInterface->initialize(); + } + } + if (NULL != gData.batchingInterface) { + gData.batchingInterface->addClient(newLocationAPI, locationCallbacks); + if (!requestedCapabilities) { + gData.batchingInterface->requestCapabilities(newLocationAPI); + requestedCapabilities = true; + } + } + } + + if (isGeofenceClient(locationCallbacks)) { + if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) { + gData.geofenceInterface = + (GeofenceInterface*)loadLocationInterface("libgeofencing.so", "getGeofenceInterface"); + if (NULL == gData.geofenceInterface) { + gGeofenceLoadFailed = true; + LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__); + } else { + gData.geofenceInterface->initialize(); + } + } + if (NULL != gData.geofenceInterface) { + gData.geofenceInterface->addClient(newLocationAPI, locationCallbacks); + if (!requestedCapabilities) { + gData.geofenceInterface->requestCapabilities(newLocationAPI); + requestedCapabilities = true; + } + } + } + + gData.clientData[newLocationAPI] = locationCallbacks; + + pthread_mutex_unlock(&gDataMutex); + + return newLocationAPI; +} + +void +LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb) +{ + bool invokeDestroyCb = false; + + pthread_mutex_lock(&gDataMutex); + auto it = gData.clientData.find(this); + if (it != gData.clientData.end()) { + bool removeFromGnssInf = (NULL != gData.gnssInterface); + bool removeFromBatchingInf = (NULL != gData.batchingInterface); + bool removeFromGeofenceInf = (NULL != gData.geofenceInterface); + bool needToWait = (removeFromGnssInf || removeFromBatchingInf || removeFromGeofenceInf); + LOC_LOGe("removeFromGnssInf: %d, removeFromBatchingInf: %d, removeFromGeofenceInf: %d," + "needToWait: %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf, + needToWait); + + if ((NULL != destroyCompleteCb) && (true == needToWait)) { + LocationAPIDestroyCbData destroyCbData = {}; + destroyCbData.destroyCompleteCb = destroyCompleteCb; + // record down from which adapter we need to wait for the destroy complete callback + // only when we have received all the needed callbacks from all the associated stacks, + // we shall notify the client. + destroyCbData.waitAdapterMask = + (removeFromGnssInf ? LOCATION_ADAPTER_GNSS_TYPE_BIT : 0); + destroyCbData.waitAdapterMask |= + (removeFromBatchingInf ? LOCATION_ADAPTER_BATCHING_TYPE_BIT : 0); + destroyCbData.waitAdapterMask |= + (removeFromGeofenceInf ? LOCATION_ADAPTER_GEOFENCE_TYPE_BIT : 0); + gData.destroyClientData[this] = destroyCbData; + LOC_LOGi("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask); + } + + if (removeFromGnssInf) { + gData.gnssInterface->removeClient(it->first, + onGnssRemoveClientCompleteCb); + } + if (removeFromBatchingInf) { + gData.batchingInterface->removeClient(it->first, + onBatchingRemoveClientCompleteCb); + } + if (removeFromGeofenceInf) { + gData.geofenceInterface->removeClient(it->first, + onGeofenceRemoveClientCompleteCb); + } + + gData.clientData.erase(it); + + if (!needToWait) { + invokeDestroyCb = true; + } + } else { + LOC_LOGE("%s:%d]: Location API client %p not found in client data", + __func__, __LINE__, this); + } + + if (1 == gOSFrameworkRefCount) { + destroyOSFrameworkInstance(); + } + gOSFrameworkRefCount--; + + pthread_mutex_unlock(&gDataMutex); + if (invokeDestroyCb) { + if (!destroyCompleteCb) { + (destroyCompleteCb) (); + } + delete this; + } +} + +LocationAPI::LocationAPI() +{ + LOC_LOGD("LOCATION API CONSTRUCTOR"); +} + +// private destructor +LocationAPI::~LocationAPI() +{ + LOC_LOGD("LOCATION API DESTRUCTOR"); +} + +void +LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks) +{ + if (nullptr == locationCallbacks.capabilitiesCb || + nullptr == locationCallbacks.responseCb || + nullptr == locationCallbacks.collectiveResponseCb) { + return; + } + + pthread_mutex_lock(&gDataMutex); + + if (isGnssClient(locationCallbacks)) { + if (NULL == gData.gnssInterface && !gGnssLoadFailed) { + gData.gnssInterface = + (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); + if (NULL == gData.gnssInterface) { + gGnssLoadFailed = true; + LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__); + } else { + gData.gnssInterface->initialize(); + } + } + if (NULL != gData.gnssInterface) { + // either adds new Client or updates existing Client + gData.gnssInterface->addClient(this, locationCallbacks); + } + } + + if (isBatchingClient(locationCallbacks)) { + if (NULL == gData.batchingInterface && !gBatchingLoadFailed) { + gData.batchingInterface = + (BatchingInterface*)loadLocationInterface("libbatching.so", "getBatchingInterface"); + if (NULL == gData.batchingInterface) { + gBatchingLoadFailed = true; + LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__); + } else { + gData.batchingInterface->initialize(); + } + } + if (NULL != gData.batchingInterface) { + // either adds new Client or updates existing Client + gData.batchingInterface->addClient(this, locationCallbacks); + } + } + + if (isGeofenceClient(locationCallbacks)) { + if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) { + gData.geofenceInterface = + (GeofenceInterface*)loadLocationInterface("libgeofencing.so", "getGeofenceInterface"); + if (NULL == gData.geofenceInterface) { + gGeofenceLoadFailed = true; + LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__); + } else { + gData.geofenceInterface->initialize(); + } + } + if (NULL != gData.geofenceInterface) { + // either adds new Client or updates existing Client + gData.geofenceInterface->addClient(this, locationCallbacks); + } + } + + gData.clientData[this] = locationCallbacks; + + pthread_mutex_unlock(&gDataMutex); +} + +uint32_t +LocationAPI::startTracking(TrackingOptions& trackingOptions) +{ + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + auto it = gData.clientData.find(this); + if (it != gData.clientData.end()) { + if (NULL != gData.gnssInterface) { + id = gData.gnssInterface->startTracking(this, trackingOptions); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", + __func__, __LINE__, this); + } + } else { + LOC_LOGE("%s:%d]: Location API client %p not found in client data", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +void +LocationAPI::stopTracking(uint32_t id) +{ + pthread_mutex_lock(&gDataMutex); + + auto it = gData.clientData.find(this); + if (it != gData.clientData.end()) { + if (gData.gnssInterface != NULL) { + gData.gnssInterface->stopTracking(this, id); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", + __func__, __LINE__, this); + } + } else { + LOC_LOGE("%s:%d]: Location API client %p not found in client data", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::updateTrackingOptions( + uint32_t id, TrackingOptions& trackingOptions) +{ + pthread_mutex_lock(&gDataMutex); + + auto it = gData.clientData.find(this); + if (it != gData.clientData.end()) { + if (gData.gnssInterface != NULL) { + gData.gnssInterface->updateTrackingOptions(this, id, trackingOptions); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", + __func__, __LINE__, this); + } + } else { + LOC_LOGE("%s:%d]: Location API client %p not found in client data", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +uint32_t +LocationAPI::startBatching(BatchingOptions &batchingOptions) +{ + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (NULL != gData.batchingInterface) { + id = gData.batchingInterface->startBatching(this, batchingOptions); + } else { + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +void +LocationAPI::stopBatching(uint32_t id) +{ + pthread_mutex_lock(&gDataMutex); + + if (NULL != gData.batchingInterface) { + gData.batchingInterface->stopBatching(this, id); + } else { + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::updateBatchingOptions(uint32_t id, BatchingOptions& batchOptions) +{ + pthread_mutex_lock(&gDataMutex); + + if (NULL != gData.batchingInterface) { + gData.batchingInterface->updateBatchingOptions(this, id, batchOptions); + } else { + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::getBatchedLocations(uint32_t id, size_t count) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.batchingInterface != NULL) { + gData.batchingInterface->getBatchedLocations(this, id, count); + } else { + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +uint32_t* +LocationAPI::addGeofences(size_t count, GeofenceOption* options, GeofenceInfo* info) +{ + uint32_t* ids = NULL; + pthread_mutex_lock(&gDataMutex); + + if (gData.geofenceInterface != NULL) { + ids = gData.geofenceInterface->addGeofences(this, count, options, info); + } else { + LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); + return ids; +} + +void +LocationAPI::removeGeofences(size_t count, uint32_t* ids) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.geofenceInterface != NULL) { + gData.geofenceInterface->removeGeofences(this, count, ids); + } else { + LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.geofenceInterface != NULL) { + gData.geofenceInterface->modifyGeofences(this, count, ids, options); + } else { + LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::pauseGeofences(size_t count, uint32_t* ids) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.geofenceInterface != NULL) { + gData.geofenceInterface->pauseGeofences(this, count, ids); + } else { + LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::resumeGeofences(size_t count, uint32_t* ids) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.geofenceInterface != NULL) { + gData.geofenceInterface->resumeGeofences(this, count, ids); + } else { + LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void +LocationAPI::gnssNiResponse(uint32_t id, GnssNiResponse response) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + gData.gnssInterface->gnssNiResponse(this, id, response); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +void LocationAPI::enableNetworkProvider() { + void* libHandle = nullptr; + enableProviderGetter* setter = (enableProviderGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "enableNetworkProvider"); + if (setter != nullptr) { + (*setter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +void LocationAPI::disableNetworkProvider() { + void* libHandle = nullptr; + disableProviderGetter* setter = (disableProviderGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "disableNetworkProvider"); + if (setter != nullptr) { + (*setter)(); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +void LocationAPI::startNetworkLocation(trackingCallback* callback) { + void* libHandle = nullptr; + getSingleNetworkLocationGetter* setter = + (getSingleNetworkLocationGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "startNetworkLocation"); + if (setter != nullptr) { + (*setter)(callback); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +void LocationAPI::stopNetworkLocation(trackingCallback* callback) { + void* libHandle = nullptr; + stopNetworkLocationGetter* setter = (stopNetworkLocationGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "stopNetworkLocation"); + if (setter != nullptr) { + LOC_LOGe("called"); + (*setter)(callback); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } +} + +LocationControlAPI* +LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks) +{ + LocationControlAPI* controlAPI = NULL; + pthread_mutex_lock(&gDataMutex); + + if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) { + if (NULL == gData.gnssInterface && !gGnssLoadFailed) { + gData.gnssInterface = + (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); + if (NULL == gData.gnssInterface) { + gGnssLoadFailed = true; + LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__); + } else { + gData.gnssInterface->initialize(); + } + } + if (NULL != gData.gnssInterface) { + gData.controlAPI = new LocationControlAPI(); + gData.controlCallbacks = locationControlCallbacks; + gData.gnssInterface->setControlCallbacks(locationControlCallbacks); + controlAPI = gData.controlAPI; + } + } + + pthread_mutex_unlock(&gDataMutex); + return controlAPI; +} + +void +LocationControlAPI::destroy() +{ + delete this; +} + +LocationControlAPI::LocationControlAPI() +{ + LOC_LOGD("LOCATION CONTROL API CONSTRUCTOR"); +} + +LocationControlAPI::~LocationControlAPI() +{ + LOC_LOGD("LOCATION CONTROL API DESTRUCTOR"); + pthread_mutex_lock(&gDataMutex); + + gData.controlAPI = NULL; + + pthread_mutex_unlock(&gDataMutex); +} + +uint32_t +LocationControlAPI::enable(LocationTechnologyType techType) +{ + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->enable(techType); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +void +LocationControlAPI::disable(uint32_t id) +{ + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + gData.gnssInterface->disable(id); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); +} + +uint32_t* +LocationControlAPI::gnssUpdateConfig(const GnssConfig& config) +{ + uint32_t* ids = NULL; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + ids = gData.gnssInterface->gnssUpdateConfig(config); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); + return ids; +} + +uint32_t* LocationControlAPI::gnssGetConfig(GnssConfigFlagsMask mask) { + + uint32_t* ids = NULL; + pthread_mutex_lock(&gDataMutex); + + if (NULL != gData.gnssInterface) { + ids = gData.gnssInterface->gnssGetConfig(mask); + } else { + LOC_LOGe("No gnss interface available for Control API client %p", this); + } + + pthread_mutex_unlock(&gDataMutex); + return ids; +} + +uint32_t +LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data) +{ + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->gnssDeleteAidingData(data); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ", + __func__, __LINE__, this); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configConstellations( + const GnssSvTypeConfig& constellationEnablementConfig, + const GnssSvIdConfig& blacklistSvConfig) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->gnssUpdateSvConfig( + constellationEnablementConfig, blacklistSvConfig); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configConstellationSecondaryBand( + const GnssSvTypeConfig& secondaryBandConfig) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->gnssUpdateSecondaryBandConfig(secondaryBandConfig); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configConstrainedTimeUncertainty( + bool enable, float tuncThreshold, uint32_t energyBudget) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->setConstrainedTunc(enable, + tuncThreshold, + energyBudget); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configPositionAssistedClockEstimator(bool enable) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->setPositionAssistedClockEstimator(enable); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configLeverArm(const LeverArmConfigInfo& configInfo) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configLeverArm(configInfo); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configRobustLocation(bool enable, bool enableForE911) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configRobustLocation(enable, enableForE911); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configMinGpsWeek(uint16_t minGpsWeek) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configMinGpsWeek(minGpsWeek); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configDeadReckoningEngineParams( + const DeadReckoningEngineConfig& dreConfig) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configDeadReckoningEngineParams(dreConfig); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::configEngineRunState( + PositioningEngineMask engType, LocEngineRunState engState) { + uint32_t id = 0; + pthread_mutex_lock(&gDataMutex); + + if (gData.gnssInterface != NULL) { + id = gData.gnssInterface->configEngineRunState(engType, engState); + } else { + LOC_LOGe("No gnss interface available for Location Control API"); + } + + pthread_mutex_unlock(&gDataMutex); + return id; +} + +uint32_t LocationControlAPI::setOptInStatus(bool userConsent) { + void* libHandle = nullptr; + uint32_t sessionId = 0; + setOptInStatusGetter* setter = (setOptInStatusGetter*)dlGetSymFromLib(libHandle, + "liblocationservice_glue.so", "setOptInStatus"); + if (setter != nullptr) { + sessionId = (*setter)(userConsent, &gData.controlCallbacks.responseCb); + } else { + LOC_LOGe("dlGetSymFromLib failed for liblocationservice_glue.so"); + } + return sessionId; +} -- cgit v1.2.3