From baa3641d5f8e64288f45432d6e4989701dbbcc0f Mon Sep 17 00:00:00 2001 From: Raghuram Subramani Date: Thu, 17 Oct 2024 09:31:12 +0530 Subject: msm8996-common: Import newer GPS stack from xiaomi_msm8996-common Change-Id: I5afe78048c4af3648b2d267d71a58b63b9decbc9 --- gps/location/LocationAPI.cpp | 326 +++++++++++++++++++++++++++---------------- 1 file changed, 203 insertions(+), 123 deletions(-) (limited to 'gps/location/LocationAPI.cpp') diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp index 0111a9c..4348c27 100644 --- a/gps/location/LocationAPI.cpp +++ b/gps/location/LocationAPI.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019 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 @@ -25,6 +25,7 @@ * 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 @@ -33,42 +34,64 @@ #include #include #include +#include + +typedef const GnssInterface* (getGnssInterface)(); +typedef const GeofenceInterface* (getGeofenceInterface)(); +typedef const BatchingInterface* (getBatchingInterface)(); + +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 void* (getLocationInterface)(); typedef std::map LocationClientMap; typedef struct { LocationClientMap clientData; + LocationClientDestroyCbMap destroyClientData; LocationControlAPI* controlAPI; LocationControlCallbacks controlCallbacks; GnssInterface* gnssInterface; GeofenceInterface* geofenceInterface; - FlpInterface* flpInterface; + BatchingInterface* batchingInterface; } LocationAPIData; + static LocationAPIData gData = {}; static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER; static bool gGnssLoadFailed = false; -static bool gFlpLoadFailed = false; +static bool gBatchingLoadFailed = false; static bool gGeofenceLoadFailed = false; -static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks) -{ - return (locationCallbacks.gnssLocationInfoCb != nullptr || - locationCallbacks.gnssSvCb != nullptr || - locationCallbacks.gnssNmeaCb != nullptr || - locationCallbacks.gnssMeasurementsCb != nullptr); +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 bool isGnssClient(LocationCallbacks& locationCallbacks) { return (locationCallbacks.gnssNiCb != nullptr || locationCallbacks.trackingCb != nullptr || + locationCallbacks.gnssLocationInfoCb != nullptr || + locationCallbacks.engineLocationsInfoCb != nullptr || locationCallbacks.gnssMeasurementsCb != nullptr); } -static bool isFlpClient(LocationCallbacks& locationCallbacks) +static bool isBatchingClient(LocationCallbacks& locationCallbacks) { - return (locationCallbacks.trackingCb != nullptr || - locationCallbacks.batchingCb != nullptr); + return (locationCallbacks.batchingCb != nullptr); } static bool isGeofenceClient(LocationCallbacks& locationCallbacks) @@ -77,32 +100,48 @@ static bool isGeofenceClient(LocationCallbacks& locationCallbacks) locationCallbacks.geofenceStatusCb != nullptr); } -static void* loadLocationInterface(const char* library, const char* name) { - LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name); - if (NULL == library || NULL == name) { - return NULL; - } - getLocationInterface* getter = NULL; - const char *error = NULL; - dlerror(); - void *handle = dlopen(library, RTLD_NOW); - if (NULL == handle || (error = dlerror()) != NULL) { - LOC_LOGW("dlopen for %s failed, error = %s", library, error); - } else { - getter = (getLocationInterface*)dlsym(handle, name); - if ((error = dlerror()) != NULL) { - LOC_LOGW("dlsym for %s::%s failed, error = %s", library, name, error); - getter = NULL; + +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 (NULL == getter) { - return (void*)getter; - } else { - return (*getter)(); + if ((true == invokeCallback) && (nullptr != destroyCompleteCb)) { + LOC_LOGd("invoke client destroy cb"); + (destroyCompleteCb) (); + LOC_LOGd("finish invoke client destroy cb"); + + 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) { @@ -120,7 +159,8 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks) if (isGnssClient(locationCallbacks)) { if (NULL == gData.gnssInterface && !gGnssLoadFailed) { gData.gnssInterface = - (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); + (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); if (NULL == gData.gnssInterface) { gGnssLoadFailed = true; LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__); @@ -137,21 +177,22 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks) } } - if (isFlpClient(locationCallbacks)) { - if (NULL == gData.flpInterface && !gFlpLoadFailed) { - gData.flpInterface = - (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface"); - if (NULL == gData.flpInterface) { - gFlpLoadFailed = true; - LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__); + 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.flpInterface->initialize(); + gData.batchingInterface->initialize(); } } - if (NULL != gData.flpInterface) { - gData.flpInterface->addClient(newLocationAPI, locationCallbacks); + if (NULL != gData.batchingInterface) { + gData.batchingInterface->addClient(newLocationAPI, locationCallbacks); if (!requestedCapabilities) { - gData.flpInterface->requestCapabilities(newLocationAPI); + gData.batchingInterface->requestCapabilities(newLocationAPI); requestedCapabilities = true; } } @@ -160,7 +201,8 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks) if (isGeofenceClient(locationCallbacks)) { if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) { gData.geofenceInterface = - (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface"); + (GeofenceInterface*)loadLocationInterface("libgeofencing.so", "getGeofenceInterface"); if (NULL == gData.geofenceInterface) { gGeofenceLoadFailed = true; LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__); @@ -185,39 +227,79 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks) } void -LocationAPI::destroy() +LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb) { - delete this; -} + bool invokeDestroyCb = false; -LocationAPI::LocationAPI() -{ - LOC_LOGD("LOCATION API CONSTRUCTOR"); -} - -LocationAPI::~LocationAPI() -{ - LOC_LOGD("LOCATION API DESTRUCTOR"); pthread_mutex_lock(&gDataMutex); - auto it = gData.clientData.find(this); if (it != gData.clientData.end()) { - if (isGnssClient(it->second) && NULL != gData.gnssInterface) { - gData.gnssInterface->removeClient(it->first); + bool removeFromGnssInf = + (isGnssClient(it->second) && NULL != gData.gnssInterface); + bool removeFromBatchingInf = + (isBatchingClient(it->second) && NULL != gData.batchingInterface); + bool removeFromGeofenceInf = + (isGeofenceClient(it->second) && NULL != gData.geofenceInterface); + bool needToWait = (removeFromGnssInf || removeFromBatchingInf || removeFromGeofenceInf); + LOC_LOGe("removeFromGnssInf: %d, removeFromBatchingInf: %d, removeFromGeofenceInf: %d," + "need %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_LOGe("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask); } - if (isFlpClient(it->second) && NULL != gData.flpInterface) { - gData.flpInterface->removeClient(it->first); + + if (removeFromGnssInf) { + gData.gnssInterface->removeClient(it->first, + onGnssRemoveClientCompleteCb); } - if (isGeofenceClient(it->second) && NULL != gData.geofenceInterface) { - gData.geofenceInterface->removeClient(it->first); + if (removeFromBatchingInf) { + gData.batchingInterface->removeClient(it->first, + onBatchingRemoveClientCompleteCb); } + if (removeFromGeofenceInf) { + gData.geofenceInterface->removeClient(it->first, + onGeofenceRemoveClientCompleteCb); + } + gData.clientData.erase(it); + + if ((NULL != destroyCompleteCb) && (false == needToWait)) { + invokeDestroyCb = true; + } } else { LOC_LOGE("%s:%d]: Location API client %p not found in client data", __func__, __LINE__, this); } pthread_mutex_unlock(&gDataMutex); + if (invokeDestroyCb == true) { + (destroyCompleteCb) (); + delete this; + } +} + +LocationAPI::LocationAPI() +{ + LOC_LOGD("LOCATION API CONSTRUCTOR"); +} + +// private destructor +LocationAPI::~LocationAPI() +{ + LOC_LOGD("LOCATION API DESTRUCTOR"); } void @@ -234,7 +316,8 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks) if (isGnssClient(locationCallbacks)) { if (NULL == gData.gnssInterface && !gGnssLoadFailed) { gData.gnssInterface = - (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); + (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); if (NULL == gData.gnssInterface) { gGnssLoadFailed = true; LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__); @@ -248,27 +331,29 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks) } } - if (isFlpClient(locationCallbacks)) { - if (NULL == gData.flpInterface && !gFlpLoadFailed) { - gData.flpInterface = - (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface"); - if (NULL == gData.flpInterface) { - gFlpLoadFailed = true; - LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__); + 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.flpInterface->initialize(); + gData.batchingInterface->initialize(); } } - if (NULL != gData.flpInterface) { + if (NULL != gData.batchingInterface) { // either adds new Client or updates existing Client - gData.flpInterface->addClient(this, locationCallbacks); + gData.batchingInterface->addClient(this, locationCallbacks); } } if (isGeofenceClient(locationCallbacks)) { if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) { gData.geofenceInterface = - (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface"); + (GeofenceInterface*)loadLocationInterface("libgeofencing.so", "getGeofenceInterface"); if (NULL == gData.geofenceInterface) { gGeofenceLoadFailed = true; LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__); @@ -288,23 +373,17 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks) } uint32_t -LocationAPI::startTracking(LocationOptions& locationOptions) +LocationAPI::startTracking(TrackingOptions& trackingOptions) { uint32_t id = 0; pthread_mutex_lock(&gDataMutex); auto it = gData.clientData.find(this); if (it != gData.clientData.end()) { - if (gData.flpInterface != NULL && locationOptions.minDistance > 0) { - id = gData.flpInterface->startTracking(this, locationOptions); - } else if (gData.gnssInterface != NULL && needsGnssTrackingInfo(it->second)) { - id = gData.gnssInterface->startTracking(this, locationOptions); - } else if (gData.flpInterface != NULL) { - id = gData.flpInterface->startTracking(this, locationOptions); - } else if (gData.gnssInterface != NULL) { - id = gData.gnssInterface->startTracking(this, locationOptions); + if (NULL != gData.gnssInterface) { + id = gData.gnssInterface->startTracking(this, trackingOptions); } else { - LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ", + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", __func__, __LINE__, this); } } else { @@ -323,16 +402,10 @@ LocationAPI::stopTracking(uint32_t id) auto it = gData.clientData.find(this); if (it != gData.clientData.end()) { - // we don't know if tracking was started on flp or gnss, so we call stop on both, where - // stopTracking call to the incorrect interface will fail without response back to client if (gData.gnssInterface != NULL) { gData.gnssInterface->stopTracking(this, id); - } - if (gData.flpInterface != NULL) { - gData.flpInterface->stopTracking(this, id); - } - if (gData.flpInterface == NULL && gData.gnssInterface == NULL) { - LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ", + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", __func__, __LINE__, this); } } else { @@ -344,22 +417,17 @@ LocationAPI::stopTracking(uint32_t id) } void -LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions) +LocationAPI::updateTrackingOptions( + uint32_t id, TrackingOptions& trackingOptions) { pthread_mutex_lock(&gDataMutex); auto it = gData.clientData.find(this); if (it != gData.clientData.end()) { - // we don't know if tracking was started on flp or gnss, so we call update on both, where - // updateTracking call to the incorrect interface will fail without response back to client if (gData.gnssInterface != NULL) { - gData.gnssInterface->updateTrackingOptions(this, id, locationOptions); - } - if (gData.flpInterface != NULL) { - gData.flpInterface->updateTrackingOptions(this, id, locationOptions); - } - if (gData.flpInterface == NULL && gData.gnssInterface == NULL) { - LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ", + gData.gnssInterface->updateTrackingOptions(this, id, trackingOptions); + } else { + LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ", __func__, __LINE__, this); } } else { @@ -371,15 +439,15 @@ LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions } uint32_t -LocationAPI::startBatching(LocationOptions& locationOptions, BatchingOptions &batchingOptions) +LocationAPI::startBatching(BatchingOptions &batchingOptions) { uint32_t id = 0; pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { - id = gData.flpInterface->startBatching(this, locationOptions, batchingOptions); + if (NULL != gData.batchingInterface) { + id = gData.batchingInterface->startBatching(this, batchingOptions); } else { - LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", __func__, __LINE__, this); } @@ -392,10 +460,10 @@ LocationAPI::stopBatching(uint32_t id) { pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { - gData.flpInterface->stopBatching(this, id); + if (NULL != gData.batchingInterface) { + gData.batchingInterface->stopBatching(this, id); } else { - LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", __func__, __LINE__, this); } @@ -403,18 +471,14 @@ LocationAPI::stopBatching(uint32_t id) } void -LocationAPI::updateBatchingOptions(uint32_t id, - LocationOptions& locationOptions, BatchingOptions& batchOptions) +LocationAPI::updateBatchingOptions(uint32_t id, BatchingOptions& batchOptions) { pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { - gData.flpInterface->updateBatchingOptions(this, - id, - locationOptions, - batchOptions); + if (NULL != gData.batchingInterface) { + gData.batchingInterface->updateBatchingOptions(this, id, batchOptions); } else { - LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", __func__, __LINE__, this); } @@ -426,10 +490,10 @@ LocationAPI::getBatchedLocations(uint32_t id, size_t count) { pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { - gData.flpInterface->getBatchedLocations(this, id, count); + if (gData.batchingInterface != NULL) { + gData.batchingInterface->getBatchedLocations(this, id, count); } else { - LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", + LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ", __func__, __LINE__, this); } @@ -537,7 +601,8 @@ LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCall if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) { if (NULL == gData.gnssInterface && !gGnssLoadFailed) { gData.gnssInterface = - (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); + (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface"); if (NULL == gData.gnssInterface) { gGnssLoadFailed = true; LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__); @@ -627,6 +692,21 @@ LocationControlAPI::gnssUpdateConfig(GnssConfig config) 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) { -- cgit v1.2.3