Location API for Outdoor Trip Batching

Add / Modify Location API for
Outdoor Trip Batching feature.
Introduce a batch mode to differentiate
between routine and outdoor trip mode.

CRs-Fixed: 2041674

Change-Id: Ia8b2d34457b29c4fe754ab24287a6984ab9a96f5
This commit is contained in:
Bhavna Sharma 2017-05-02 14:29:46 -07:00
parent 2df685d3ec
commit 686a5c54b0
9 changed files with 145 additions and 36 deletions

View file

@ -36,6 +36,9 @@
#include "LocationUtil.h"
#include "BatchingAPIClient.h"
#include "limits.h"
namespace android {
namespace hardware {
namespace gnss {
@ -48,7 +51,7 @@ static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions
BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
LocationAPIClientBase(),
mGnssBatchingCbIface(callback),
mDefaultId(42),
mDefaultId(UINT_MAX),
mLocationCapabilitiesMask(0)
{
LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
@ -60,8 +63,9 @@ BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback)
locationCallbacks.trackingCb = nullptr;
locationCallbacks.batchingCb = nullptr;
if (mGnssBatchingCbIface != nullptr) {
locationCallbacks.batchingCb = [this](size_t count, Location* location) {
onBatchingCb(count, location);
locationCallbacks.batchingCb = [this](size_t count, Location* location,
BatchingOptions batchOptions) {
onBatchingCb(count, location, batchOptions);
};
}
locationCallbacks.geofenceBreachCb = nullptr;
@ -134,13 +138,13 @@ int BatchingAPIClient::stopSession()
void BatchingAPIClient::getBatchedLocation(int last_n_locations)
{
LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
locAPIGetBatchedLocations(last_n_locations);
locAPIGetBatchedLocations(mDefaultId, last_n_locations);
}
void BatchingAPIClient::flushBatchedLocations()
{
LOC_LOGD("%s]: ()", __FUNCTION__);
locAPIGetBatchedLocations(SIZE_MAX);
locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
}
void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
@ -149,7 +153,7 @@ void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMa
mLocationCapabilitiesMask = capabilitiesMask;
}
void BatchingAPIClient::onBatchingCb(size_t count, Location* location)
void BatchingAPIClient::onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions)
{
LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
if (mGnssBatchingCbIface != nullptr && count > 0) {

View file

@ -58,7 +58,7 @@ public:
// callbacks
void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
void onBatchingCb(size_t count, Location* location) final;
void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
private:
sp<IGnssBatchingCallback> mGnssBatchingCbIface;

View file

@ -1111,6 +1111,10 @@ GnssAdapter::requestCapabilitiesCommand(LocationAPI* client)
if (mApi.isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
}
if (mApi.isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
}
// geofence always supported
mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
if (mApi.gnssConstellationConfig()) {

View file

@ -370,13 +370,13 @@ LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions
}
uint32_t
LocationAPI::startBatching(LocationOptions& locationOptions)
LocationAPI::startBatching(LocationOptions& locationOptions, BatchingOptions &batchingOptions)
{
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
if (gData.flpInterface != NULL) {
id = gData.flpInterface->startBatching(this, locationOptions);
id = gData.flpInterface->startBatching(this, locationOptions, batchingOptions);
} else {
LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
__func__, __LINE__, this);
@ -402,14 +402,16 @@ LocationAPI::stopBatching(uint32_t id)
}
void
LocationAPI::updateBatchingOptions(uint32_t id, LocationOptions& locationOptions)
LocationAPI::updateBatchingOptions(uint32_t id,
LocationOptions& locationOptions, BatchingOptions& batchOptions)
{
pthread_mutex_lock(&gDataMutex);
if (gData.flpInterface != NULL) {
gData.flpInterface->updateBatchingOptions(this,
id,
locationOptions);
locationOptions,
batchOptions);
} else {
LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
__func__, __LINE__, this);

View file

@ -32,6 +32,7 @@
#include <vector>
#include <stdint.h>
#include <functional>
#include <list>
#define GNSS_NI_REQUESTOR_MAX 256
#define GNSS_NI_MESSAGE_ID_MAX 2048
@ -140,6 +141,8 @@ typedef enum {
LOCATION_CAPABILITIES_GNSS_MSA_BIT = (1<<7),
// supports debug nmea sentences in the debugNmeaCallback
LOCATION_CAPABILITIES_DEBUG_NMEA_BIT = (1<<8),
// support outdoor trip batching
LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT = (1<<9)
} LocationCapabilitiesBits;
typedef enum {
@ -298,6 +301,17 @@ typedef enum {
GNSS_SUPL_MODE_MSA,
} GnssSuplMode;
typedef enum {
BATCHING_MODE_ROUTINE = 0,
BATCHING_MODE_TRIP
} BatchingMode;
typedef enum {
BATCHING_STATUS_TRIP_COMPLETED = 0,
BATCHING_STATUS_POSITION_AVAILABE,
BATCHING_STATUS_POSITION_UNAVAILABLE
} BatchingStatus;
typedef uint16_t GnssMeasurementsAdrStateMask;
typedef enum {
GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_UNKNOWN = 0,
@ -439,6 +453,16 @@ typedef struct {
GnssSuplMode mode; // Standalone/MS-Based/MS-Assisted
} LocationOptions;
typedef struct {
size_t size;
BatchingMode batchingMode;
} BatchingOptions;
typedef struct {
size_t size;
BatchingStatus batchingStatus;
} BatchingStatusInfo;
typedef struct {
size_t size; // set to sizeof(GeofenceOption)
GeofenceBreachTypeMask breachTypeMask; // bitwise OR of GeofenceBreachTypeBits
@ -657,9 +681,15 @@ typedef std::function<void(
broadcasted to all clients, no matter if a session has started by client */
typedef std::function<void(
size_t count, // number of locations in array
Location* location // array of locations
Location* location, // array of locations
BatchingOptions batchingOptions // Batching options
)> batchingCallback;
typedef std::function<void(
BatchingStatusInfo batchingStatus, // batch status
std::list<uint32_t> & listOfCompletedTrips
)> batchingStatusCallback;
/* Gives GNSS Location information, optional can be NULL
gnssLocationInfoCallback is called only during a tracking session
broadcasted to all clients, no matter if a session has started by client */
@ -721,6 +751,7 @@ typedef struct {
gnssSvCallback gnssSvCb; // optional
gnssNmeaCallback gnssNmeaCb; // optional
gnssMeasurementsCallback gnssMeasurementsCb; // optional
batchingStatusCallback batchingStatusCb; // optional
} LocationCallbacks;
class LocationAPI
@ -788,7 +819,7 @@ public:
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance
LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid
LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */
uint32_t startBatching(LocationOptions&); // returns session id
uint32_t startBatching(LocationOptions&, BatchingOptions&); // returns session id
/* stopBatching stops a batching session associated with id parameter.
responseCallback returns:
@ -801,7 +832,7 @@ public:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
void updateBatchingOptions(uint32_t id, LocationOptions&);
void updateBatchingOptions(uint32_t id, LocationOptions&, BatchingOptions&);
/* getBatchedLocations gets a number of locations that are currently stored/batched
on the low power processor, delivered by the batchingCallback passed in createInstance.

View file

@ -221,6 +221,7 @@ LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t sessi
// LocationAPIClientBase
LocationAPIClientBase::LocationAPIClientBase() :
mGeofenceBreachCallback(nullptr),
mBatchingStatusCallback(nullptr),
mLocationAPI(nullptr),
mBatchSize(-1)
{
@ -260,6 +261,14 @@ void LocationAPIClientBase::locAPISetCallbacks(LocationCallbacks& locationCallba
onCollectiveResponseCb(count, errors, ids);
};
if (locationCallbacks.batchingStatusCb != nullptr) {
mBatchingStatusCallback = locationCallbacks.batchingStatusCb;
locationCallbacks.batchingStatusCb =
[this](BatchingStatusInfo batchStatus, std::list<uint32_t> & tripCompletedList) {
beforeBatchingStatusCb(batchStatus, tripCompletedList);
};
}
if (mLocationAPI == nullptr ) {
mLocationAPI = LocationAPI::createInstance(locationCallbacks);
} else {
@ -360,7 +369,7 @@ int32_t LocationAPIClientBase::locAPIGetBatchSize()
uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t sessionMode,
LocationOptions& options)
LocationOptions& locationOptions)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
pthread_mutex_lock(&mMutex);
@ -374,18 +383,29 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session
uint32_t batchingSession = 0;
if (sessionMode == SESSION_MODE_ON_FIX) {
trackingSession = mLocationAPI->startTracking(options);
trackingSession = mLocationAPI->startTracking(locationOptions);
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
} else if (sessionMode == SESSION_MODE_ON_FULL) {
batchingSession = mLocationAPI->startBatching(options);
} else if ((sessionMode == SESSION_MODE_ON_FULL) ||
(sessionMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
// Fill in the batch mode
BatchingOptions batchOptions = {};
batchOptions.size = sizeof(BatchingOptions);
batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
if (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
batchOptions.batchingMode = BATCHING_MODE_TRIP;
}
batchingSession = mLocationAPI->startBatching(locationOptions, batchOptions);
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this));
}
uint32_t session =
(sessionMode == SESSION_MODE_ON_FULL) ? batchingSession : trackingSession;
uint32_t session = ((sessionMode == SESSION_MODE_ON_FULL ||
(sessionMode == SESSION_MODE_ON_TRIP_COMPLETED)) ?
batchingSession : trackingSession);
SessionEntity entity;
entity.id = id;
entity.trackingSession = trackingSession;
@ -418,7 +438,8 @@ uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
if (sMode == SESSION_MODE_ON_FIX) {
mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this));
mLocationAPI->stopTracking(trackingSession);
} else if (sMode == SESSION_MODE_ON_FULL) {
} else if ((sMode == SESSION_MODE_ON_FULL) ||
(sMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this));
mLocationAPI->stopBatching(batchingSession);
} else {
@ -456,7 +477,8 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t
mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this));
if (sMode == SESSION_MODE_ON_FIX) {
mLocationAPI->updateTrackingOptions(trackingSession, options);
} else if (sMode == SESSION_MODE_ON_FULL) {
} else if ((sMode == SESSION_MODE_ON_FULL) ||
(sMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
// stop batching
// batchingSession will be removed from mSessionBiDict soon,
// so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
@ -471,10 +493,18 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t
} else {
LOC_LOGE("%s:%d] unknown mode %d", __FUNCTION__, __LINE__, sMode);
}
} else if (sessionMode == SESSION_MODE_ON_FULL) {
} else if ((sessionMode == SESSION_MODE_ON_FULL) ||
(sessionMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
// we only add an UpdateBatchingOptionsRequest to mRequestQueues[REQUEST_SESSION],
// even if this update request will stop tracking and then start batching.
mRequestQueues[REQUEST_SESSION].push(new UpdateBatchingOptionsRequest(*this));
BatchingOptions batchOptions = {};
batchOptions.size = sizeof(BatchingOptions);
batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
if (sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
batchOptions.batchingMode = BATCHING_MODE_TRIP;
}
if (sMode == SESSION_MODE_ON_FIX) {
// stop tracking
// trackingSession will be removed from mSessionBiDict soon,
@ -483,12 +513,13 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t
trackingSession = 0;
// start batching
batchingSession = mLocationAPI->startBatching(options);
batchingSession = mLocationAPI->startBatching(options, batchOptions);
LOC_LOGI("%s:%d] start new session: %d",
__FUNCTION__, __LINE__, batchingSession);
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
} else if (sMode == SESSION_MODE_ON_FULL) {
mLocationAPI->updateBatchingOptions(batchingSession, options);
} else if ((sMode == SESSION_MODE_ON_FULL) ||
(sMode == SESSION_MODE_ON_TRIP_COMPLETED)) {
mLocationAPI->updateBatchingOptions(batchingSession, options, batchOptions);
} else {
LOC_LOGE("%s:%d] unknown mode %d", __FUNCTION__, __LINE__, sMode);
}
@ -497,8 +528,10 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t
LOC_LOGE("%s:%d] unknown mode %d.", __FUNCTION__, __LINE__, sessionMode);
}
uint32_t session =
(sessionMode == SESSION_MODE_ON_FULL) ? batchingSession : trackingSession;
uint32_t session = ((sessionMode == SESSION_MODE_ON_FULL) ||
(sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) ?
batchingSession : trackingSession);
entity.trackingSession = trackingSession;
entity.batchingSession = batchingSession;
entity.sessionMode = sessionMode;
@ -511,22 +544,23 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t
retVal = LOCATION_ERROR_ID_UNKNOWN;
LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
}
}
pthread_mutex_unlock(&mMutex);
return retVal;
}
void LocationAPIClientBase::locAPIGetBatchedLocations(size_t count)
void LocationAPIClientBase::locAPIGetBatchedLocations(uint32_t id, size_t count)
{
pthread_mutex_lock(&mMutex);
if (mLocationAPI) {
uint32_t session = 0;
session = mRequestQueues[REQUEST_SESSION].getSession();
if (session > 0) {
SessionEntity entity = mSessionBiDict.getExtById(id);
uint32_t batchingSession = entity.batchingSession;
mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this));
mLocationAPI->getBatchedLocations(session, count);
} else {
mLocationAPI->getBatchedLocations(batchingSession, count);
} else {
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
}
}
@ -794,6 +828,29 @@ void LocationAPIClientBase::beforeGeofenceBreachCb(
free(ids);
}
void LocationAPIClientBase::beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
std::list<uint32_t> & tripCompletedList) {
// map the trip ids to the client ids
std::list<uint32_t> tripCompletedClientIdList;
tripCompletedClientIdList.clear();
if (batchStatus.batchingStatus == BATCHING_STATUS_TRIP_COMPLETED) {
for (auto itt = tripCompletedList.begin(); itt != tripCompletedList.end(); itt++) {
if (mSessionBiDict.hasSession(*itt)) {
SessionEntity sessEntity = mSessionBiDict.getExtBySession(*itt);
if (sessEntity.sessionMode == SESSION_MODE_ON_TRIP_COMPLETED) {
tripCompletedClientIdList.push_back(sessEntity.id);
mSessionBiDict.rmBySession(*itt);
}
}
}
}
mBatchingStatusCallback(batchStatus, tripCompletedClientIdList);
}
void LocationAPIClientBase::onResponseCb(LocationError error, uint32_t id)
{
if (error != LOCATION_ERROR_SUCCESS) {

View file

@ -41,6 +41,7 @@ enum SESSION_MODE {
SESSION_MODE_NONE = 0,
SESSION_MODE_ON_FULL,
SESSION_MODE_ON_FIX,
SESSION_MODE_ON_TRIP_COMPLETED
};
enum REQUEST_TYPE {
@ -194,7 +195,7 @@ public:
uint32_t locAPIStopSession(uint32_t id);
uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
LocationOptions& options);
void locAPIGetBatchedLocations(size_t count);
void locAPIGetBatchedLocations(uint32_t id, size_t count);
uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
GeofenceOption* options, GeofenceInfo* data);
@ -226,7 +227,12 @@ public:
inline virtual void onGnssLocationInfoCb(
GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}
inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/) {}
inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/,
BatchingOptions /*batchingOptions*/) {}
inline virtual void onBatchingStatusCb(BatchingStatusInfo /*batchingStatus*/,
std::list<uint32_t> &/*listOfCompletedTrips*/) {}
void beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
std::list<uint32_t> & tripCompletedList);
inline virtual void onStartBatchingCb(LocationError /*error*/) {}
inline virtual void onStopBatchingCb(LocationError /*error*/) {}
inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {}
@ -525,6 +531,7 @@ private:
pthread_mutex_t mMutex;
geofenceBreachCallback mGeofenceBreachCallback;
batchingStatusCallback mBatchingStatusCallback;
LocationAPI* mLocationAPI;

View file

@ -67,9 +67,10 @@ struct FlpInterface {
uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options);
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options);
void (*stopTracking)(LocationAPI* client, uint32_t id);
uint32_t (*startBatching)(LocationAPI* client, LocationOptions&);
uint32_t (*startBatching)(LocationAPI* client, LocationOptions&, BatchingOptions&);
void (*stopBatching)(LocationAPI* client, uint32_t id);
void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, LocationOptions&);
void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, LocationOptions&,
BatchingOptions&);
void (*getBatchedLocations)(LocationAPI* client, uint32_t id, size_t count);
void (*getPowerStateChanges)(void* powerStateCb);
};

View file

@ -559,6 +559,7 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT, // Geofence dwell report
LOC_API_ADAPTER_REQUEST_SRN_DATA, // request srn data from AP
LOC_API_ADAPTER_REQUEST_POSITION_INJECTION, // Position injection request
LOC_API_ADAPTER_BATCH_STATUS, // batch status
LOC_API_ADAPTER_EVENT_MAX
};
@ -593,6 +594,7 @@ enum loc_api_adapter_event_index {
#define LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL (1<<LOC_API_ADAPTER_REPORT_GENFENCE_DWELL_REPORT)
#define LOC_API_ADAPTER_BIT_REQUEST_SRN_DATA (1<<LOC_API_ADAPTER_REQUEST_SRN_DATA)
#define LOC_API_ADAPTER_BIT_POSITION_INJECTION_REQUEST (1<<LOC_API_ADAPTER_REQUEST_POSITION_INJECTION)
#define LOC_API_ADAPTER_BIT_BATCH_STATUS (1<<LOC_API_ADAPTER_BATCH_STATUS)
typedef unsigned int LOC_API_ADAPTER_EVENT_MASK_T;
@ -604,6 +606,7 @@ typedef enum loc_api_adapter_msg_to_check_supported {
LOC_API_ADAPTER_MESSAGE_ADAPTIVE_LOCATION_BATCHING, // Batching 1.5
LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING, // Batching 2.0
LOC_API_ADAPTER_MESSAGE_UPDATE_TBF_ON_THE_FLY, // Updating Tracking TBF On The Fly
LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING, // Outdoor Trip Batching
LOC_API_ADAPTER_MESSAGE_MAX
} LocCheckingMessagesID;