sm8450-common: Import gps from LA.VENDOR.1.0.r1-12800-WAIPIO.0
Change-Id: Ia76265a8c3326f2b5f9f260ce98807276af80ee3
This commit is contained in:
36
gps/location/Android.bp
Normal file
36
gps/location/Android.bp
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
cc_library_shared {
|
||||
|
||||
name: "liblocation_api",
|
||||
vendor: true,
|
||||
|
||||
|
||||
|
||||
shared_libs: [
|
||||
"libutils",
|
||||
"libcutils",
|
||||
"libgps.utils",
|
||||
"libdl",
|
||||
"liblog",
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"LocationAPI.cpp",
|
||||
"LocationAPIClientBase.cpp",
|
||||
],
|
||||
|
||||
cflags: ["-fno-short-enums"] + GNSS_CFLAGS,
|
||||
|
||||
header_libs: [
|
||||
"libloc_pla_headers",
|
||||
"libgps.utils_headers",
|
||||
],
|
||||
|
||||
}
|
||||
|
||||
cc_library_headers {
|
||||
|
||||
name: "liblocation_api_headers",
|
||||
export_include_dirs: ["."],
|
||||
vendor: true,
|
||||
}
|
451
gps/location/ILocationAPI.h
Normal file
451
gps/location/ILocationAPI.h
Normal file
@@ -0,0 +1,451 @@
|
||||
/* Copyright (c) 2018-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.
|
||||
*/
|
||||
|
||||
#ifndef ILOCATIONAPI_H
|
||||
#define ILOCATIONAPI_H
|
||||
|
||||
#include "LocationDataTypes.h"
|
||||
|
||||
class ILocationAPI
|
||||
{
|
||||
public:
|
||||
virtual ~ILocationAPI(){};
|
||||
|
||||
/** @brief Updates/changes the callbacks that will be called.
|
||||
mandatory callbacks must be present for callbacks to be successfully updated
|
||||
no return value */
|
||||
virtual void updateCallbacks(LocationCallbacks&) = 0;
|
||||
|
||||
/* ================================== TRACKING ================================== */
|
||||
|
||||
/** @brief Starts a tracking session, which returns a session id that will be
|
||||
used by the other tracking APIs and also in the responseCallback to match command
|
||||
with response. locations are reported on the registered trackingCallback
|
||||
periodically according to LocationOptions.
|
||||
@return session id
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successfully started
|
||||
LOCATION_ERROR_ALREADY_STARTED if a startTracking session is already in progress
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no trackingCallback was passed
|
||||
LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameter is invalid */
|
||||
virtual uint32_t startTracking(TrackingOptions&) = 0;
|
||||
|
||||
/** @brief Stops a tracking session associated with id parameter.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
|
||||
virtual void stopTracking(uint32_t id) = 0;
|
||||
|
||||
/** @brief Changes the LocationOptions of a tracking session associated with id.
|
||||
responseCallback returns:
|
||||
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 tracking session */
|
||||
virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) = 0;
|
||||
|
||||
/* ================================== BATCHING ================================== */
|
||||
|
||||
/** @brief starts a batching session, which returns a session id that will be
|
||||
used by the other batching APIs and also in the responseCallback to match command
|
||||
with response. locations are reported on the batchingCallback passed in createInstance
|
||||
periodically according to LocationOptions. A batching session starts tracking on
|
||||
the low power processor and delivers them in batches by the batchingCallback when
|
||||
the batch is full or when getBatchedLocations is called. This allows for the processor
|
||||
that calls this API to sleep when the low power processor can batch locations in the
|
||||
backgroup and wake up the processor calling the API only when the batch is full, thus
|
||||
saving power.
|
||||
@return session id
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_ALREADY_STARTED if a startBatching session is already in progress
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback
|
||||
LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid
|
||||
LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */
|
||||
virtual uint32_t startBatching(BatchingOptions&) = 0;
|
||||
|
||||
/** @brief Stops a batching session associated with id parameter.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */
|
||||
virtual void stopBatching(uint32_t id) = 0;
|
||||
|
||||
/** @brief Changes the LocationOptions of a batching session associated with id.
|
||||
responseCallback returns:
|
||||
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 */
|
||||
virtual void updateBatchingOptions(uint32_t id, BatchingOptions&) = 0;
|
||||
|
||||
/** @brief Gets a number of locations that are currently stored/batched
|
||||
on the low power processor, delivered by the batchingCallback passed in createInstance.
|
||||
Location are then deleted from the batch stored on the low power processor.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful, will be followed by batchingCallback call
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
|
||||
virtual void getBatchedLocations(uint32_t id, size_t count) = 0;
|
||||
|
||||
/* ================================== GEOFENCE ================================== */
|
||||
|
||||
/** @brief Adds any number of geofences and returns an array of geofence ids that
|
||||
will be used by the other geofence APIs and also in the collectiveResponseCallback to
|
||||
match command with response. The geofenceBreachCallback will deliver the status of each
|
||||
geofence according to the GeofenceOption for each. The geofence id array returned will
|
||||
be valid until the collectiveResponseCallback is called and has returned.
|
||||
@return id array
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no geofenceBreachCallback
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
LOCATION_ERROR_NOT_SUPPORTED if geofence is not supported */
|
||||
virtual uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*) = 0;
|
||||
|
||||
/** @brief Removes any number of geofences. Caller should delete ids array after
|
||||
removeGeofences returneds.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||
virtual void removeGeofences(size_t count, uint32_t* ids) = 0;
|
||||
|
||||
/** @brief Modifies any number of geofences. Caller should delete ids array after
|
||||
modifyGeofences returns.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */
|
||||
virtual void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options) = 0;
|
||||
|
||||
/** @brief Pauses any number of geofences, which is similar to removeGeofences,
|
||||
only that they can be resumed at any time. Caller should delete ids array after
|
||||
pauseGeofences returns.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||
virtual void pauseGeofences(size_t count, uint32_t* ids) = 0;
|
||||
|
||||
/** @brief Resumes any number of geofences that are currently paused. Caller should
|
||||
delete ids array after resumeGeofences returns.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||
virtual void resumeGeofences(size_t count, uint32_t* ids) = 0;
|
||||
|
||||
/* ================================== GNSS ====================================== */
|
||||
|
||||
/** @brief gnssNiResponse is called in response to a gnssNiCallback.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
|
||||
LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
|
||||
virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) = 0;
|
||||
};
|
||||
|
||||
class ILocationControlAPI
|
||||
{
|
||||
public:
|
||||
virtual ~ILocationControlAPI(){};
|
||||
|
||||
/** @brief Updates the gnss specific configuration, which returns a session id array
|
||||
with an id for each of the bits set in GnssConfig.flags, order from low bits to high bits.
|
||||
The response for each config that is set will be returned in collectiveResponseCallback.
|
||||
The session id array returned will be valid until the collectiveResponseCallback is called
|
||||
and has returned. This effect is global for all clients of ILocationAPI.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
|
||||
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
|
||||
virtual uint32_t* gnssUpdateConfig(const GnssConfig& config) = 0;
|
||||
|
||||
/** @brief Delete specific gnss aiding data for testing, which returns a session id
|
||||
that will be returned in responseCallback to match command with response.
|
||||
Only allowed in userdebug builds. This effect is global for all clients of ILocationAPI.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
LOCATION_ERROR_NOT_SUPPORTED if build is not userdebug */
|
||||
virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) = 0;
|
||||
|
||||
/** @brief
|
||||
Configure the constellation and SVs to be used by the GNSS engine on
|
||||
modem.
|
||||
|
||||
@param
|
||||
constellationEnablementConfig: configuration to enable/disable SV
|
||||
constellation to be used by SPE engine. When size in
|
||||
constellationEnablementConfig is set to 0, this indicates to reset SV
|
||||
constellation configuration to modem NV default.
|
||||
|
||||
blacklistSvConfig: configuration to blacklist or unblacklist SVs
|
||||
used by SPE engine
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configConstellations(
|
||||
const GnssSvTypeConfig& constellationEnablementConfig,
|
||||
const GnssSvIdConfig& blacklistSvConfig) = 0;
|
||||
|
||||
/** @brief
|
||||
Configure the secondary band of constellations to be used by
|
||||
the GNSS engine on modem.
|
||||
|
||||
@param
|
||||
secondaryBandConfig: configuration the secondary band usage
|
||||
for SPE engine
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configConstellationSecondaryBand(
|
||||
const GnssSvTypeConfig& secondaryBandConfig) = 0;
|
||||
|
||||
/** @brief
|
||||
Enable or disable the constrained time uncertainty feature.
|
||||
|
||||
@param
|
||||
enable: true to enable the constrained time uncertainty
|
||||
feature and false to disable the constrainted time
|
||||
uncertainty feature.
|
||||
|
||||
@param
|
||||
tuncThreshold: this specifies the time uncertainty threshold
|
||||
that gps engine need to maintain, in units of milli-seconds.
|
||||
Default is 0.0 meaning that modem default value of time
|
||||
uncertainty threshold will be used. This parameter is
|
||||
ignored when requesting to disable this feature.
|
||||
|
||||
@param
|
||||
energyBudget: this specifies the power budget that gps
|
||||
engine is allowed to spend to maintain the time uncertainty.
|
||||
Default is 0 meaning that GPS engine is not constained by
|
||||
power budget and can spend as much power as needed. The
|
||||
parameter need to be specified in units of 0.1 milli watt
|
||||
second. This parameter is ignored requesting to disable this
|
||||
feature.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters
|
||||
are invalid
|
||||
*/
|
||||
virtual uint32_t configConstrainedTimeUncertainty(
|
||||
bool enable, float tuncThreshold = 0.0,
|
||||
uint32_t energyBudget = 0) = 0;
|
||||
|
||||
/** @brief
|
||||
Enable or disable position assisted clock estimator feature.
|
||||
|
||||
@param
|
||||
enable: true to enable position assisted clock estimator and
|
||||
false to disable the position assisted clock estimator
|
||||
feature.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configPositionAssistedClockEstimator(bool enable) = 0;
|
||||
|
||||
/** @brief
|
||||
Sets the lever arm parameters for the vehicle.
|
||||
|
||||
@param
|
||||
configInfo: lever arm configuration info regarding below two
|
||||
types of lever arm info:
|
||||
a: GNSS Antenna w.r.t the origin at the IMU e.g.: inertial
|
||||
measurement unit.
|
||||
b: lever arm parameters regarding the OPF (output frame)
|
||||
w.r.t the origin (at the GPS Antenna). Vehicle manufacturers
|
||||
prefer the position output to be tied to a specific point in
|
||||
the vehicle rather than where the antenna is placed
|
||||
(midpoint of the rear axle is typical).
|
||||
|
||||
Caller can choose types of lever arm info to configure via the
|
||||
leverMarkTypeMask.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) = 0;
|
||||
|
||||
/** @brief
|
||||
Configure the robust location setting.
|
||||
|
||||
@param
|
||||
enable: true to enable robust location and false to disable
|
||||
robust location.
|
||||
|
||||
@param
|
||||
enableForE911: true to enable robust location when device is on
|
||||
E911 session and false to disable on E911 session.
|
||||
This parameter is only valid if robust location is enabled.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configRobustLocation(bool enable, bool enableForE911) = 0;
|
||||
|
||||
/** @brief
|
||||
Config the minimum GPS week used by modem GNSS engine.
|
||||
|
||||
@param
|
||||
minGpsWeek: minimum GPS week to be used by modem GNSS engine.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configMinGpsWeek(uint16_t minGpsWeek) = 0;
|
||||
|
||||
/** @brief
|
||||
Configure the vehicle body-to-Sensor mount parameters and
|
||||
other parameters for dead reckoning position engine.
|
||||
|
||||
@param
|
||||
dreConfig: vehicle body-to-Sensor mount angles and other
|
||||
parameters.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig)=0;
|
||||
|
||||
/** @brief
|
||||
This API is used to instruct the specified engine to be in
|
||||
the pause/resume state. <br/>
|
||||
|
||||
When the engine is placed in paused state, the engine will
|
||||
stop. If there is an on-going session, engine will no longer
|
||||
produce fixes. In the paused state, calling API to delete
|
||||
aiding data from the paused engine may not have effect.
|
||||
Request to delete Aiding data shall be issued after
|
||||
engine resume. <br/>
|
||||
|
||||
Currently, only DRE engine will support pause/resume
|
||||
request. responseCb() will return not supported when request
|
||||
is made to pause/resume none-DRE engine. <br/>
|
||||
|
||||
Request to pause/resume DRE engine can be made with or
|
||||
without an on-going session. With QDR engine, on resume,
|
||||
GNSS position & heading re-acquisition is needed for DR
|
||||
engine to engage. If DR engine is already in the requested
|
||||
state, the request will be no-op. <br/>
|
||||
|
||||
@param
|
||||
engType: the engine that is instructed to change its run
|
||||
state. <br/>
|
||||
|
||||
engState: the new engine run state that the engine is
|
||||
instructed to be in. <br/>
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configEngineRunState(PositioningEngineMask engType,
|
||||
LocEngineRunState engState) = 0;
|
||||
|
||||
/** @brief
|
||||
This API is used to config the NMEA sentence types.
|
||||
|
||||
Without prior calling this API, all NMEA sentences supported
|
||||
in the system, as defined in NmeaTypesMask, will get
|
||||
generated and delivered to all the location clients that
|
||||
register to receive NMEA sentences.
|
||||
|
||||
The NMEA sentence types are per-device setting and calling
|
||||
this API will impact all the location api clients that
|
||||
register to receive NMEA sentences. This API call is not
|
||||
incremental and the new NMEA sentence types will completely
|
||||
overwrite the previous call.
|
||||
|
||||
If one or more unspecified bits are set in the NMEA mask,
|
||||
those bits will be ignored, but the rest of the
|
||||
configuration will get applied.
|
||||
|
||||
Please note that the configured NMEA sentence types are not
|
||||
persistent.
|
||||
|
||||
@param
|
||||
enabledNmeaTypes: specify the set of NMEA sentences the
|
||||
device will generate and deliver to the location api clients
|
||||
that register to receive NMEA sentences. <br/>
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response.
|
||||
*/
|
||||
virtual uint32_t configOutputNmeaTypes(
|
||||
GnssNmeaTypesMask enabledNmeaTypes) = 0;
|
||||
|
||||
/** @brief
|
||||
This API is used to send platform power events to GNSS adapters in order
|
||||
to handle GNSS sessions as per platform power event.
|
||||
|
||||
@param
|
||||
powerState: Current vehicle/platform power state.
|
||||
|
||||
@return
|
||||
No return value.
|
||||
*/
|
||||
virtual void powerStateEvent(PowerStateType powerState) {};
|
||||
};
|
||||
|
||||
#endif /* ILOCATIONAPI_H */
|
985
gps/location/LocationAPI.cpp
Normal file
985
gps/location/LocationAPI.cpp
Normal file
@@ -0,0 +1,985 @@
|
||||
/* Copyright (c) 2017-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.
|
||||
*/
|
||||
#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "LocSvc_LocationAPI"
|
||||
|
||||
#include <location_interface.h>
|
||||
#include <dlfcn.h>
|
||||
#include <loc_pla.h>
|
||||
#include <log_util.h>
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <loc_misc_utils.h>
|
||||
|
||||
typedef const GnssInterface* (getGnssInterface)();
|
||||
typedef const GeofenceInterface* (getGeofenceInterface)();
|
||||
typedef const BatchingInterface* (getBatchingInterface)();
|
||||
|
||||
// GTP services
|
||||
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<LocationAPI*, LocationAPIDestroyCbData>
|
||||
LocationClientDestroyCbMap;
|
||||
|
||||
typedef std::map<LocationAPI*, LocationCallbacks> 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;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
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 loadLibGnss() {
|
||||
|
||||
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
|
||||
gData.gnssInterface =
|
||||
(GnssInterface*)loadLocationInterface<GnssInterface,
|
||||
getGnssInterface>("libgnss.so", "getGnssInterface");
|
||||
if (NULL == gData.gnssInterface) {
|
||||
gGnssLoadFailed = true;
|
||||
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
|
||||
} else {
|
||||
gData.gnssInterface->initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void loadLibBatching() {
|
||||
|
||||
if (NULL == gData.batchingInterface && !gBatchingLoadFailed) {
|
||||
gData.batchingInterface =
|
||||
(BatchingInterface*)loadLocationInterface<BatchingInterface,
|
||||
getBatchingInterface>("libbatching.so", "getBatchingInterface");
|
||||
if (NULL == gData.batchingInterface) {
|
||||
gBatchingLoadFailed = true;
|
||||
LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__);
|
||||
} else {
|
||||
gData.batchingInterface->initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void loadLibGeofencing() {
|
||||
|
||||
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
|
||||
gData.geofenceInterface =
|
||||
(GeofenceInterface*)loadLocationInterface<GeofenceInterface,
|
||||
getGeofenceInterface>("libgeofencing.so", "getGeofenceInterface");
|
||||
if (NULL == gData.geofenceInterface) {
|
||||
gGeofenceLoadFailed = true;
|
||||
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
|
||||
} else {
|
||||
gData.geofenceInterface->initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
|
||||
{
|
||||
return (locationCallbacks.gnssLocationInfoCb != nullptr ||
|
||||
locationCallbacks.engineLocationsInfoCb != nullptr ||
|
||||
locationCallbacks.gnssSvCb != nullptr ||
|
||||
locationCallbacks.gnssNmeaCb != nullptr ||
|
||||
locationCallbacks.gnssDataCb != nullptr ||
|
||||
locationCallbacks.gnssMeasurementsCb != nullptr ||
|
||||
locationCallbacks.gnssNHzMeasurementsCb != 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.gnssNHzMeasurementsCb != 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);
|
||||
|
||||
if (isGnssClient(locationCallbacks)) {
|
||||
loadLibGnss();
|
||||
if (NULL != gData.gnssInterface) {
|
||||
gData.gnssInterface->addClient(newLocationAPI, locationCallbacks);
|
||||
if (!requestedCapabilities) {
|
||||
gData.gnssInterface->requestCapabilities(newLocationAPI);
|
||||
requestedCapabilities = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isBatchingClient(locationCallbacks)) {
|
||||
loadLibBatching();
|
||||
if (NULL != gData.batchingInterface) {
|
||||
gData.batchingInterface->addClient(newLocationAPI, locationCallbacks);
|
||||
if (!requestedCapabilities) {
|
||||
gData.batchingInterface->requestCapabilities(newLocationAPI);
|
||||
requestedCapabilities = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isGeofenceClient(locationCallbacks)) {
|
||||
loadLibGeofencing();
|
||||
if (NULL != gData.geofenceInterface) {
|
||||
gData.geofenceInterface->addClient(newLocationAPI, locationCallbacks);
|
||||
if (!requestedCapabilities) {
|
||||
gData.geofenceInterface->requestCapabilities(newLocationAPI);
|
||||
requestedCapabilities = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!requestedCapabilities && locationCallbacks.capabilitiesCb != nullptr) {
|
||||
loadLibGnss();
|
||||
if (NULL != gData.gnssInterface) {
|
||||
gData.gnssInterface->addClient(newLocationAPI, locationCallbacks);
|
||||
gData.gnssInterface->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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
loadLibGnss();
|
||||
if (NULL != gData.gnssInterface) {
|
||||
// either adds new Client or updates existing Client
|
||||
gData.gnssInterface->addClient(this, locationCallbacks);
|
||||
}
|
||||
}
|
||||
|
||||
if (isBatchingClient(locationCallbacks)) {
|
||||
loadLibBatching();
|
||||
if (NULL != gData.batchingInterface) {
|
||||
// either adds new Client or updates existing Client
|
||||
gData.batchingInterface->addClient(this, locationCallbacks);
|
||||
}
|
||||
}
|
||||
|
||||
if (isGeofenceClient(locationCallbacks)) {
|
||||
loadLibGeofencing();
|
||||
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 (NULL != gData.controlAPI) {
|
||||
controlAPI = gData.controlAPI;
|
||||
} else {
|
||||
if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) {
|
||||
loadLibGnss();
|
||||
if (NULL != gData.gnssInterface) {
|
||||
gData.controlAPI = new LocationControlAPI();
|
||||
gData.controlCallbacks = locationControlCallbacks;
|
||||
gData.gnssInterface->setControlCallbacks(locationControlCallbacks);
|
||||
controlAPI = gData.controlAPI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&gDataMutex);
|
||||
return controlAPI;
|
||||
}
|
||||
|
||||
|
||||
LocationControlAPI*
|
||||
LocationControlAPI::getInstance()
|
||||
{
|
||||
LocationControlAPI* controlAPI = NULL;
|
||||
|
||||
pthread_mutex_lock(&gDataMutex);
|
||||
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) {
|
||||
uint32_t id = 0;
|
||||
pthread_mutex_lock(&gDataMutex);
|
||||
|
||||
if (gData.gnssInterface != NULL) {
|
||||
id = gData.gnssInterface->setOptInStatus(userConsent);
|
||||
} else {
|
||||
LOC_LOGe("No gnss interface available for Location Control API");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&gDataMutex);
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t LocationControlAPI::configOutputNmeaTypes(
|
||||
GnssNmeaTypesMask enabledNmeaTypes) {
|
||||
uint32_t id = 0;
|
||||
pthread_mutex_lock(&gDataMutex);
|
||||
|
||||
if (gData.gnssInterface != NULL) {
|
||||
id = gData.gnssInterface->configOutputNmeaTypes(enabledNmeaTypes);
|
||||
} else {
|
||||
LOC_LOGe("No gnss interface available for Location Control API");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&gDataMutex);
|
||||
return id;
|
||||
}
|
||||
|
||||
void LocationControlAPI::powerStateEvent(PowerStateType powerState) {
|
||||
pthread_mutex_lock(&gDataMutex);
|
||||
|
||||
LOC_LOGv("--> entry, powerState: %d", powerState);
|
||||
|
||||
if (NULL != gData.gnssInterface) {
|
||||
gData.gnssInterface->updateSystemPowerState(powerState);
|
||||
} else {
|
||||
LOC_LOGv("No gnss interface available.");
|
||||
}
|
||||
|
||||
if (NULL != gData.geofenceInterface) {
|
||||
gData.geofenceInterface->updateSystemPowerState(powerState);
|
||||
} else {
|
||||
LOC_LOGv("No geofence interface available.");
|
||||
}
|
||||
|
||||
if (NULL != gData.batchingInterface) {
|
||||
gData.batchingInterface->updateSystemPowerState(powerState);
|
||||
} else {
|
||||
LOC_LOGv("No batching interface available.");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&gDataMutex);
|
||||
}
|
561
gps/location/LocationAPI.h
Normal file
561
gps/location/LocationAPI.h
Normal file
@@ -0,0 +1,561 @@
|
||||
/* Copyright (c) 2017-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.
|
||||
*/
|
||||
|
||||
#ifndef LOCATIONAPI_H
|
||||
#define LOCATIONAPI_H
|
||||
|
||||
#include "ILocationAPI.h"
|
||||
|
||||
|
||||
class LocationAPI : public ILocationAPI
|
||||
{
|
||||
private:
|
||||
LocationAPI();
|
||||
~LocationAPI();
|
||||
|
||||
public:
|
||||
/* creates an instance to LocationAPI object.
|
||||
Will return NULL if mandatory parameters are invalid or if the maximum number
|
||||
of instances have been reached */
|
||||
static LocationAPI* createInstance(LocationCallbacks&);
|
||||
|
||||
/* destroy/cleans up the instance, which should be called when LocationControlAPI object is
|
||||
no longer needed. LocationControlAPI* returned from createInstance will no longer valid
|
||||
after destroy is called.
|
||||
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);
|
||||
|
||||
void onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType);
|
||||
|
||||
/* updates/changes the callbacks that will be called.
|
||||
mandatory callbacks must be present for callbacks to be successfully updated
|
||||
no return value */
|
||||
virtual void updateCallbacks(LocationCallbacks&) override;
|
||||
|
||||
/* ================================== TRACKING ================================== */
|
||||
|
||||
/* startTracking starts a tracking session, which returns a session id that will be
|
||||
used by the other tracking APIs and also in the responseCallback to match command
|
||||
with response. locations are reported on the trackingCallback passed in createInstance
|
||||
periodically according to LocationOptions.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successfully started
|
||||
LOCATION_ERROR_ALREADY_STARTED if a startTracking session is already in progress
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no trackingCallback was passed in createInstance
|
||||
LOCATION_ERROR_INVALID_PARAMETER if TrackingOptions parameter is invalid */
|
||||
virtual uint32_t startTracking(TrackingOptions&) override;
|
||||
|
||||
/* stopTracking stops a tracking session associated with id parameter.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
|
||||
virtual void stopTracking(uint32_t id) override;
|
||||
|
||||
/* updateTrackingOptions changes the TrackingOptions of a tracking session associated with id
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if TrackingOptions parameters are invalid
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
|
||||
virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) override;
|
||||
|
||||
/* ================================== BATCHING ================================== */
|
||||
|
||||
/* startBatching starts a batching session, which returns a session id that will be
|
||||
used by the other batching APIs and also in the responseCallback to match command
|
||||
with response. locations are reported on the batchingCallback passed in createInstance
|
||||
periodically according to LocationOptions. A batching session starts tracking on
|
||||
the low power processor and delivers them in batches by the batchingCallback when
|
||||
the batch is full or when getBatchedLocations is called. This allows for the processor
|
||||
that calls this API to sleep when the low power processor can batch locations in the
|
||||
backgroup and wake up the processor calling the API only when the batch is full, thus
|
||||
saving power
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_ALREADY_STARTED if a startBatching session is already in progress
|
||||
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 */
|
||||
virtual uint32_t startBatching(BatchingOptions&) override;
|
||||
|
||||
/* stopBatching stops a batching session associated with id parameter.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */
|
||||
virtual void stopBatching(uint32_t id) override;
|
||||
|
||||
/* updateBatchingOptions changes the BatchingOptions of a batching session associated with id
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if BatchingOptions parameters are invalid
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
|
||||
virtual void updateBatchingOptions(uint32_t id, BatchingOptions&) override;
|
||||
|
||||
/* getBatchedLocations gets a number of locations that are currently stored/batched
|
||||
on the low power processor, delivered by the batchingCallback passed in createInstance.
|
||||
Location are then deleted from the batch stored on the low power processor.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful, will be followed by batchingCallback call
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
|
||||
virtual void getBatchedLocations(uint32_t id, size_t count) override;
|
||||
|
||||
/* ================================== GEOFENCE ================================== */
|
||||
|
||||
/* addGeofences adds any number of geofences and returns an array of geofence ids that
|
||||
will be used by the other geofence APIs and also in the collectiveResponseCallback to
|
||||
match command with response. The geofenceBreachCallback will deliver the status of each
|
||||
geofence according to the GeofenceOption for each. The geofence id array returned will
|
||||
be valid until the collectiveResponseCallback is called and has returned.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_CALLBACK_MISSING if no geofenceBreachCallback
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
LOCATION_ERROR_NOT_SUPPORTED if geofence is not supported */
|
||||
virtual uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*) override;
|
||||
|
||||
/* removeGeofences removes any number of geofences. Caller should delete ids array after
|
||||
removeGeofences returneds.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||
virtual void removeGeofences(size_t count, uint32_t* ids) override;
|
||||
|
||||
/* modifyGeofences modifies any number of geofences. Caller should delete ids array after
|
||||
modifyGeofences returns.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */
|
||||
virtual void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options) override;
|
||||
|
||||
/* pauseGeofences pauses any number of geofences, which is similar to removeGeofences,
|
||||
only that they can be resumed at any time. Caller should delete ids array after
|
||||
pauseGeofences returns.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||
virtual void pauseGeofences(size_t count, uint32_t* ids) override;
|
||||
|
||||
/* resumeGeofences resumes any number of geofences that are currently paused. Caller should
|
||||
delete ids array after resumeGeofences returns.
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
|
||||
virtual void resumeGeofences(size_t count, uint32_t* ids) override;
|
||||
|
||||
/* ================================== GNSS ====================================== */
|
||||
|
||||
/* gnssNiResponse is called in response to a gnssNiCallback.
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
|
||||
LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
|
||||
virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) override;
|
||||
|
||||
/* ================================== NETWORK PROVIDER =========================== */
|
||||
|
||||
/* enableNetworkProvider enables Network Provider */
|
||||
virtual void enableNetworkProvider();
|
||||
|
||||
/* disableNetworkProvider disables Network Provider */
|
||||
virtual void disableNetworkProvider();
|
||||
|
||||
/* startNetworkLocation starts tracking session for
|
||||
network location request */
|
||||
virtual void startNetworkLocation(trackingCallback* callback);
|
||||
|
||||
/* stopNetworkLocation stops the ongoing tracking session for
|
||||
network location request */
|
||||
virtual void stopNetworkLocation(trackingCallback* callback);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
size_t size; // set to sizeof(LocationControlCallbacks)
|
||||
responseCallback responseCb; // mandatory
|
||||
collectiveResponseCallback collectiveResponseCb; // mandatory
|
||||
gnssConfigCallback gnssConfigCb; // optional
|
||||
} LocationControlCallbacks;
|
||||
|
||||
class LocationControlAPI : public ILocationControlAPI
|
||||
{
|
||||
private:
|
||||
LocationControlAPI();
|
||||
~LocationControlAPI();
|
||||
|
||||
public:
|
||||
/* creates an instance to LocationControlAPI object.
|
||||
Will return NULL if mandatory parameters are invalid or if the maximum number
|
||||
of instances have been reached. Only once instance allowed */
|
||||
static LocationControlAPI* createInstance(LocationControlCallbacks&);
|
||||
static LocationControlAPI* getInstance();
|
||||
|
||||
/* destroy/cleans up the instance, which should be called when LocationControlAPI object is
|
||||
no longer needed. LocationControlAPI* returned from createInstance will no longer valid
|
||||
after destroy is called */
|
||||
void destroy();
|
||||
|
||||
/* enable will enable specific location technology to be used for calculation locations and
|
||||
will effectively start a control session if call is successful, which returns a session id
|
||||
that will be returned in responseCallback to match command with response. The session id is
|
||||
also needed to call the disable command.
|
||||
This effect is global for all clients of LocationAPI
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ALREADY_STARTED if an enable was already called for this techType
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
|
||||
uint32_t enable(LocationTechnologyType techType);
|
||||
|
||||
/* disable will disable specific location technology to be used for calculation locations and
|
||||
effectively ends the control session if call is successful.
|
||||
id parameter is the session id that was returned in enable responseCallback for techType.
|
||||
The session id is no longer valid after disable's responseCallback returns success.
|
||||
This effect is global for all clients of LocationAPI
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_ID_UNKNOWN if id was not returned from responseCallback from enable
|
||||
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
|
||||
void disable(uint32_t id);
|
||||
|
||||
/* gnssUpdateConfig updates the gnss specific configuration, which returns a session id array
|
||||
with an id for each of the bits set in GnssConfig.flags, order from low bits to high bits.
|
||||
The response for each config that is set will be returned in collectiveResponseCallback.
|
||||
The session id array returned will be valid until the collectiveResponseCallback is called
|
||||
and has returned. This effect is global for all clients of LocationAPI
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
|
||||
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason
|
||||
|
||||
PLEASE NOTE: It is caller's resposibility to FREE the memory of the return value.
|
||||
The memory must be freed by delete [].*/
|
||||
virtual uint32_t* gnssUpdateConfig(const GnssConfig& config) override;
|
||||
|
||||
/* gnssGetConfig fetches the current constellation and SV configuration
|
||||
on the GNSS engine.
|
||||
Returns a session id array with an id for each of the bits set in
|
||||
the mask parameter, order from low bits to high bits.
|
||||
Response is sent via the registered gnssConfigCallback.
|
||||
This effect is global for all clients of LocationAPI
|
||||
collectiveResponseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if session was successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameter is invalid
|
||||
LOCATION_ERROR_CALLBACK_MISSING If no gnssConfigCallback
|
||||
was passed in createInstance
|
||||
LOCATION_ERROR_NOT_SUPPORTED If read of requested configuration
|
||||
is not supported
|
||||
|
||||
PLEASE NOTE: It is caller's resposibility to FREE the memory of the return value.
|
||||
The memory must be freed by delete [].*/
|
||||
uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
|
||||
|
||||
/* delete specific gnss aiding data for testing, which returns a session id
|
||||
that will be returned in responseCallback to match command with response.
|
||||
Only allowed in userdebug builds. This effect is global for all clients of LocationAPI
|
||||
responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
LOCATION_ERROR_NOT_SUPPORTED if build is not userdebug */
|
||||
virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) override;
|
||||
|
||||
/** @brief
|
||||
Configure the constellation and SVs to be used by the GNSS engine on
|
||||
modem.
|
||||
|
||||
@param
|
||||
constellationEnablementConfig: configuration to enable/disable SV
|
||||
constellation to be used by SPE engine. When size in
|
||||
constellationEnablementConfig is set to 0, this indicates to reset SV
|
||||
constellation configuration to modem NV default.
|
||||
|
||||
blacklistSvConfig: configuration to blacklist or unblacklist SVs
|
||||
used by SPE engine
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configConstellations(
|
||||
const GnssSvTypeConfig& constellationEnablementConfig,
|
||||
const GnssSvIdConfig& blacklistSvConfig) override;
|
||||
|
||||
/** @brief
|
||||
Configure the secondary band of constellations to be used by
|
||||
the GNSS engine on modem.
|
||||
|
||||
@param
|
||||
secondaryBandConfig: configuration the secondary band usage
|
||||
for SPE engine
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configConstellationSecondaryBand(
|
||||
const GnssSvTypeConfig& secondaryBandConfig) override;
|
||||
|
||||
/** @brief
|
||||
Enable or disable the constrained time uncertainty feature.
|
||||
|
||||
@param
|
||||
enable: true to enable the constrained time uncertainty
|
||||
feature and false to disable the constrainted time
|
||||
uncertainty feature.
|
||||
|
||||
@param
|
||||
tuncThreshold: this specifies the time uncertainty threshold
|
||||
that gps engine need to maintain, in units of milli-seconds.
|
||||
Default is 0.0 meaning that modem default value of time
|
||||
uncertainty threshold will be used. This parameter is
|
||||
ignored when requesting to disable this feature.
|
||||
|
||||
@param
|
||||
energyBudget: this specifies the power budget that gps
|
||||
engine is allowed to spend to maintain the time uncertainty.
|
||||
Default is 0 meaning that GPS engine is not constained by
|
||||
power budget and can spend as much power as needed. The
|
||||
parameter need to be specified in units of 0.1 milli watt
|
||||
second. This parameter is ignored requesting to disable this
|
||||
feature.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters
|
||||
are invalid
|
||||
*/
|
||||
virtual uint32_t configConstrainedTimeUncertainty(
|
||||
bool enable, float tuncThreshold = 0.0,
|
||||
uint32_t energyBudget = 0) override;
|
||||
|
||||
/** @brief
|
||||
Enable or disable position assisted clock estimator feature.
|
||||
|
||||
@param
|
||||
enable: true to enable position assisted clock estimator and
|
||||
false to disable the position assisted clock estimator
|
||||
feature.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configPositionAssistedClockEstimator(bool enable) override;
|
||||
|
||||
/** @brief
|
||||
Sets the lever arm parameters for the vehicle.
|
||||
|
||||
@param
|
||||
configInfo: lever arm configuration info regarding below two
|
||||
types of lever arm info:
|
||||
a: GNSS Antenna w.r.t the origin at the IMU e.g.: inertial
|
||||
measurement unit.
|
||||
b: lever arm parameters regarding the OPF (output frame)
|
||||
w.r.t the origin (at the GPS Antenna). Vehicle manufacturers
|
||||
prefer the position output to be tied to a specific point in
|
||||
the vehicle rather than where the antenna is placed
|
||||
(midpoint of the rear axle is typical).
|
||||
|
||||
Caller can choose types of lever arm info to configure via the
|
||||
leverMarkTypeMask.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) override;
|
||||
|
||||
/** @brief
|
||||
Configure the robust location setting.
|
||||
|
||||
@param
|
||||
enable: true to enable robust location and false to disable
|
||||
robust location.
|
||||
|
||||
@param
|
||||
enableForE911: true to enable robust location when device is
|
||||
on E911 session and false to disable on E911 session.
|
||||
This parameter is only valid if robust location is enabled.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configRobustLocation(bool enable, bool enableForE911) override;
|
||||
|
||||
/** @brief
|
||||
Config the minimal GPS week used by modem GNSS engine.
|
||||
|
||||
@param
|
||||
minGpsWeek: minimal GPS week to be used by modem GNSS engine.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configMinGpsWeek(uint16_t minGpsWeek) override;
|
||||
|
||||
/** @brief
|
||||
Configure the vehicle body-to-Sensor mount parameters and
|
||||
other parameters for dead reckoning position engine.
|
||||
|
||||
@param
|
||||
dreConfig: vehicle body-to-Sensor mount angles and other
|
||||
parameters.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configDeadReckoningEngineParams(
|
||||
const DeadReckoningEngineConfig& dreConfig) override;
|
||||
|
||||
/** @brief
|
||||
This API is used to instruct the specified engine to be in
|
||||
the pause/resume state. <br/>
|
||||
|
||||
When the engine is placed in paused state, the engine will
|
||||
stop. If there is an on-going session, engine will no longer
|
||||
produce fixes. In the paused state, calling API to delete
|
||||
aiding data from the paused engine may not have effect.
|
||||
Request to delete Aiding data shall be issued after
|
||||
engine resume. <br/>
|
||||
|
||||
Currently, only DRE engine will support pause/resume
|
||||
request. responseCb() will return not supported when request
|
||||
is made to pause/resume none-DRE engine. <br/>
|
||||
|
||||
Request to pause/resume DRE engine can be made with or
|
||||
without an on-going session. With QDR engine, on resume, GNSS
|
||||
position & heading re-acquisition is needed for DR engine to
|
||||
engage. If DR engine is already in the requested state, the
|
||||
request will be no-op. <br/>
|
||||
|
||||
@param
|
||||
engType: the engine that is instructed to change its run
|
||||
state. <br/>
|
||||
|
||||
engState: the new engine run state that the engine is
|
||||
instructed to be in. <br/>
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response. This effect is global for all
|
||||
clients of LocationAPI responseCallback returns:
|
||||
LOCATION_ERROR_SUCCESS if successful
|
||||
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
|
||||
*/
|
||||
virtual uint32_t configEngineRunState(PositioningEngineMask engType,
|
||||
LocEngineRunState engState) override;
|
||||
|
||||
/** @brief
|
||||
Set the EULA opt-in status from system user. This is used as consent to
|
||||
use network-based positioning.
|
||||
|
||||
@param
|
||||
userConsnt: user agrees to use GTP service or not.
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response.
|
||||
*/
|
||||
virtual uint32_t setOptInStatus(bool userConsent);
|
||||
|
||||
/** @brief
|
||||
This API is used to config the NMEA sentence types.
|
||||
|
||||
Without prior calling this API, all NMEA sentences supported
|
||||
in the system, as defined in NmeaTypesMask, will get
|
||||
generated and delivered to all the location clients that
|
||||
register to receive NMEA sentences.
|
||||
|
||||
The NMEA sentence types are per-device setting and calling
|
||||
this API will impact all the location api clients that
|
||||
register to receive NMEA sentences. This API call is not
|
||||
incremental and the new NMEA sentence types will completely
|
||||
overwrite the previous call.
|
||||
|
||||
If one or more unspecified bits are set in the NMEA mask,
|
||||
those bits will be ignored, but the rest of the
|
||||
configuration will get applied.
|
||||
|
||||
Please note that the configured NMEA sentence types are not
|
||||
persistent.
|
||||
|
||||
@param
|
||||
enabledNmeaTypes: specify the set of NMEA sentences the
|
||||
device will generate and deliver to the location api clients
|
||||
that register to receive NMEA sentences. <br/>
|
||||
|
||||
@return
|
||||
A session id that will be returned in responseCallback to
|
||||
match command with response.
|
||||
*/
|
||||
virtual uint32_t configOutputNmeaTypes(
|
||||
GnssNmeaTypesMask enabledNmeaTypes) override;
|
||||
|
||||
/** @brief
|
||||
This API is used to send platform power events to GNSS adapters in order
|
||||
to handle GNSS sessions as per platform power event.
|
||||
|
||||
@param
|
||||
powerState: Current vehicle/platform power state.
|
||||
|
||||
@return
|
||||
No return value.
|
||||
*/
|
||||
virtual void powerStateEvent(PowerStateType powerState) override;
|
||||
};
|
||||
|
||||
#endif /* LOCATIONAPI_H */
|
969
gps/location/LocationAPIClientBase.cpp
Normal file
969
gps/location/LocationAPIClientBase.cpp
Normal file
@@ -0,0 +1,969 @@
|
||||
/* Copyright (c) 2017, 2020-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.
|
||||
*/
|
||||
|
||||
#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "LocSvc_APIClientBase"
|
||||
|
||||
#include <loc_pla.h>
|
||||
#include <log_util.h>
|
||||
#include <inttypes.h>
|
||||
#include <loc_cfg.h>
|
||||
#include "LocationAPIClientBase.h"
|
||||
|
||||
#define GEOFENCE_SESSION_ID 0xFFFFFFFF
|
||||
#define CONFIG_SESSION_ID 0xFFFFFFFF
|
||||
|
||||
// LocationAPIControlClient
|
||||
LocationAPIControlClient::LocationAPIControlClient() :
|
||||
mEnabled(false)
|
||||
{
|
||||
pthread_mutex_init(&mMutex, nullptr);
|
||||
|
||||
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
|
||||
mRequestQueues[i].reset((uint32_t)0);
|
||||
}
|
||||
|
||||
LocationControlCallbacks locationControlCallbacks;
|
||||
locationControlCallbacks.size = sizeof(LocationControlCallbacks);
|
||||
|
||||
locationControlCallbacks.responseCb =
|
||||
[this](LocationError error, uint32_t id) {
|
||||
onCtrlResponseCb(error, id);
|
||||
};
|
||||
locationControlCallbacks.collectiveResponseCb =
|
||||
[this](size_t count, LocationError* errors, uint32_t* ids) {
|
||||
onCtrlCollectiveResponseCb(count, errors, ids);
|
||||
};
|
||||
|
||||
mLocationControlAPI = LocationControlAPI::createInstance(locationControlCallbacks);
|
||||
}
|
||||
|
||||
LocationAPIControlClient::~LocationAPIControlClient()
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
|
||||
if (mLocationControlAPI) {
|
||||
mLocationControlAPI->destroy();
|
||||
mLocationControlAPI = nullptr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
|
||||
mRequestQueues[i].reset((uint32_t)0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
|
||||
uint32_t LocationAPIControlClient::locAPIGnssDeleteAidingData(GnssAidingData& data)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationControlAPI) {
|
||||
uint32_t session = mLocationControlAPI->gnssDeleteAidingData(data);
|
||||
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||
mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].reset(session);
|
||||
mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].push(new GnssDeleteAidingDataRequest(*this));
|
||||
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIControlClient::locAPIEnable(LocationTechnologyType techType)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mEnabled) {
|
||||
// just return success if already enabled
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
} else if (mLocationControlAPI) {
|
||||
uint32_t session = mLocationControlAPI->enable(techType);
|
||||
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||
mRequestQueues[CTRL_REQUEST_CONTROL].reset(session);
|
||||
mRequestQueues[CTRL_REQUEST_CONTROL].push(new EnableRequest(*this));
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
mEnabled = true;
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] failed.", __FUNCTION__, __LINE__);
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LocationAPIControlClient::locAPIDisable()
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mEnabled && mLocationControlAPI) {
|
||||
uint32_t session = 0;
|
||||
session = mRequestQueues[CTRL_REQUEST_CONTROL].getSession();
|
||||
if (session > 0) {
|
||||
mRequestQueues[CTRL_REQUEST_CONTROL].push(new DisableRequest(*this));
|
||||
mLocationControlAPI->disable(session);
|
||||
mEnabled = false;
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationControlAPI) {
|
||||
uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
|
||||
LOC_LOGv("gnssUpdateConfig return array: %p", idArray);
|
||||
if (nullptr != idArray) {
|
||||
if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr()) {
|
||||
mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].reset(idArray);
|
||||
}
|
||||
mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this));
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
delete [] idArray;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIControlClient::locAPIGnssGetConfig(GnssConfigFlagsMask mask)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationControlAPI) {
|
||||
|
||||
uint32_t* idArray = mLocationControlAPI->gnssGetConfig(mask);
|
||||
LOC_LOGv("gnssGetConfig return array: %p", idArray);
|
||||
if (nullptr != idArray) {
|
||||
if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr()) {
|
||||
mRequestQueues[CTRL_REQUEST_CONFIG_GET].reset(idArray);
|
||||
}
|
||||
mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this));
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
delete [] idArray;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LocationAPIControlClient::onCtrlResponseCb(LocationError error, uint32_t id)
|
||||
{
|
||||
if (error != LOCATION_ERROR_SUCCESS) {
|
||||
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
|
||||
} else {
|
||||
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
|
||||
}
|
||||
LocationAPIRequest* request = getRequestBySession(id);
|
||||
if (request) {
|
||||
request->onResponse(error, id);
|
||||
delete request;
|
||||
}
|
||||
}
|
||||
|
||||
void LocationAPIControlClient::onCtrlCollectiveResponseCb(
|
||||
size_t count, LocationError* errors, uint32_t* ids)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (errors[i] != LOCATION_ERROR_SUCCESS) {
|
||||
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||
} else {
|
||||
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||
}
|
||||
}
|
||||
LocationAPIRequest* request = getRequestBySessionArrayPtr(ids);
|
||||
if (request) {
|
||||
request->onCollectiveResponse(count, errors, ids);
|
||||
delete request;
|
||||
}
|
||||
}
|
||||
|
||||
LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t session)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
LocationAPIRequest* request = nullptr;
|
||||
|
||||
if (mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].getSession() == session) {
|
||||
request = mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].pop();
|
||||
} else if (mRequestQueues[CTRL_REQUEST_CONTROL].getSession() == session) {
|
||||
request = mRequestQueues[CTRL_REQUEST_CONTROL].pop();
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return request;
|
||||
}
|
||||
|
||||
LocationAPIRequest*
|
||||
LocationAPIControlClient::getRequestBySessionArrayPtr(
|
||||
uint32_t* sessionArrayPtr)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
LocationAPIRequest* request = nullptr;
|
||||
|
||||
if (mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr() == sessionArrayPtr) {
|
||||
request = mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].pop();
|
||||
} else if (mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr() == sessionArrayPtr) {
|
||||
request = mRequestQueues[CTRL_REQUEST_CONFIG_GET].pop();
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return request;
|
||||
}
|
||||
|
||||
// LocationAPIClientBase
|
||||
LocationAPIClientBase::LocationAPIClientBase() :
|
||||
mGeofenceBreachCallback(nullptr),
|
||||
mBatchingStatusCallback(nullptr),
|
||||
mLocationAPI(nullptr),
|
||||
mBatchSize(-1),
|
||||
mTracking(false)
|
||||
{
|
||||
|
||||
// use recursive mutex, in case callback come from the same thread
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mMutex, &attr);
|
||||
|
||||
for (int i = 0; i < REQUEST_MAX; i++) {
|
||||
mRequestQueues[i].reset((uint32_t)0);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPISetCallbacks(LocationCallbacks& locationCallbacks)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
|
||||
if (locationCallbacks.geofenceBreachCb != nullptr) {
|
||||
mGeofenceBreachCallback = locationCallbacks.geofenceBreachCb;
|
||||
locationCallbacks.geofenceBreachCb =
|
||||
[this](GeofenceBreachNotification geofenceBreachNotification) {
|
||||
beforeGeofenceBreachCb(geofenceBreachNotification);
|
||||
};
|
||||
}
|
||||
|
||||
locationCallbacks.capabilitiesCb =
|
||||
[this](LocationCapabilitiesMask capabilitiesMask) {
|
||||
onCapabilitiesCb(capabilitiesMask);
|
||||
};
|
||||
locationCallbacks.responseCb = [this](LocationError error, uint32_t id) {
|
||||
onResponseCb(error, id);
|
||||
};
|
||||
locationCallbacks.collectiveResponseCb =
|
||||
[this](size_t count, LocationError* errors, uint32_t* ids) {
|
||||
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 {
|
||||
mLocationAPI->updateCallbacks(locationCallbacks);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::destroy()
|
||||
{
|
||||
LOC_LOGD("LocationAPIClientBase::destroy()");
|
||||
|
||||
pthread_mutex_lock(&mMutex);
|
||||
|
||||
mGeofenceBreachCallback = nullptr;
|
||||
|
||||
for (int i = 0; i < REQUEST_MAX; i++) {
|
||||
mRequestQueues[i].reset((uint32_t)0);
|
||||
}
|
||||
|
||||
LocationAPI* localHandle = nullptr;
|
||||
if (nullptr != mLocationAPI) {
|
||||
localHandle = mLocationAPI;
|
||||
mLocationAPI = nullptr;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
// Invoking destroy has the possibility of destroy complete callback
|
||||
// being invoked right away in the same context, hence no instance
|
||||
// member must be accessed after the destroy call.
|
||||
if (nullptr != localHandle) {
|
||||
localHandle->destroy([this]() {onLocationApiDestroyCompleteCb();});
|
||||
}
|
||||
}
|
||||
|
||||
LocationAPIClientBase::~LocationAPIClientBase()
|
||||
{
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::onLocationApiDestroyCompleteCb()
|
||||
{
|
||||
LOC_LOGD("LocationAPIClientBase::onLocationApiDestroyCompleteCb()");
|
||||
delete this;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIClientBase::locAPIStartTracking(TrackingOptions& options)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
if (mTracking) {
|
||||
LOC_LOGW("%s:%d] Existing tracking session present", __FUNCTION__, __LINE__);
|
||||
} else {
|
||||
uint32_t session = mLocationAPI->startTracking(options);
|
||||
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||
// onResponseCb might be called from other thread immediately after
|
||||
// startTracking returns, so we are not going to unlock mutex
|
||||
// until StartTrackingRequest is pushed into mRequestQueues[REQUEST_TRACKING]
|
||||
mRequestQueues[REQUEST_TRACKING].reset(session);
|
||||
mRequestQueues[REQUEST_TRACKING].push(new StartTrackingRequest(*this));
|
||||
mTracking = true;
|
||||
}
|
||||
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIStopTracking()
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t session = 0;
|
||||
session = mRequestQueues[REQUEST_TRACKING].getSession();
|
||||
if (session > 0) {
|
||||
mRequestQueues[REQUEST_TRACKING].push(new StopTrackingRequest(*this));
|
||||
mLocationAPI->stopTracking(session);
|
||||
mTracking = false;
|
||||
} else {
|
||||
LOC_LOGD("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIUpdateTrackingOptions(TrackingOptions& options)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t session = 0;
|
||||
session = mRequestQueues[REQUEST_TRACKING].getSession();
|
||||
if (session > 0) {
|
||||
mRequestQueues[REQUEST_TRACKING].push(new UpdateTrackingOptionsRequest(*this));
|
||||
mLocationAPI->updateTrackingOptions(session, options);
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
int32_t LocationAPIClientBase::locAPIGetBatchSize()
|
||||
{
|
||||
if (mBatchSize == -1) {
|
||||
const loc_param_s_type batching_conf_param_table[] =
|
||||
{
|
||||
{"BATCH_SIZE", &mBatchSize, nullptr, 'n'},
|
||||
};
|
||||
UTIL_READ_CONF(LOC_PATH_BATCHING_CONF, batching_conf_param_table);
|
||||
if (mBatchSize < 0) {
|
||||
// set mBatchSize to 0 if we got an illegal value from config file
|
||||
mBatchSize = 0;
|
||||
}
|
||||
}
|
||||
return mBatchSize;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIClientBase::locAPIStartSession(
|
||||
uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
|
||||
if (mSessionBiDict.hasId(id)) {
|
||||
LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id);
|
||||
retVal = LOCATION_ERROR_ALREADY_STARTED;
|
||||
} else {
|
||||
uint32_t trackingSession = 0;
|
||||
uint32_t batchingSession = 0;
|
||||
|
||||
if (sessionMode == SESSION_MODE_ON_FIX) {
|
||||
trackingSession = mLocationAPI->startTracking(options);
|
||||
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
|
||||
mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
|
||||
} else {
|
||||
// Fill in the batch mode
|
||||
BatchingOptions batchOptions = {};
|
||||
batchOptions.size = sizeof(BatchingOptions);
|
||||
switch (sessionMode) {
|
||||
case SESSION_MODE_ON_FULL:
|
||||
batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
|
||||
break;
|
||||
case SESSION_MODE_ON_TRIP_COMPLETED:
|
||||
batchOptions.batchingMode = BATCHING_MODE_TRIP;
|
||||
break;
|
||||
default:
|
||||
batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
// Populate location option values
|
||||
batchOptions.minDistance = options.minDistance;
|
||||
batchOptions.minInterval = options.minInterval;
|
||||
batchOptions.mode = options.mode;
|
||||
|
||||
batchingSession = mLocationAPI->startBatching(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_FIX) ?
|
||||
batchingSession : trackingSession);
|
||||
|
||||
SessionEntity entity;
|
||||
entity.id = id;
|
||||
entity.trackingSession = trackingSession;
|
||||
entity.batchingSession = batchingSession;
|
||||
entity.sessionMode = sessionMode;
|
||||
mSessionBiDict.set(id, session, entity);
|
||||
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
|
||||
if (mSessionBiDict.hasId(id)) {
|
||||
SessionEntity entity = mSessionBiDict.getExtById(id);
|
||||
|
||||
uint32_t trackingSession = entity.trackingSession;
|
||||
uint32_t batchingSession = entity.batchingSession;
|
||||
uint32_t sMode = entity.sessionMode;
|
||||
|
||||
if (sMode == SESSION_MODE_ON_FIX) {
|
||||
mRequestQueues[REQUEST_SESSION].push(new StopTrackingRequest(*this));
|
||||
mLocationAPI->stopTracking(trackingSession);
|
||||
} else {
|
||||
mRequestQueues[REQUEST_SESSION].push(new StopBatchingRequest(*this));
|
||||
mLocationAPI->stopBatching(batchingSession);
|
||||
}
|
||||
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
} else {
|
||||
retVal = LOCATION_ERROR_ID_UNKNOWN;
|
||||
LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
|
||||
}
|
||||
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(
|
||||
uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
|
||||
if (mSessionBiDict.hasId(id)) {
|
||||
SessionEntity entity = mSessionBiDict.getExtById(id);
|
||||
|
||||
uint32_t trackingSession = entity.trackingSession;
|
||||
uint32_t batchingSession = entity.batchingSession;
|
||||
uint32_t sMode = entity.sessionMode;
|
||||
|
||||
if (sessionMode == SESSION_MODE_ON_FIX) {
|
||||
// we only add an UpdateTrackingOptionsRequest to mRequestQueues[REQUEST_SESSION],
|
||||
// even if this update request will stop batching and then start tracking.
|
||||
mRequestQueues[REQUEST_SESSION].push(new UpdateTrackingOptionsRequest(*this));
|
||||
if (sMode == SESSION_MODE_ON_FIX) {
|
||||
mLocationAPI->updateTrackingOptions(trackingSession, options);
|
||||
} else {
|
||||
// stop batching
|
||||
// batchingSession will be removed from mSessionBiDict soon,
|
||||
// so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
|
||||
mLocationAPI->stopBatching(batchingSession);
|
||||
batchingSession = 0;
|
||||
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
|
||||
|
||||
// start tracking
|
||||
trackingSession = mLocationAPI->startTracking(options);
|
||||
LOC_LOGI("%s:%d] start new session: %d",
|
||||
__FUNCTION__, __LINE__, trackingSession);
|
||||
}
|
||||
} else {
|
||||
// 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);
|
||||
switch (sessionMode) {
|
||||
case SESSION_MODE_ON_FULL:
|
||||
batchOptions.batchingMode = BATCHING_MODE_ROUTINE;
|
||||
break;
|
||||
case SESSION_MODE_ON_TRIP_COMPLETED:
|
||||
batchOptions.batchingMode = BATCHING_MODE_TRIP;
|
||||
break;
|
||||
default:
|
||||
batchOptions.batchingMode = BATCHING_MODE_NO_AUTO_REPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sMode == SESSION_MODE_ON_FIX) {
|
||||
// stop tracking
|
||||
// trackingSession will be removed from mSessionBiDict soon,
|
||||
// so we don't need to add a new request to mRequestQueues[REQUEST_SESSION].
|
||||
mLocationAPI->stopTracking(trackingSession);
|
||||
trackingSession = 0;
|
||||
|
||||
// Populate location option values
|
||||
batchOptions.minDistance = options.minDistance;
|
||||
batchOptions.minInterval = options.minInterval;
|
||||
batchOptions.mode = options.mode;
|
||||
|
||||
// start batching
|
||||
batchingSession = mLocationAPI->startBatching(batchOptions);
|
||||
LOC_LOGI("%s:%d] start new session: %d",
|
||||
__FUNCTION__, __LINE__, batchingSession);
|
||||
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
|
||||
} else {
|
||||
mLocationAPI->updateBatchingOptions(batchingSession, batchOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t session = ((sessionMode != SESSION_MODE_ON_FIX) ?
|
||||
batchingSession : trackingSession);
|
||||
|
||||
entity.trackingSession = trackingSession;
|
||||
entity.batchingSession = batchingSession;
|
||||
entity.sessionMode = sessionMode;
|
||||
// remove the old values from mSessionBiDict before we add a new one.
|
||||
mSessionBiDict.rmById(id);
|
||||
mSessionBiDict.set(id, session, entity);
|
||||
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
} else {
|
||||
retVal = LOCATION_ERROR_ID_UNKNOWN;
|
||||
LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIClientBase::locAPIGetBatchedLocations(uint32_t id, size_t count)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
if (mSessionBiDict.hasId(id)) {
|
||||
SessionEntity entity = mSessionBiDict.getExtById(id);
|
||||
if (entity.sessionMode != SESSION_MODE_ON_FIX) {
|
||||
uint32_t batchingSession = entity.batchingSession;
|
||||
mRequestQueues[REQUEST_SESSION].push(new GetBatchedLocationsRequest(*this));
|
||||
mLocationAPI->getBatchedLocations(batchingSession, count);
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] Unsupported for session id: %d, mode is SESSION_MODE_ON_FIX",
|
||||
__FUNCTION__, __LINE__, id);
|
||||
retVal = LOCATION_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
retVal = LOCATION_ERROR_ID_UNKNOWN;
|
||||
LOC_LOGd("unknown session id: %d, might flush() a stopped session", id);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint32_t LocationAPIClientBase::locAPIAddGeofences(
|
||||
size_t count, uint32_t* ids, GeofenceOption* options, GeofenceInfo* data)
|
||||
{
|
||||
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
if (mRequestQueues[REQUEST_GEOFENCE].getSession() != GEOFENCE_SESSION_ID) {
|
||||
mRequestQueues[REQUEST_GEOFENCE].reset(GEOFENCE_SESSION_ID);
|
||||
}
|
||||
uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
|
||||
if (sessions) {
|
||||
LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
|
||||
mRequestQueues[REQUEST_GEOFENCE].push(new AddGeofencesRequest(*this));
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
|
||||
}
|
||||
retVal = LOCATION_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIRemoveGeofences(size_t count, uint32_t* ids)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
if (sessions == NULL) {
|
||||
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||
BiDict<GeofenceBreachTypeMask>* removedGeofenceBiDict =
|
||||
new BiDict<GeofenceBreachTypeMask>();
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||
if (sessions[j] > 0) {
|
||||
GeofenceBreachTypeMask type = mGeofenceBiDict.getExtBySession(sessions[j]);
|
||||
mGeofenceBiDict.rmBySession(sessions[j]);
|
||||
removedGeofenceBiDict->set(ids[i], sessions[j], type);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
mRequestQueues[REQUEST_GEOFENCE].push(new RemoveGeofencesRequest(*this,
|
||||
removedGeofenceBiDict));
|
||||
mLocationAPI->removeGeofences(j, sessions);
|
||||
} else {
|
||||
delete(removedGeofenceBiDict);
|
||||
}
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||
}
|
||||
|
||||
free(sessions);
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIModifyGeofences(
|
||||
size_t count, uint32_t* ids, GeofenceOption* options)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
if (sessions == NULL) {
|
||||
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||
if (sessions[j] > 0) {
|
||||
mGeofenceBiDict.set(ids[i], sessions[j], options[i].breachTypeMask);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
mRequestQueues[REQUEST_GEOFENCE].push(new ModifyGeofencesRequest(*this));
|
||||
mLocationAPI->modifyGeofences(j, sessions, options);
|
||||
}
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||
}
|
||||
|
||||
free(sessions);
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIPauseGeofences(size_t count, uint32_t* ids)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
if (sessions == NULL) {
|
||||
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||
if (sessions[j] > 0) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
mRequestQueues[REQUEST_GEOFENCE].push(new PauseGeofencesRequest(*this));
|
||||
mLocationAPI->pauseGeofences(j, sessions);
|
||||
}
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||
}
|
||||
|
||||
free(sessions);
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIResumeGeofences(
|
||||
size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t* sessions = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
if (sessions == NULL) {
|
||||
LOC_LOGE("%s:%d] Failed to allocate %zu bytes !",
|
||||
__FUNCTION__, __LINE__, sizeof(uint32_t) * count);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sessions[j] = mGeofenceBiDict.getSession(ids[i]);
|
||||
if (sessions[j] > 0) {
|
||||
if (mask) {
|
||||
mGeofenceBiDict.set(ids[i], sessions[j], mask[i]);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
mRequestQueues[REQUEST_GEOFENCE].push(new ResumeGeofencesRequest(*this));
|
||||
mLocationAPI->resumeGeofences(j, sessions);
|
||||
}
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__,
|
||||
mRequestQueues[REQUEST_GEOFENCE].getSession());
|
||||
}
|
||||
|
||||
free(sessions);
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIRemoveAllGeofences()
|
||||
{
|
||||
std::vector<uint32_t> idsVec = mGeofenceBiDict.getAllIds();
|
||||
if (idsVec.size() > 0) {
|
||||
locAPIRemoveGeofences(idsVec.size(), &idsVec[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mLocationAPI) {
|
||||
uint32_t session = id;
|
||||
mLocationAPI->gnssNiResponse(id, response);
|
||||
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
|
||||
mRequestQueues[REQUEST_NIRESPONSE].reset(session);
|
||||
mRequestQueues[REQUEST_NIRESPONSE].push(new GnssNiResponseRequest(*this));
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::beforeGeofenceBreachCb(
|
||||
GeofenceBreachNotification geofenceBreachNotification)
|
||||
{
|
||||
uint32_t* ids = (uint32_t*)malloc(sizeof(uint32_t) * geofenceBreachNotification.count);
|
||||
uint32_t* backup = geofenceBreachNotification.ids;
|
||||
size_t n = geofenceBreachNotification.count;
|
||||
geofenceBreachCallback genfenceCallback = nullptr;
|
||||
|
||||
if (ids == NULL) {
|
||||
LOC_LOGE("%s:%d] Failed to alloc %zu bytes",
|
||||
__FUNCTION__, __LINE__,
|
||||
sizeof(uint32_t) * geofenceBreachNotification.count);
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mGeofenceBreachCallback != nullptr) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
uint32_t id = mGeofenceBiDict.getId(geofenceBreachNotification.ids[i]);
|
||||
GeofenceBreachTypeMask type =
|
||||
mGeofenceBiDict.getExtBySession(geofenceBreachNotification.ids[i]);
|
||||
// if type == 0, we will not head into the fllowing block anyway.
|
||||
// so we don't need to check id and type
|
||||
if ((geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER &&
|
||||
(type & GEOFENCE_BREACH_ENTER_BIT)) ||
|
||||
(geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT &&
|
||||
(type & GEOFENCE_BREACH_EXIT_BIT))
|
||||
) {
|
||||
ids[count] = id;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
geofenceBreachNotification.count = count;
|
||||
geofenceBreachNotification.ids = ids;
|
||||
|
||||
genfenceCallback = mGeofenceBreachCallback;
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
if (genfenceCallback != nullptr) {
|
||||
genfenceCallback(geofenceBreachNotification);
|
||||
}
|
||||
|
||||
// restore ids
|
||||
geofenceBreachNotification.ids = backup;
|
||||
geofenceBreachNotification.count = n;
|
||||
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) {
|
||||
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
|
||||
} else {
|
||||
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, error, id);
|
||||
}
|
||||
LocationAPIRequest* request = getRequestBySession(id);
|
||||
if (request) {
|
||||
request->onResponse(error, id);
|
||||
delete request;
|
||||
}
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::onCollectiveResponseCb(
|
||||
size_t count, LocationError* errors, uint32_t* ids)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (errors[i] != LOCATION_ERROR_SUCCESS) {
|
||||
LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||
} else {
|
||||
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
|
||||
}
|
||||
}
|
||||
LocationAPIRequest* request = nullptr;
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mRequestQueues[REQUEST_GEOFENCE].getSession() == GEOFENCE_SESSION_ID) {
|
||||
request = mRequestQueues[REQUEST_GEOFENCE].pop();
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
if (request) {
|
||||
request->onCollectiveResponse(count, errors, ids);
|
||||
delete request;
|
||||
}
|
||||
}
|
||||
|
||||
void LocationAPIClientBase::removeSession(uint32_t session) {
|
||||
if (mSessionBiDict.hasSession(session)) {
|
||||
mSessionBiDict.rmBySession(session);
|
||||
}
|
||||
}
|
||||
|
||||
LocationAPIRequest* LocationAPIClientBase::getRequestBySession(uint32_t session)
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
LocationAPIRequest* request = nullptr;
|
||||
for (int i = 0; i < REQUEST_MAX; i++) {
|
||||
if (i != REQUEST_GEOFENCE &&
|
||||
i != REQUEST_SESSION &&
|
||||
mRequestQueues[i].getSession() == session) {
|
||||
request = mRequestQueues[i].pop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (request == nullptr) {
|
||||
// Can't find a request with correct session,
|
||||
// try to find it from mSessionBiDict
|
||||
if (mSessionBiDict.hasSession(session)) {
|
||||
request = mRequestQueues[REQUEST_SESSION].pop();
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return request;
|
||||
}
|
592
gps/location/LocationAPIClientBase.h
Normal file
592
gps/location/LocationAPIClientBase.h
Normal file
@@ -0,0 +1,592 @@
|
||||
/* Copyright (c) 2017,2020-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.
|
||||
*/
|
||||
|
||||
#ifndef LOCATION_API_CLINET_BASE_H
|
||||
#define LOCATION_API_CLINET_BASE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
|
||||
#include "LocationAPI.h"
|
||||
#include <loc_pla.h>
|
||||
#include <log_util.h>
|
||||
|
||||
enum SESSION_MODE {
|
||||
SESSION_MODE_NONE = 0,
|
||||
SESSION_MODE_ON_FULL,
|
||||
SESSION_MODE_ON_FIX,
|
||||
SESSION_MODE_ON_TRIP_COMPLETED
|
||||
};
|
||||
|
||||
enum REQUEST_TYPE {
|
||||
REQUEST_TRACKING = 0,
|
||||
REQUEST_SESSION,
|
||||
REQUEST_GEOFENCE,
|
||||
REQUEST_NIRESPONSE,
|
||||
REQUEST_MAX,
|
||||
};
|
||||
|
||||
enum CTRL_REQUEST_TYPE {
|
||||
CTRL_REQUEST_DELETEAIDINGDATA = 0,
|
||||
CTRL_REQUEST_CONTROL,
|
||||
CTRL_REQUEST_CONFIG_UPDATE,
|
||||
CTRL_REQUEST_CONFIG_GET,
|
||||
CTRL_REQUEST_MAX,
|
||||
};
|
||||
|
||||
class LocationAPIClientBase;
|
||||
|
||||
class LocationAPIRequest {
|
||||
public:
|
||||
LocationAPIRequest() {}
|
||||
virtual ~LocationAPIRequest() {}
|
||||
virtual void onResponse(LocationError /*error*/, uint32_t /*id*/) {}
|
||||
virtual void onCollectiveResponse(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
};
|
||||
|
||||
class RequestQueue {
|
||||
public:
|
||||
RequestQueue(): mSession(0), mSessionArrayPtr(nullptr) {
|
||||
}
|
||||
virtual ~RequestQueue() {
|
||||
reset((uint32_t)0);
|
||||
}
|
||||
void inline setSession(uint32_t session) { mSession = session; }
|
||||
void inline setSessionArrayPtr(uint32_t* ptr) { mSessionArrayPtr = ptr; }
|
||||
void reset(uint32_t session) {
|
||||
LocationAPIRequest* request = nullptr;
|
||||
while (!mQueue.empty()) {
|
||||
request = mQueue.front();
|
||||
mQueue.pop();
|
||||
delete request;
|
||||
}
|
||||
mSession = session;
|
||||
}
|
||||
void reset(uint32_t* sessionArrayPtr) {
|
||||
reset((uint32_t)0);
|
||||
mSessionArrayPtr = sessionArrayPtr;
|
||||
}
|
||||
void push(LocationAPIRequest* request) {
|
||||
mQueue.push(request);
|
||||
}
|
||||
LocationAPIRequest* pop() {
|
||||
LocationAPIRequest* request = nullptr;
|
||||
if (!mQueue.empty()) {
|
||||
request = mQueue.front();
|
||||
mQueue.pop();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
uint32_t getSession() { return mSession; }
|
||||
uint32_t* getSessionArrayPtr() { return mSessionArrayPtr; }
|
||||
private:
|
||||
uint32_t mSession;
|
||||
uint32_t* mSessionArrayPtr;
|
||||
std::queue<LocationAPIRequest*> mQueue;
|
||||
};
|
||||
|
||||
class LocationAPIControlClient {
|
||||
public:
|
||||
LocationAPIControlClient();
|
||||
virtual ~LocationAPIControlClient();
|
||||
LocationAPIControlClient(const LocationAPIControlClient&) = delete;
|
||||
LocationAPIControlClient& operator=(const LocationAPIControlClient&) = delete;
|
||||
|
||||
LocationAPIRequest* getRequestBySession(uint32_t session);
|
||||
LocationAPIRequest* getRequestBySessionArrayPtr(uint32_t* sessionArrayPtr);
|
||||
|
||||
// LocationControlAPI
|
||||
uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
|
||||
uint32_t locAPIEnable(LocationTechnologyType techType);
|
||||
void locAPIDisable();
|
||||
uint32_t locAPIGnssUpdateConfig(GnssConfig config);
|
||||
uint32_t locAPIGnssGetConfig(GnssConfigFlagsMask config);
|
||||
inline LocationControlAPI* getControlAPI() { return mLocationControlAPI; }
|
||||
|
||||
// callbacks
|
||||
void onCtrlResponseCb(LocationError error, uint32_t id);
|
||||
void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
|
||||
|
||||
inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {}
|
||||
inline virtual void onEnableCb(LocationError /*error*/) {}
|
||||
inline virtual void onDisableCb(LocationError /*error*/) {}
|
||||
inline virtual void onGnssUpdateConfigCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
inline virtual void onGnssGetConfigCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
|
||||
class GnssDeleteAidingDataRequest : public LocationAPIRequest {
|
||||
public:
|
||||
GnssDeleteAidingDataRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onGnssDeleteAidingDataCb(error);
|
||||
}
|
||||
LocationAPIControlClient& mAPI;
|
||||
};
|
||||
|
||||
class EnableRequest : public LocationAPIRequest {
|
||||
public:
|
||||
EnableRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onEnableCb(error);
|
||||
}
|
||||
LocationAPIControlClient& mAPI;
|
||||
};
|
||||
|
||||
class DisableRequest : public LocationAPIRequest {
|
||||
public:
|
||||
DisableRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onDisableCb(error);
|
||||
}
|
||||
LocationAPIControlClient& mAPI;
|
||||
};
|
||||
|
||||
class GnssUpdateConfigRequest : public LocationAPIRequest {
|
||||
public:
|
||||
GnssUpdateConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
|
||||
mAPI.onGnssUpdateConfigCb(count, errors, ids);
|
||||
}
|
||||
LocationAPIControlClient& mAPI;
|
||||
};
|
||||
|
||||
class GnssGetConfigRequest : public LocationAPIRequest {
|
||||
public:
|
||||
GnssGetConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
|
||||
mAPI.onGnssGetConfigCb(count, errors, ids);
|
||||
}
|
||||
LocationAPIControlClient& mAPI;
|
||||
};
|
||||
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
LocationControlAPI* mLocationControlAPI;
|
||||
RequestQueue mRequestQueues[CTRL_REQUEST_MAX];
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
class LocationAPIClientBase {
|
||||
public:
|
||||
LocationAPIClientBase();
|
||||
LocationAPIClientBase(const LocationAPIClientBase&) = delete;
|
||||
LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;
|
||||
|
||||
void destroy();
|
||||
void onLocationApiDestroyCompleteCb();
|
||||
|
||||
void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
|
||||
void removeSession(uint32_t session);
|
||||
LocationAPIRequest* getRequestBySession(uint32_t session);
|
||||
|
||||
// LocationAPI
|
||||
uint32_t locAPIStartTracking(TrackingOptions& trackingOptions);
|
||||
void locAPIStopTracking();
|
||||
void locAPIUpdateTrackingOptions(TrackingOptions& trackingOptions);
|
||||
|
||||
int32_t locAPIGetBatchSize();
|
||||
uint32_t locAPIStartSession(
|
||||
uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
|
||||
uint32_t locAPIStopSession(uint32_t id);
|
||||
uint32_t locAPIUpdateSessionOptions(
|
||||
uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
|
||||
uint32_t locAPIGetBatchedLocations(uint32_t id, size_t count);
|
||||
|
||||
uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
|
||||
GeofenceOption* options, GeofenceInfo* data);
|
||||
void locAPIRemoveGeofences(size_t count, uint32_t* ids);
|
||||
void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
|
||||
void locAPIPauseGeofences(size_t count, uint32_t* ids);
|
||||
void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask);
|
||||
void locAPIRemoveAllGeofences();
|
||||
|
||||
void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response);
|
||||
|
||||
// callbacks
|
||||
void onResponseCb(LocationError error, uint32_t id);
|
||||
void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);
|
||||
|
||||
void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification);
|
||||
|
||||
inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
|
||||
inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
|
||||
inline virtual void onGnssDataCb(GnssDataNotification /*gnssDataNotification*/) {}
|
||||
inline virtual void onGnssMeasurementsCb(
|
||||
GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
|
||||
inline virtual void onGnssNHzMeasurementsCb(
|
||||
GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
|
||||
inline virtual void onTrackingCb(Location /*location*/) {}
|
||||
inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {}
|
||||
inline virtual void onStartTrackingCb(LocationError /*error*/) {}
|
||||
inline virtual void onStopTrackingCb(LocationError /*error*/) {}
|
||||
inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {}
|
||||
|
||||
inline virtual void onGnssLocationInfoCb(
|
||||
GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}
|
||||
|
||||
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*/) {}
|
||||
inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {}
|
||||
|
||||
inline virtual void onGeofenceBreachCb(
|
||||
GeofenceBreachNotification /*geofenceBreachNotification*/) {}
|
||||
inline virtual void onGeofenceStatusCb(
|
||||
GeofenceStatusNotification /*geofenceStatusNotification*/) {}
|
||||
inline virtual void onAddGeofencesCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
inline virtual void onRemoveGeofencesCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
inline virtual void onModifyGeofencesCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
inline virtual void onPauseGeofencesCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
inline virtual void onResumeGeofencesCb(
|
||||
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
|
||||
|
||||
inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
|
||||
inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}
|
||||
|
||||
inline virtual void onLocationSystemInfoCb(LocationSystemInfo /*locationSystemInfo*/) {}
|
||||
|
||||
protected:
|
||||
virtual ~LocationAPIClientBase();
|
||||
|
||||
private:
|
||||
// private inner classes
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint32_t trackingSession;
|
||||
uint32_t batchingSession;
|
||||
uint32_t sessionMode;
|
||||
} SessionEntity;
|
||||
|
||||
template<typename T>
|
||||
class BiDict {
|
||||
public:
|
||||
BiDict() {
|
||||
pthread_mutex_init(&mBiDictMutex, nullptr);
|
||||
}
|
||||
virtual ~BiDict() {
|
||||
pthread_mutex_destroy(&mBiDictMutex);
|
||||
}
|
||||
bool hasId(uint32_t id) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
bool ret = (mForwardMap.find(id) != mForwardMap.end());
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
bool hasSession(uint32_t session) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
bool ret = (mBackwardMap.find(session) != mBackwardMap.end());
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
void set(uint32_t id, uint32_t session, T& ext) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
mForwardMap[id] = session;
|
||||
mBackwardMap[session] = id;
|
||||
mExtMap[session] = ext;
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
}
|
||||
void clear() {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
mForwardMap.clear();
|
||||
mBackwardMap.clear();
|
||||
mExtMap.clear();
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
}
|
||||
void rmById(uint32_t id) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
mBackwardMap.erase(mForwardMap[id]);
|
||||
mExtMap.erase(mForwardMap[id]);
|
||||
mForwardMap.erase(id);
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
}
|
||||
void rmBySession(uint32_t session) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
mForwardMap.erase(mBackwardMap[session]);
|
||||
mBackwardMap.erase(session);
|
||||
mExtMap.erase(session);
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
}
|
||||
uint32_t getId(uint32_t session) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
uint32_t ret = 0;
|
||||
auto it = mBackwardMap.find(session);
|
||||
if (it != mBackwardMap.end()) {
|
||||
ret = it->second;
|
||||
}
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
uint32_t getSession(uint32_t id) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
uint32_t ret = 0;
|
||||
auto it = mForwardMap.find(id);
|
||||
if (it != mForwardMap.end()) {
|
||||
ret = it->second;
|
||||
}
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
T getExtById(uint32_t id) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
T ret;
|
||||
memset(&ret, 0, sizeof(T));
|
||||
uint32_t session = mForwardMap[id];
|
||||
if (session > 0) {
|
||||
auto it = mExtMap.find(session);
|
||||
if (it != mExtMap.end()) {
|
||||
ret = it->second;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
T getExtBySession(uint32_t session) {
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
T ret;
|
||||
memset(&ret, 0, sizeof(T));
|
||||
auto it = mExtMap.find(session);
|
||||
if (it != mExtMap.end()) {
|
||||
ret = it->second;
|
||||
}
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
std::vector<uint32_t> getAllIds() {
|
||||
std::vector<uint32_t> ret;
|
||||
pthread_mutex_lock(&mBiDictMutex);
|
||||
for (auto idToSessionPair : mForwardMap) {
|
||||
ret.push_back(idToSessionPair.first);
|
||||
}
|
||||
pthread_mutex_unlock(&mBiDictMutex);
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
pthread_mutex_t mBiDictMutex;
|
||||
// mForwarMap mapping id->session
|
||||
std::map<uint32_t, uint32_t> mForwardMap;
|
||||
// mBackwardMap mapping session->id
|
||||
std::map<uint32_t, uint32_t> mBackwardMap;
|
||||
// mExtMap mapping session->ext
|
||||
std::map<uint32_t, T> mExtMap;
|
||||
};
|
||||
|
||||
class StartTrackingRequest : public LocationAPIRequest {
|
||||
public:
|
||||
StartTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t id) {
|
||||
if (error != LOCATION_ERROR_SUCCESS) {
|
||||
mAPI.removeSession(id);
|
||||
}
|
||||
mAPI.onStartTrackingCb(error);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class StopTrackingRequest : public LocationAPIRequest {
|
||||
public:
|
||||
StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t id) {
|
||||
mAPI.onStopTrackingCb(error);
|
||||
if (error == LOCATION_ERROR_SUCCESS) {
|
||||
mAPI.removeSession(id);
|
||||
}
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class UpdateTrackingOptionsRequest : public LocationAPIRequest {
|
||||
public:
|
||||
UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onUpdateTrackingOptionsCb(error);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class StartBatchingRequest : public LocationAPIRequest {
|
||||
public:
|
||||
StartBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t id) {
|
||||
if (error != LOCATION_ERROR_SUCCESS) {
|
||||
mAPI.removeSession(id);
|
||||
}
|
||||
mAPI.onStartBatchingCb(error);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class StopBatchingRequest : public LocationAPIRequest {
|
||||
public:
|
||||
StopBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t id) {
|
||||
mAPI.onStopBatchingCb(error);
|
||||
if (error == LOCATION_ERROR_SUCCESS) {
|
||||
mAPI.removeSession(id);
|
||||
}
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class UpdateBatchingOptionsRequest : public LocationAPIRequest {
|
||||
public:
|
||||
UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onUpdateBatchingOptionsCb(error);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class GetBatchedLocationsRequest : public LocationAPIRequest {
|
||||
public:
|
||||
GetBatchedLocationsRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onGetBatchedLocationsCb(error);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class AddGeofencesRequest : public LocationAPIRequest {
|
||||
public:
|
||||
AddGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||
}
|
||||
LOC_LOGD("%s:]Returned geofence-id: %d in add geofence", __FUNCTION__, *ids);
|
||||
mAPI.onAddGeofencesCb(count, errors, ids);
|
||||
free(ids);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class RemoveGeofencesRequest : public LocationAPIRequest {
|
||||
public:
|
||||
RemoveGeofencesRequest(LocationAPIClientBase& API,
|
||||
BiDict<GeofenceBreachTypeMask>* removedGeofenceBiDict) :
|
||||
mAPI(API), mRemovedGeofenceBiDict(removedGeofenceBiDict) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||
if (nullptr != mRemovedGeofenceBiDict) {
|
||||
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ids[i] = mRemovedGeofenceBiDict->getId(sessions[i]);
|
||||
}
|
||||
LOC_LOGD("%s:]Returned geofence-id: %d in remove geofence", __FUNCTION__, *ids);
|
||||
mAPI.onRemoveGeofencesCb(count, errors, ids);
|
||||
free(ids);
|
||||
delete(mRemovedGeofenceBiDict);
|
||||
} else {
|
||||
LOC_LOGE("%s:%d] Unable to access removed geofences data.", __FUNCTION__, __LINE__);
|
||||
}
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
BiDict<GeofenceBreachTypeMask>* mRemovedGeofenceBiDict;
|
||||
};
|
||||
|
||||
class ModifyGeofencesRequest : public LocationAPIRequest {
|
||||
public:
|
||||
ModifyGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||
}
|
||||
mAPI.onModifyGeofencesCb(count, errors, ids);
|
||||
free(ids);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class PauseGeofencesRequest : public LocationAPIRequest {
|
||||
public:
|
||||
PauseGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||
}
|
||||
mAPI.onPauseGeofencesCb(count, errors, ids);
|
||||
free(ids);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class ResumeGeofencesRequest : public LocationAPIRequest {
|
||||
public:
|
||||
ResumeGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
|
||||
uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
|
||||
}
|
||||
mAPI.onResumeGeofencesCb(count, errors, ids);
|
||||
free(ids);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
class GnssNiResponseRequest : public LocationAPIRequest {
|
||||
public:
|
||||
GnssNiResponseRequest(LocationAPIClientBase& API) : mAPI(API) {}
|
||||
inline void onResponse(LocationError error, uint32_t /*id*/) {
|
||||
mAPI.onGnssNiResponseCb(error);
|
||||
}
|
||||
LocationAPIClientBase& mAPI;
|
||||
};
|
||||
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
|
||||
geofenceBreachCallback mGeofenceBreachCallback;
|
||||
batchingStatusCallback mBatchingStatusCallback;
|
||||
|
||||
LocationAPI* mLocationAPI;
|
||||
|
||||
RequestQueue mRequestQueues[REQUEST_MAX];
|
||||
BiDict<GeofenceBreachTypeMask> mGeofenceBiDict;
|
||||
BiDict<SessionEntity> mSessionBiDict;
|
||||
int32_t mBatchSize;
|
||||
bool mTracking;
|
||||
};
|
||||
|
||||
#endif /* LOCATION_API_CLINET_BASE_H */
|
2309
gps/location/LocationDataTypes.h
Normal file
2309
gps/location/LocationDataTypes.h
Normal file
File diff suppressed because it is too large
Load Diff
44
gps/location/Makefile.am
Normal file
44
gps/location/Makefile.am
Normal file
@@ -0,0 +1,44 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
AM_CFLAGS = \
|
||||
-I./ \
|
||||
-I../utils \
|
||||
$(LOCPLA_CFLAGS) \
|
||||
$(GPSUTILS_CFLAGS) \
|
||||
-std=c++11
|
||||
|
||||
liblocation_api_la_SOURCES = \
|
||||
LocationAPI.cpp \
|
||||
LocationAPIClientBase.cpp
|
||||
|
||||
if USE_EXTERNAL_AP
|
||||
AM_CFLAGS += -DFEATURE_EXTERNAL_AP
|
||||
endif
|
||||
|
||||
if USE_GLIB
|
||||
liblocation_api_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
|
||||
liblocation_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
|
||||
liblocation_api_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||
else
|
||||
liblocation_api_la_CFLAGS = $(AM_CFLAGS)
|
||||
liblocation_api_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
|
||||
liblocation_api_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||
endif
|
||||
|
||||
liblocation_api_la_LIBADD = -lstdc++ -ldl $(GPSUTILS_LIBS)
|
||||
|
||||
library_include_HEADERS = \
|
||||
LocationAPI.h \
|
||||
LocationAPIClientBase.h \
|
||||
location_interface.h \
|
||||
LocationDataTypes.h \
|
||||
ILocationAPI.h
|
||||
|
||||
#Create and Install libraries
|
||||
lib_LTLIBRARIES = liblocation_api.la
|
||||
|
||||
library_includedir = $(pkgincludedir)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = location-api.pc
|
||||
EXTRA_DIST = $(pkgconfig_DATA)
|
95
gps/location/configure.ac
Normal file
95
gps/location/configure.ac
Normal file
@@ -0,0 +1,95 @@
|
||||
# configure.ac -- Autoconf script for gps location-api-iface
|
||||
#
|
||||
# Process this file with autoconf to produce a configure script
|
||||
|
||||
# Requires autoconf tool later than 2.61
|
||||
AC_PREREQ(2.61)
|
||||
# Initialize the gps location-api-iface package version 1.0.0
|
||||
AC_INIT([location-api-iface],1.0.0)
|
||||
# Does not strictly follow GNU Coding standards
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
# Disables auto rebuilding of configure, Makefile.ins
|
||||
AM_MAINTAINER_MODE
|
||||
# Verifies the --srcdir is correct by checking for the path
|
||||
AC_CONFIG_SRCDIR([location-api.pc.in])
|
||||
# defines some macros variable to be included by source
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
# Checks for libraries.
|
||||
PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
|
||||
AC_SUBST([GPSUTILS_CFLAGS])
|
||||
AC_SUBST([GPSUTILS_LIBS])
|
||||
|
||||
AC_ARG_WITH([core_includes],
|
||||
AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
|
||||
[Specify the location of the core headers]),
|
||||
[core_incdir=$withval],
|
||||
with_core_includes=no)
|
||||
|
||||
if test "x$with_core_includes" != "xno"; then
|
||||
CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([locpla_includes],
|
||||
AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
|
||||
[Specify the path to locpla-includes in loc-pla_git.bb]),
|
||||
[locpla_incdir=$withval],
|
||||
with_locpla_includes=no)
|
||||
|
||||
if test "x${with_locpla_includes}" != "xno"; then
|
||||
AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
|
||||
fi
|
||||
|
||||
AC_SUBST([CPPFLAGS])
|
||||
|
||||
AC_ARG_WITH([glib],
|
||||
AC_HELP_STRING([--with-glib],
|
||||
[enable glib, building HLOS systems which use glib]))
|
||||
|
||||
if (test "x${with_glib}" = "xyes"); then
|
||||
AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
|
||||
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
|
||||
AC_MSG_ERROR(GThread >= 2.16 is required))
|
||||
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
|
||||
AC_MSG_ERROR(GLib >= 2.16 is required))
|
||||
GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
|
||||
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
|
||||
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
|
||||
|
||||
# External AP
|
||||
AC_ARG_WITH([external_ap],
|
||||
AC_HELP_STRING([--with-external_ap=@<:@dir@:>@],
|
||||
[Using External Application Processor]),
|
||||
[],
|
||||
with_external_ap=no)
|
||||
|
||||
if test "x$with_external_ap" != "xno"; then
|
||||
CPPFLAGS="${CPPFLAGS} -DFEATURE_EXTERNAL_AP"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(USE_EXTERNAL_AP, test "x${with_external_ap}" = "xyes")
|
||||
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
location-api.pc \
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
10
gps/location/location-api.pc.in
Normal file
10
gps/location/location-api.pc.in
Normal file
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: location-api
|
||||
Description: Location API
|
||||
Version: @VERSION
|
||||
Libs: -L${libdir} -llocation_api
|
||||
Cflags: -I${includedir}/location-api
|
152
gps/location/location_interface.h
Normal file
152
gps/location/location_interface.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* Copyright (c) 2017-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.
|
||||
*/
|
||||
|
||||
#ifndef LOCATION_INTERFACE_H
|
||||
#define LOCATION_INTERFACE_H
|
||||
|
||||
#include <LocationAPI.h>
|
||||
#include <gps_extended_c.h>
|
||||
#include <functional>
|
||||
|
||||
/* Used for callback to deliver GNSS energy consumed */
|
||||
/** @fn
|
||||
@brief Used by query API that retrieves energy consumed by
|
||||
modem GNSS engine.
|
||||
|
||||
@param gnssEnergyConsumedFromFirstBoot:
|
||||
Energy consumed by the GNSS engine since the first bootup
|
||||
in units of 0.1 milli watt seconds.
|
||||
A value of 0xffffffffffffffff indicates an invalid reading.
|
||||
*/
|
||||
typedef std::function<void(
|
||||
uint64_t gnssEnergyConsumedFromFirstBoot
|
||||
)> GnssEnergyConsumedCallback;
|
||||
|
||||
typedef void (*removeClientCompleteCallback)(LocationAPI* client);
|
||||
|
||||
struct GnssInterface {
|
||||
size_t size;
|
||||
void (*initialize)(void);
|
||||
void (*deinitialize)(void);
|
||||
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||
void (*requestCapabilities)(LocationAPI* client);
|
||||
uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
|
||||
void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
|
||||
void (*stopTracking)(LocationAPI* client, uint32_t id);
|
||||
void (*gnssNiResponse)(LocationAPI* client, uint32_t id, GnssNiResponse response);
|
||||
void (*setControlCallbacks)(LocationControlCallbacks& controlCallbacks);
|
||||
uint32_t (*enable)(LocationTechnologyType techType);
|
||||
void (*disable)(uint32_t id);
|
||||
uint32_t* (*gnssUpdateConfig)(const GnssConfig& config);
|
||||
uint32_t* (*gnssGetConfig)(GnssConfigFlagsMask config);
|
||||
void (*gnssUpdateSvTypeConfig)(GnssSvTypeConfig& config);
|
||||
void (*gnssGetSvTypeConfig)(GnssSvTypeConfigCallback& callback);
|
||||
void (*gnssResetSvTypeConfig)();
|
||||
uint32_t (*gnssDeleteAidingData)(GnssAidingData& data);
|
||||
void (*gnssUpdateXtraThrottle)(const bool enabled);
|
||||
void (*injectLocation)(double latitude, double longitude, float accuracy);
|
||||
void (*injectTime)(int64_t time, int64_t timeReference, int32_t uncertainty);
|
||||
void (*agpsInit)(const AgpsCbInfo& cbInfo);
|
||||
void (*agpsDataConnOpen)(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
|
||||
void (*agpsDataConnClosed)(AGpsExtType agpsType);
|
||||
void (*agpsDataConnFailed)(AGpsExtType agpsType);
|
||||
void (*getDebugReport)(GnssDebugReport& report);
|
||||
void (*updateConnectionStatus)(bool connected, int8_t type, bool roaming,
|
||||
NetworkHandle networkHandle, std::string& apn);
|
||||
void (*odcpiInit)(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
|
||||
void (*odcpiInject)(const Location& location);
|
||||
void (*blockCPI)(double latitude, double longitude, float accuracy,
|
||||
int blockDurationMsec, double latLonDiffThreshold);
|
||||
void (*getGnssEnergyConsumed)(GnssEnergyConsumedCallback energyConsumedCb);
|
||||
void (*enableNfwLocationAccess)(std::vector<std::string>& enabledNfws);
|
||||
void (*nfwInit)(const NfwCbInfo& cbInfo);
|
||||
void (*getPowerStateChanges)(std::function<void(bool)> powerStateCb);
|
||||
void (*injectLocationExt)(const GnssLocationInfoNotification &locationInfo);
|
||||
void (*updateBatteryStatus)(bool charging);
|
||||
void (*updateSystemPowerState)(PowerStateType systemPowerState);
|
||||
uint32_t (*setConstrainedTunc) (bool enable, float tuncConstraint, uint32_t energyBudget);
|
||||
uint32_t (*setPositionAssistedClockEstimator) (bool enable);
|
||||
uint32_t (*gnssUpdateSvConfig)(const GnssSvTypeConfig& constellationEnablementConfig,
|
||||
const GnssSvIdConfig& blacklistSvConfig);
|
||||
uint32_t (*configLeverArm)(const LeverArmConfigInfo& configInfo);
|
||||
bool (*measCorrInit)(const measCorrSetCapabilitiesCb setCapabilitiesCb);
|
||||
bool (*measCorrSetCorrections)(const GnssMeasurementCorrections gnssMeasCorr);
|
||||
void (*measCorrClose)();
|
||||
uint32_t (*antennaInfoInit)(const antennaInfoCb antennaInfoCallback);
|
||||
void (*antennaInfoClose) ();
|
||||
uint32_t (*configRobustLocation)(bool enable, bool enableForE911);
|
||||
uint32_t (*configMinGpsWeek)(uint16_t minGpsWeek);
|
||||
uint32_t (*configDeadReckoningEngineParams)(const DeadReckoningEngineConfig& dreConfig);
|
||||
void (*updateNTRIPGGAConsent)(bool consentAccepted);
|
||||
void (*enablePPENtripStream)(const GnssNtripConnectionParams& params, bool enableRTKEngine);
|
||||
void (*disablePPENtripStream)();
|
||||
uint32_t (*gnssUpdateSecondaryBandConfig)(const GnssSvTypeConfig& secondaryBandConfig);
|
||||
uint32_t (*gnssGetSecondaryBandConfig)();
|
||||
void (*resetNetworkInfo)();
|
||||
uint32_t (*configEngineRunState)(PositioningEngineMask engType,
|
||||
LocEngineRunState engState);
|
||||
uint32_t (*configOutputNmeaTypes)(GnssNmeaTypesMask enabledNmeaTypes);
|
||||
void (*powerIndicationInit)(const powerIndicationCb powerIndicationCallback);
|
||||
void (*powerIndicationRequest)();
|
||||
void (*setAddressRequestCb)(std::function<void(const Location&)> addressRequestCb);
|
||||
void (*injectLocationAndAddr)(const Location& location, const GnssCivicAddress& addr);
|
||||
uint32_t (*setOptInStatus)(bool userConsent);
|
||||
};
|
||||
|
||||
struct BatchingInterface {
|
||||
size_t size;
|
||||
void (*initialize)(void);
|
||||
void (*deinitialize)(void);
|
||||
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||
void (*requestCapabilities)(LocationAPI* client);
|
||||
uint32_t (*startBatching)(LocationAPI* client, BatchingOptions&);
|
||||
void (*stopBatching)(LocationAPI* client, uint32_t id);
|
||||
void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, BatchingOptions&);
|
||||
void (*getBatchedLocations)(LocationAPI* client, uint32_t id, size_t count);
|
||||
void (*updateSystemPowerState)(PowerStateType systemPowerState);
|
||||
};
|
||||
|
||||
struct GeofenceInterface {
|
||||
size_t size;
|
||||
void (*initialize)(void);
|
||||
void (*deinitialize)(void);
|
||||
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
|
||||
void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
|
||||
void (*requestCapabilities)(LocationAPI* client);
|
||||
uint32_t* (*addGeofences)(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
|
||||
void (*removeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||
void (*modifyGeofences)(LocationAPI* client, size_t count, uint32_t* ids,
|
||||
GeofenceOption* options);
|
||||
void (*pauseGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||
void (*resumeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
|
||||
void (*updateSystemPowerState)(PowerStateType systemPowerState);
|
||||
};
|
||||
|
||||
#endif /* LOCATION_INTERFACE_H */
|
Reference in New Issue
Block a user