Merge "GPS location API: support destroy with callback for completion"
This commit is contained in:
commit
372ec44be0
7 changed files with 159 additions and 40 deletions
|
@ -1859,25 +1859,32 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GnssAdapter::removeClientCommand(LocationAPI* client)
|
GnssAdapter::removeClientCommand(LocationAPI* client,
|
||||||
|
removeClientCompleteCallback rmClientCb)
|
||||||
{
|
{
|
||||||
LOC_LOGD("%s]: client %p", __func__, client);
|
LOC_LOGD("%s]: client %p", __func__, client);
|
||||||
|
|
||||||
struct MsgRemoveClient : public LocMsg {
|
struct MsgRemoveClient : public LocMsg {
|
||||||
GnssAdapter& mAdapter;
|
GnssAdapter& mAdapter;
|
||||||
LocationAPI* mClient;
|
LocationAPI* mClient;
|
||||||
|
removeClientCompleteCallback mRmClientCb;
|
||||||
inline MsgRemoveClient(GnssAdapter& adapter,
|
inline MsgRemoveClient(GnssAdapter& adapter,
|
||||||
LocationAPI* client) :
|
LocationAPI* client,
|
||||||
|
removeClientCompleteCallback rmCb) :
|
||||||
LocMsg(),
|
LocMsg(),
|
||||||
mAdapter(adapter),
|
mAdapter(adapter),
|
||||||
mClient(client) {}
|
mClient(client),
|
||||||
|
mRmClientCb(rmCb){}
|
||||||
inline virtual void proc() const {
|
inline virtual void proc() const {
|
||||||
mAdapter.stopClientSessions(mClient);
|
mAdapter.stopClientSessions(mClient);
|
||||||
mAdapter.eraseClient(mClient);
|
mAdapter.eraseClient(mClient);
|
||||||
|
if (nullptr != mRmClientCb) {
|
||||||
|
mRmClientCb(mClient);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMsg(new MsgRemoveClient(*this, client));
|
sendMsg(new MsgRemoveClient(*this, client, rmClientCb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -128,6 +128,8 @@ typedef std::function<void(
|
||||||
uint64_t gnssEnergyConsumedFromFirstBoot
|
uint64_t gnssEnergyConsumedFromFirstBoot
|
||||||
)> GnssEnergyConsumedCallback;
|
)> GnssEnergyConsumedCallback;
|
||||||
|
|
||||||
|
typedef void (*removeClientCompleteCallback)(LocationAPI* client);
|
||||||
|
|
||||||
class GnssAdapter : public LocAdapterBase {
|
class GnssAdapter : public LocAdapterBase {
|
||||||
|
|
||||||
/* ==== Engine Hub ===================================================================== */
|
/* ==== Engine Hub ===================================================================== */
|
||||||
|
@ -206,7 +208,8 @@ public:
|
||||||
/* ==== CLIENT ========================================================================= */
|
/* ==== CLIENT ========================================================================= */
|
||||||
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
|
||||||
void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
|
void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
void removeClientCommand(LocationAPI* client);
|
void removeClientCommand(LocationAPI* client,
|
||||||
|
removeClientCompleteCallback rmClientCb);
|
||||||
void requestCapabilitiesCommand(LocationAPI* client);
|
void requestCapabilitiesCommand(LocationAPI* client);
|
||||||
/* ======== UTILITIES ================================================================== */
|
/* ======== UTILITIES ================================================================== */
|
||||||
void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
|
|
|
@ -36,7 +36,7 @@ static void initialize();
|
||||||
static void deinitialize();
|
static void deinitialize();
|
||||||
|
|
||||||
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
static void removeClient(LocationAPI* client);
|
static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||||
static void requestCapabilities(LocationAPI* client);
|
static void requestCapabilities(LocationAPI* client);
|
||||||
|
|
||||||
static uint32_t startTracking(LocationAPI* client, TrackingOptions&);
|
static uint32_t startTracking(LocationAPI* client, TrackingOptions&);
|
||||||
|
@ -140,10 +140,10 @@ static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeClient(LocationAPI* client)
|
static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
|
||||||
{
|
{
|
||||||
if (NULL != gGnssAdapter) {
|
if (NULL != gGnssAdapter) {
|
||||||
gGnssAdapter->removeClientCommand(client);
|
gGnssAdapter->removeClientCommand(client, rmClientCb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,15 +36,37 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
typedef void* (getLocationInterface)();
|
typedef void* (getLocationInterface)();
|
||||||
|
|
||||||
|
typedef uint16_t LocationAdapterTypeMask;
|
||||||
|
typedef enum {
|
||||||
|
LOCATION_ADAPTER_GNSS_TYPE_BIT = (1<<0), // adapter type is GNSS
|
||||||
|
LOCATION_ADAPTER_FLP_TYPE_BIT = (1<<1), // adapter type is FLP
|
||||||
|
LOCATION_ADAPTER_GEOFENCE_TYPE_BIT = (1<<2) // adapter type is geo fence
|
||||||
|
} LocationAdapterTypeBits;
|
||||||
|
|
||||||
|
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<LocationAPI*, LocationAPIDestroyCbData>
|
||||||
|
LocationClientDestroyCbMap;
|
||||||
|
|
||||||
typedef std::map<LocationAPI*, LocationCallbacks> LocationClientMap;
|
typedef std::map<LocationAPI*, LocationCallbacks> LocationClientMap;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
LocationClientMap clientData;
|
LocationClientMap clientData;
|
||||||
|
LocationClientDestroyCbMap destroyClientData;
|
||||||
LocationControlAPI* controlAPI;
|
LocationControlAPI* controlAPI;
|
||||||
LocationControlCallbacks controlCallbacks;
|
LocationControlCallbacks controlCallbacks;
|
||||||
GnssInterface* gnssInterface;
|
GnssInterface* gnssInterface;
|
||||||
GeofenceInterface* geofenceInterface;
|
GeofenceInterface* geofenceInterface;
|
||||||
FlpInterface* flpInterface;
|
FlpInterface* flpInterface;
|
||||||
} LocationAPIData;
|
} LocationAPIData;
|
||||||
|
|
||||||
static LocationAPIData gData = {};
|
static LocationAPIData gData = {};
|
||||||
static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static bool gGnssLoadFailed = false;
|
static bool gGnssLoadFailed = false;
|
||||||
|
@ -80,7 +102,8 @@ static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
|
||||||
locationCallbacks.geofenceStatusCb != nullptr);
|
locationCallbacks.geofenceStatusCb != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* loadLocationInterface(const char* library, const char* name) {
|
static void* loadLocationInterface(const char* library, const char* name)
|
||||||
|
{
|
||||||
LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name);
|
LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name);
|
||||||
if (NULL == library || NULL == name) {
|
if (NULL == library || NULL == name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -106,6 +129,46 @@ static void* loadLocationInterface(const char* library, const char* name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onRemoveClientCompleteCb (
|
||||||
|
LocationAPI* client, LocationAdapterTypeMask adapterType)
|
||||||
|
{
|
||||||
|
bool invokeCallback = false;
|
||||||
|
locationApiDestroyCompleteCallback destroyCompleteCb;
|
||||||
|
LOC_LOGd("adatper type %x", adapterType);
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
auto it = gData.destroyClientData.find(client);
|
||||||
|
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 ((true == invokeCallback) && (nullptr != destroyCompleteCb)) {
|
||||||
|
LOC_LOGd("invoke client destroy cb");
|
||||||
|
(destroyCompleteCb) ();
|
||||||
|
LOC_LOGd("finish invoke client destroy cb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onGnssRemoveClientCompleteCb (LocationAPI* client)
|
||||||
|
{
|
||||||
|
onRemoveClientCompleteCb (client, LOCATION_ADAPTER_GNSS_TYPE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onFlpRemoveClientCompleteCb (LocationAPI* client)
|
||||||
|
{
|
||||||
|
onRemoveClientCompleteCb (client, LOCATION_ADAPTER_FLP_TYPE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onGeofenceRemoveClientCompleteCb (LocationAPI* client)
|
||||||
|
{
|
||||||
|
onRemoveClientCompleteCb (client, LOCATION_ADAPTER_GEOFENCE_TYPE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
LocationAPI*
|
LocationAPI*
|
||||||
LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
|
LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
|
||||||
{
|
{
|
||||||
|
@ -188,9 +251,66 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LocationAPI::destroy()
|
LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
|
||||||
{
|
{
|
||||||
delete this;
|
bool invokeDestroyCb = false;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&gDataMutex);
|
||||||
|
auto it = gData.clientData.find(this);
|
||||||
|
if (it != gData.clientData.end()) {
|
||||||
|
bool removeFromGnssInf =
|
||||||
|
(isGnssClient(it->second) && NULL != gData.gnssInterface);
|
||||||
|
bool removeFromFlpInf =
|
||||||
|
(isFlpClient(it->second) && NULL != gData.flpInterface);
|
||||||
|
bool removeFromGeofenceInf =
|
||||||
|
(isGeofenceClient(it->second) && NULL != gData.geofenceInterface);
|
||||||
|
bool needToWait = (removeFromGnssInf || removeFromFlpInf || removeFromGeofenceInf);
|
||||||
|
LOC_LOGe("removeFromGnssInf: %d, removeFromFlpInf: %d, removeFromGeofenceInf: %d, need %d",
|
||||||
|
removeFromGnssInf, removeFromFlpInf, 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 |=
|
||||||
|
(removeFromFlpInf ? LOCATION_ADAPTER_FLP_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 (removeFromGnssInf) {
|
||||||
|
gData.gnssInterface->removeClient(it->first,
|
||||||
|
onGnssRemoveClientCompleteCb);
|
||||||
|
}
|
||||||
|
if (removeFromFlpInf) {
|
||||||
|
gData.flpInterface->removeClient(it->first,
|
||||||
|
onFlpRemoveClientCompleteCb);
|
||||||
|
}
|
||||||
|
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) ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocationAPI::LocationAPI()
|
LocationAPI::LocationAPI()
|
||||||
|
@ -198,29 +318,9 @@ LocationAPI::LocationAPI()
|
||||||
LOC_LOGD("LOCATION API CONSTRUCTOR");
|
LOC_LOGD("LOCATION API CONSTRUCTOR");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private destructor
|
||||||
LocationAPI::~LocationAPI()
|
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);
|
|
||||||
}
|
|
||||||
if (isFlpClient(it->second) && NULL != gData.flpInterface) {
|
|
||||||
gData.flpInterface->removeClient(it->first);
|
|
||||||
}
|
|
||||||
if (isGeofenceClient(it->second) && NULL != gData.geofenceInterface) {
|
|
||||||
gData.geofenceInterface->removeClient(it->first);
|
|
||||||
}
|
|
||||||
gData.clientData.erase(it);
|
|
||||||
} else {
|
|
||||||
LOC_LOGE("%s:%d]: Location API client %p not found in client data",
|
|
||||||
__func__, __LINE__, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&gDataMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -43,10 +43,14 @@ public:
|
||||||
of instances have been reached */
|
of instances have been reached */
|
||||||
static LocationAPI* createInstance(LocationCallbacks&);
|
static LocationAPI* createInstance(LocationCallbacks&);
|
||||||
|
|
||||||
/* destroy/cleans up the instance, which should be called when LocationAPI object is
|
/* destroy/cleans up the instance, which should be called when LocationControlAPI object is
|
||||||
no longer needed. LocationAPI* returned from createInstance will no longer valid
|
no longer needed. LocationControlAPI* returned from createInstance will no longer valid
|
||||||
after destroy is called */
|
after destroy is called.
|
||||||
void destroy();
|
If the caller allocates the memory for LocationControlCallbacks used in
|
||||||
|
LocationControlAPI::createInstance, then the caller must ensure that the memory still remains
|
||||||
|
valid until destroyCompleteCb is invoked.
|
||||||
|
*/
|
||||||
|
void destroy(locationApiDestroyCompleteCallback destroyCompleteCb=nullptr);
|
||||||
|
|
||||||
/* updates/changes the callbacks that will be called.
|
/* updates/changes the callbacks that will be called.
|
||||||
mandatory callbacks must be present for callbacks to be successfully updated
|
mandatory callbacks must be present for callbacks to be successfully updated
|
||||||
|
|
|
@ -1274,6 +1274,9 @@ typedef std::function<void(
|
||||||
LocationSystemInfo locationSystemInfo
|
LocationSystemInfo locationSystemInfo
|
||||||
)> locationSystemInfoCallback;
|
)> locationSystemInfoCallback;
|
||||||
|
|
||||||
|
typedef std::function<void(
|
||||||
|
)> locationApiDestroyCompleteCallback;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t size; // set to sizeof(LocationCallbacks)
|
size_t size; // set to sizeof(LocationCallbacks)
|
||||||
capabilitiesCallback capabilitiesCb; // mandatory
|
capabilitiesCallback capabilitiesCb; // mandatory
|
||||||
|
|
|
@ -46,12 +46,14 @@ typedef std::function<void(
|
||||||
uint64_t gnssEnergyConsumedFromFirstBoot
|
uint64_t gnssEnergyConsumedFromFirstBoot
|
||||||
)> GnssEnergyConsumedCallback;
|
)> GnssEnergyConsumedCallback;
|
||||||
|
|
||||||
|
typedef void (*removeClientCompleteCallback)(LocationAPI* client);
|
||||||
|
|
||||||
struct GnssInterface {
|
struct GnssInterface {
|
||||||
size_t size;
|
size_t size;
|
||||||
void (*initialize)(void);
|
void (*initialize)(void);
|
||||||
void (*deinitialize)(void);
|
void (*deinitialize)(void);
|
||||||
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
void (*removeClient)(LocationAPI* client);
|
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||||
void (*requestCapabilities)(LocationAPI* client);
|
void (*requestCapabilities)(LocationAPI* client);
|
||||||
uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
|
uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
|
||||||
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
|
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
|
||||||
|
@ -87,7 +89,7 @@ struct FlpInterface {
|
||||||
void (*initialize)(void);
|
void (*initialize)(void);
|
||||||
void (*deinitialize)(void);
|
void (*deinitialize)(void);
|
||||||
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
void (*removeClient)(LocationAPI* client);
|
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||||
void (*requestCapabilities)(LocationAPI* client);
|
void (*requestCapabilities)(LocationAPI* client);
|
||||||
uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
|
uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
|
||||||
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
|
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
|
||||||
|
@ -104,7 +106,7 @@ struct GeofenceInterface {
|
||||||
void (*initialize)(void);
|
void (*initialize)(void);
|
||||||
void (*deinitialize)(void);
|
void (*deinitialize)(void);
|
||||||
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||||
void (*removeClient)(LocationAPI* client);
|
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||||
void (*requestCapabilities)(LocationAPI* client);
|
void (*requestCapabilities)(LocationAPI* client);
|
||||||
uint32_t* (*addGeofences)(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
|
uint32_t* (*addGeofences)(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
|
||||||
void (*removeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
void (*removeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||||
|
|
Loading…
Reference in a new issue