diff --git a/android/Gnss.cpp b/android/Gnss.cpp index d31a18bb..36598236 100644 --- a/android/Gnss.cpp +++ b/android/Gnss.cpp @@ -380,10 +380,17 @@ Return Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode, uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs, - bool /*lowPowerMode*/) { + bool lowPowerMode) { ENTRY_LOG_CALLFLOW(); - return setPositionMode(mode, recurrence, minIntervalMs, - preferredAccuracyMeters, preferredTimeMs); + bool retVal = false; + GnssAPIClient* api = getApi(); + if (api) { + GnssPowerMode powerMode = lowPowerMode? + GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2; + retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, + preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs); + } + return retVal; } Return> Gnss::getExtensionGnssMeasurement_1_1() { diff --git a/android/GnssMeasurement.cpp b/android/GnssMeasurement.cpp index 2578a853..ffe5c524 100644 --- a/android/GnssMeasurement.cpp +++ b/android/GnssMeasurement.cpp @@ -100,7 +100,7 @@ Return GnssMeasurement::close() { // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow. Return GnssMeasurement::setCallback_1_1( - const sp& callback, bool /*enableFullTracking*/) { + const sp& callback, bool enableFullTracking) { Return ret = IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC; @@ -113,7 +113,7 @@ Return GnssMeasurement::setCallback_1_1( LOC_LOGE("%s]: callback is nullptr", __FUNCTION__); return ret; } - if (mApi == nullptr) { + if (nullptr == mApi) { LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); return ret; } @@ -121,7 +121,10 @@ Return GnssMeasurement::setCallback_1_1( mGnssMeasurementCbIface_1_1 = callback; mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0); - return mApi->measurementSetCallback_1_1(callback); + GnssPowerMode powerMode = enableFullTracking? + GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2; + + return mApi->measurementSetCallback_1_1(callback, powerMode); } } // namespace implementation diff --git a/android/location_api/GnssAPIClient.cpp b/android/location_api/GnssAPIClient.cpp index 4fcc8683..65e8b91b 100644 --- a/android/location_api/GnssAPIClient.cpp +++ b/android/location_api/GnssAPIClient.cpp @@ -62,11 +62,11 @@ GnssAPIClient::GnssAPIClient(const sp& gpsCb, LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); // set default LocationOptions. - memset(&mLocationOptions, 0, sizeof(LocationOptions)); - mLocationOptions.size = sizeof(LocationOptions); - mLocationOptions.minInterval = 1000; - mLocationOptions.minDistance = 0; - mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; + memset(&mTrackingOptions, 0, sizeof(TrackingOptions)); + mTrackingOptions.size = sizeof(TrackingOptions); + mTrackingOptions.minInterval = 1000; + mTrackingOptions.minDistance = 0; + mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE; gnssUpdateCallbacks(gpsCb, niCb); } @@ -142,7 +142,7 @@ bool GnssAPIClient::gnssStart() { LOC_LOGD("%s]: ()", __FUNCTION__); bool retVal = true; - locAPIStartTracking(mLocationOptions); + locAPIStartTracking(mTrackingOptions); return retVal; } @@ -156,26 +156,32 @@ bool GnssAPIClient::gnssStop() bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, - uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs) + uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs, + GnssPowerMode powerMode, uint32_t timeBetweenMeasurement) { - LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__, - (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs); + LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__, + (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, + preferredTimeMs, (int)powerMode, timeBetweenMeasurement); bool retVal = true; - memset(&mLocationOptions, 0, sizeof(LocationOptions)); - mLocationOptions.size = sizeof(LocationOptions); - mLocationOptions.minInterval = minIntervalMs; - mLocationOptions.minDistance = preferredAccuracyMeters; + memset(&mTrackingOptions, 0, sizeof(TrackingOptions)); + mTrackingOptions.size = sizeof(TrackingOptions); + mTrackingOptions.minInterval = minIntervalMs; + mTrackingOptions.minDistance = preferredAccuracyMeters; if (mode == IGnss::GnssPositionMode::STANDALONE) - mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; + mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE; else if (mode == IGnss::GnssPositionMode::MS_BASED) - mLocationOptions.mode = GNSS_SUPL_MODE_MSB; + mTrackingOptions.mode = GNSS_SUPL_MODE_MSB; else if (mode == IGnss::GnssPositionMode::MS_ASSISTED) - mLocationOptions.mode = GNSS_SUPL_MODE_MSA; + mTrackingOptions.mode = GNSS_SUPL_MODE_MSA; else { LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode); retVal = false; } - locAPIUpdateTrackingOptions(mLocationOptions); + if (GNSS_POWER_MODE_INVALID != powerMode) { + mTrackingOptions.powerMode = powerMode; + mTrackingOptions.tbm = timeBetweenMeasurement; + } + locAPIUpdateTrackingOptions(mTrackingOptions); return retVal; } diff --git a/android/location_api/GnssAPIClient.h b/android/location_api/GnssAPIClient.h index 1589f396..82f8fbfc 100644 --- a/android/location_api/GnssAPIClient.h +++ b/android/location_api/GnssAPIClient.h @@ -63,7 +63,9 @@ public: V1_0::IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, - uint32_t preferredTimeMs); + uint32_t preferredTimeMs, + GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID, + uint32_t timeBetweenMeasurement = 0); // for GpsNiInterface void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse); @@ -96,8 +98,7 @@ private: LocationAPIControlClient* mControlClient; LocationCapabilitiesMask mLocationCapabilitiesMask; bool mLocationCapabilitiesCached; - - LocationOptions mLocationOptions; + TrackingOptions mTrackingOptions; }; } // namespace implementation diff --git a/android/location_api/MeasurementAPIClient.cpp b/android/location_api/MeasurementAPIClient.cpp index f1a5d012..7017e523 100644 --- a/android/location_api/MeasurementAPIClient.cpp +++ b/android/location_api/MeasurementAPIClient.cpp @@ -80,19 +80,23 @@ MeasurementAPIClient::measurementSetCallback(const sp -MeasurementAPIClient::measurementSetCallback_1_1(const sp& callback) +MeasurementAPIClient::measurementSetCallback_1_1( + const sp& callback, + GnssPowerMode powerMode, uint32_t timeBetweenMeasurement) { - LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback); + LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)", + __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement); mMutex.lock(); mGnssMeasurementCbIface_1_1 = callback; mMutex.unlock(); - return startTracking(); + return startTracking(powerMode, timeBetweenMeasurement); } Return -MeasurementAPIClient::startTracking() +MeasurementAPIClient::startTracking( + GnssPowerMode powerMode, uint32_t timeBetweenMeasurement) { LocationCallbacks locationCallbacks; memset(&locationCallbacks, 0, sizeof(LocationCallbacks)); @@ -116,15 +120,20 @@ MeasurementAPIClient::startTracking() } locAPISetCallbacks(locationCallbacks); - LocationOptions options; - memset(&options, 0, sizeof(LocationOptions)); - options.size = sizeof(LocationOptions); + + TrackingOptions options = {}; + memset(&options, 0, sizeof(TrackingOptions)); + options.size = sizeof(TrackingOptions); options.minInterval = 1000; options.mode = GNSS_SUPL_MODE_STANDALONE; + if (GNSS_POWER_MODE_INVALID != powerMode) { + options.powerMode = powerMode; + options.tbm = timeBetweenMeasurement; + } + mTracking = true; LOC_LOGD("%s]: start tracking session", __FUNCTION__); locAPIStartTracking(options); - return IGnssMeasurement::GnssMeasurementStatus::SUCCESS; } diff --git a/android/location_api/MeasurementAPIClient.h b/android/location_api/MeasurementAPIClient.h index 117ad542..38811c55 100644 --- a/android/location_api/MeasurementAPIClient.h +++ b/android/location_api/MeasurementAPIClient.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace android { namespace hardware { @@ -56,9 +57,13 @@ public: Return measurementSetCallback( const sp& callback); Return measurementSetCallback_1_1( - const sp& callback); + const sp& callback, + GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID, + uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS); void measurementClose(); - Return startTracking(); + Return startTracking( + GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID, + uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS); // callbacks we are interested in void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final; diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index 79cb25cb..9fcee128 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -51,6 +51,7 @@ inline bool operator !=(LocationSessionKey const& left, LocationSessionKey const return left.id != right.id || left.client != right.client; } typedef std::map LocationSessionMap; +typedef std::map TrackingOptionsMap; namespace loc_core { diff --git a/core/loc_core_log.cpp b/core/loc_core_log.cpp index 67d68f04..ddf18ec8 100644 --- a/core/loc_core_log.cpp +++ b/core/loc_core_log.cpp @@ -39,14 +39,17 @@ void LocPosMode::logv() const { LOC_LOGV ("Position mode: %s\n Position recurrence: %s\n " "min interval: %d\n preferred accuracy: %d\n " - "preferred time: %d\n credentials: %s provider: %s", + "preferred time: %d\n credentials: %s provider: %s \n " + "power mode: %d\n tbm %d", loc_get_position_mode_name(mode), loc_get_position_recurrence_name(recurrence), min_interval, preferred_accuracy, preferred_time, credentials, - provider); + provider, + powerMode, + timeBetweenMeasurements); } /* GPS status names */ diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index cedd27b6..0bbc3f5c 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -175,10 +175,9 @@ GnssAdapter::setControlCallbacksCommand(LocationControlCallbacks& controlCallbac } void -GnssAdapter::convertOptions(LocPosMode& out, const LocationOptions& options) +GnssAdapter::convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions) { - LocPosMode locPosMode = {}; - switch (options.mode) { + switch (trackingOptions.mode) { case GNSS_SUPL_MODE_MSB: out.mode = LOC_POSITION_MODE_MS_BASED; break; @@ -190,7 +189,9 @@ GnssAdapter::convertOptions(LocPosMode& out, const LocationOptions& options) break; } out.share_position = true; - out.min_interval = options.minInterval; + out.min_interval = trackingOptions.minInterval; + out.powerMode = trackingOptions.powerMode; + out.timeBetweenMeasurements = trackingOptions.tbm; } void @@ -1901,17 +1902,26 @@ GnssAdapter::restartSessions() } // get the LocationOptions that has the smallest interval, which should be the active one - LocationOptions smallestIntervalOptions = {}; // size is zero until set for the first time + TrackingOptions smallestIntervalOptions = {}; // size is zero until set for the first time + TrackingOptions highestPowerTrackingOptions = {}; for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) { - if (0 == smallestIntervalOptions.size || //size of zero means we havent set it yet + // size of zero means we havent set it yet + if (0 == smallestIntervalOptions.size || it->second.minInterval < smallestIntervalOptions.minInterval) { smallestIntervalOptions = it->second; } + GnssPowerMode powerMode = it->second.powerMode; + // Size of zero means we havent set it yet + if (0 == highestPowerTrackingOptions.size || + (GNSS_POWER_MODE_INVALID != powerMode && + powerMode < highestPowerTrackingOptions.powerMode)) { + highestPowerTrackingOptions = it->second; + } } LocPosMode locPosMode = {}; - convertOptions(locPosMode, smallestIntervalOptions); - + highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions); + convertOptions(locPosMode, highestPowerTrackingOptions); mLocApi->startFix(locPosMode, new LocApiResponse(*getContext(), [] (LocationError err) {} )); @@ -2042,21 +2052,20 @@ GnssAdapter::isTrackingSession(LocationAPI* client, uint32_t sessionId) void GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId, - const LocationOptions& options) + const TrackingOptions& trackingOptions) { LocationSessionKey key(client, sessionId); - mTrackingSessions[key] = options; + mTrackingSessions[key] = trackingOptions; } void GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId) { LocationSessionKey key(client, sessionId); - auto it = mTrackingSessions.find(key); - if (it != mTrackingSessions.end()) { - mTrackingSessions.erase(it); + auto itr = mTrackingSessions.find(key); + if (itr != mTrackingSessions.end()) { + mTrackingSessions.erase(itr); } - } bool GnssAdapter::setUlpPositionMode(const LocPosMode& mode) { @@ -2120,41 +2129,54 @@ GnssAdapter::reportResponse(size_t count, LocationError* errs, uint32_t* ids) } uint32_t -GnssAdapter::startTrackingCommand(LocationAPI* client, LocationOptions& options) +GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options) { uint32_t sessionId = generateSessionId(); - LOC_LOGD("%s]: client %p id %u minInterval %u mode %u", - __func__, client, sessionId, options.minInterval, options.mode); + LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u powermode %u tbm %u", + __func__, client, sessionId, options.minInterval, options.minDistance, options.mode, + options.powerMode, options.tbm); struct MsgStartTracking : public LocMsg { GnssAdapter& mAdapter; LocApiBase& mApi; LocationAPI* mClient; uint32_t mSessionId; - LocationOptions mOptions; + mutable TrackingOptions mTrackingOptions; inline MsgStartTracking(GnssAdapter& adapter, LocApiBase& api, LocationAPI* client, uint32_t sessionId, - LocationOptions options) : + TrackingOptions trackingOptions) : LocMsg(), mAdapter(adapter), mApi(api), mClient(client), mSessionId(sessionId), - mOptions(options) {} + mTrackingOptions(trackingOptions) {} inline virtual void proc() const { LocationError err = LOCATION_ERROR_SUCCESS; if (!mAdapter.hasTrackingCallback(mClient) && !mAdapter.hasMeasurementsCallback(mClient)) { err = LOCATION_ERROR_CALLBACK_MISSING; - } else if (0 == mOptions.size) { + } else if (0 == mTrackingOptions.size) { err = LOCATION_ERROR_INVALID_PARAMETER; } else { + if (GNSS_POWER_MODE_INVALID != mTrackingOptions.powerMode && + !ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) { + LOC_LOGv("Ignoring power mode, feature not supported."); + mTrackingOptions.powerMode = GNSS_POWER_MODE_INVALID; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02) && + GNSS_POWER_MODE_M4 == mTrackingOptions.powerMode && + mTrackingOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) { + LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode", + mTrackingOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS); + mTrackingOptions.powerMode = GNSS_POWER_MODE_M2; + } // Api doesn't support multiple clients for time based tracking, so mutiplex bool reportToClientWithNoWait = - mAdapter.startTrackingMultiplex(mClient, mSessionId, mOptions); - mAdapter.saveTrackingSession(mClient, mSessionId, mOptions); + mAdapter.startTrackingMultiplex(mClient, mSessionId, mTrackingOptions); + mAdapter.saveTrackingSession(mClient, mSessionId, mTrackingOptions); if (reportToClientWithNoWait) { mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId); @@ -2170,25 +2192,43 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, LocationOptions& options) bool GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId, - const LocationOptions& options) + const TrackingOptions& options) { bool reportToClientWithNoWait = true; if (mTrackingSessions.empty()) { reportToClientWithNoWait = startTracking(client, sessionId, options); } else { - // get the LocationOptions that has the smallest interval, which should be the active one - LocationOptions smallestIntervalOptions = {}; // size is zero until set for the first time + // find the smallest interval and powerMode + TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time + GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID; for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) { - if (0 == smallestIntervalOptions.size || //size of zero means we havent set it yet - it->second.minInterval < smallestIntervalOptions.minInterval) { - smallestIntervalOptions = it->second; + // if not set or there is a new smallest interval, then set the new interval + if (0 == multiplexedOptions.size || + it->second.minInterval < multiplexedOptions.minInterval) { + multiplexedOptions = it->second; + } + // if session is not the one we are updating and either powerMode + // is not set or there is a new smallest powerMode, then set the new powerMode + if (GNSS_POWER_MODE_INVALID == multiplexedPowerMode || + it->second.powerMode < multiplexedPowerMode) { + multiplexedPowerMode = it->second.powerMode; } } - // if new session's minInterval is smaller than any in other sessions - if (options.minInterval < smallestIntervalOptions.minInterval) { - // restart time based tracking with new options - reportToClientWithNoWait = startTracking(client, sessionId, options); + bool updateOptions = false; + // if session we are starting has smaller interval then next smallest + if (options.minInterval < multiplexedOptions.minInterval) { + multiplexedOptions.minInterval = options.minInterval; + updateOptions = true; + } + // if session we are starting has smaller powerMode then next smallest + if (options.powerMode < multiplexedPowerMode) { + multiplexedOptions.powerMode = options.powerMode; + updateOptions = true; + } + if (updateOptions) { + // restart time based tracking with the newly updated options + reportToClientWithNoWait = startTracking(client, sessionId, multiplexedOptions); } } @@ -2197,12 +2237,12 @@ GnssAdapter::startTrackingMultiplex(LocationAPI* client, uint32_t sessionId, bool GnssAdapter::startTracking(LocationAPI* client, uint32_t sessionId, - const LocationOptions& options) + const TrackingOptions& trackingOptions) { bool reportToClientWithNoWait = true; LocPosMode locPosMode = {}; - convertOptions(locPosMode, options); + convertOptions(locPosMode, trackingOptions); if (!mUlpProxy->sendFixMode(locPosMode)) { // do nothing } @@ -2229,7 +2269,7 @@ GnssAdapter::startTracking(LocationAPI* client, uint32_t sessionId, bool GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId, - const LocationOptions& updatedOptions, const LocationOptions& oldOptions) + const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions) { bool reportToClientWithNoWait = true; @@ -2328,7 +2368,7 @@ GnssAdapter::startTrackingCommand() void GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, - LocationOptions& options) + TrackingOptions& options) { LOC_LOGD("%s]: client %p id %u minInterval %u mode %u", __func__, client, id, options.minInterval, options.mode); @@ -2338,28 +2378,40 @@ GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocApiBase& mApi; LocationAPI* mClient; uint32_t mSessionId; - LocationOptions mOptions; + mutable TrackingOptions mTrackingOptions; inline MsgUpdateTracking(GnssAdapter& adapter, LocApiBase& api, LocationAPI* client, uint32_t sessionId, - LocationOptions options) : + TrackingOptions trackingOptions) : LocMsg(), mAdapter(adapter), mApi(api), mClient(client), mSessionId(sessionId), - mOptions(options) {} + mTrackingOptions(trackingOptions) {} inline virtual void proc() const { if (mAdapter.isTrackingSession(mClient, mSessionId)) { LocationError err = LOCATION_ERROR_SUCCESS; - if (0 == mOptions.size) { + if (0 == mTrackingOptions.size) { err = LOCATION_ERROR_INVALID_PARAMETER; } else { + if (GNSS_POWER_MODE_INVALID != mTrackingOptions.powerMode && + !ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) { + LOC_LOGv("Ignoring power mode, feature not supported."); + mTrackingOptions.powerMode = GNSS_POWER_MODE_INVALID; + } + if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02) && + GNSS_POWER_MODE_M4 == mTrackingOptions.powerMode && + mTrackingOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) { + LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode", + mTrackingOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS); + mTrackingOptions.powerMode = GNSS_POWER_MODE_M2; + } // Api doesn't support multiple clients for time based tracking, so mutiplex bool reportToClientWithNoWait = - mAdapter.updateTrackingMultiplex(mClient, mSessionId, mOptions); - mAdapter.saveTrackingSession(mClient, mSessionId, mOptions); + mAdapter.updateTrackingMultiplex(mClient, mSessionId, mTrackingOptions); + mAdapter.saveTrackingSession(mClient, mSessionId, mTrackingOptions); if (reportToClientWithNoWait) { mAdapter.reportResponse(mClient, err, mSessionId); @@ -2377,41 +2429,58 @@ GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, bool GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id, - const LocationOptions& options) + const TrackingOptions& trackingOptions) { bool reportToClientWithNoWait = true; LocationSessionKey key(client, id); // get the session we are updating auto it = mTrackingSessions.find(key); - // cache the clients existing LocationOptions - LocationOptions oldOptions = it->second; - if (1 == mTrackingSessions.size()) { - reportToClientWithNoWait = updateTracking(client, id, options, oldOptions); - } else { - if (it != mTrackingSessions.end()) { - // find the smallest interval, other than the session we are updating - LocationOptions smallestIntervalOptions = {}; // size is 0 until set for the first time - for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) { - // if session is not the one we are updating and either smallest interval is not set - // or there is a new smallest interval, then set the new smallest interval - if (it2->first != key && (0 == smallestIntervalOptions.size || - it2->second.minInterval < smallestIntervalOptions.minInterval)) { - smallestIntervalOptions = it2->second; - } + // cache the clients existing LocationOptions + TrackingOptions oldOptions = it->second; + + // if session we are updating exists and the minInterval or powerMode has changed + if (it != mTrackingSessions.end() && (it->second.minInterval != trackingOptions.minInterval || + it->second.powerMode != trackingOptions.powerMode)) { + // find the smallest interval and powerMode, other than the session we are updating + TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time + GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID; + for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) { + // if session is not the one we are updating and either interval + // is not set or there is a new smallest interval, then set the new interval + if (it2->first != key && (0 == multiplexedOptions.size || + it2->second.minInterval < multiplexedOptions.minInterval)) { + multiplexedOptions = it2->second; } - // if session we are updating has smaller interval then next smallest - if (options.minInterval < smallestIntervalOptions.minInterval) { - // restart time based tracking with the newly updated interval - reportToClientWithNoWait = updateTracking(client, id, options, oldOptions); - // else if the session we are updating used to be the smallest - } else if (it->second.minInterval < smallestIntervalOptions.minInterval) { - // restart time based tracking with the next smallest - reportToClientWithNoWait = updateTracking( - client, id, smallestIntervalOptions, oldOptions); + // if session is not the one we are updating and either powerMode + // is not set or there is a new smallest powerMode, then set the new powerMode + if (it2->first != key && (GNSS_POWER_MODE_INVALID == multiplexedPowerMode || + it2->second.powerMode < multiplexedPowerMode)) { + multiplexedPowerMode = it2->second.powerMode; } } + bool updateOptions = false; + // if session we are updating has smaller interval then next smallest + if (trackingOptions.minInterval < multiplexedOptions.minInterval) { + multiplexedOptions.minInterval = trackingOptions.minInterval; + updateOptions = true; + } + // if session we are updating has smaller powerMode then next smallest + if (trackingOptions.powerMode < multiplexedPowerMode) { + multiplexedOptions.powerMode = trackingOptions.powerMode; + updateOptions = true; + } + // if only one session exists, then tracking should be updated with it + if (1 == mTrackingSessions.size()) { + multiplexedOptions = trackingOptions; + updateOptions = true; + } + if (updateOptions) { + // restart time based tracking with the newly updated options + reportToClientWithNoWait = updateTracking( + client, id, multiplexedOptions, oldOptions); + } } return reportToClientWithNoWait; @@ -2469,20 +2538,30 @@ GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id) // get the session we are stopping auto it = mTrackingSessions.find(key); if (it != mTrackingSessions.end()) { - // find the next smallest interval, other than the session we are stopping - LocationOptions smallestIntervalOptions = {}; // size is 0 until set for the first time + // find the smallest interval and powerMode, other than the session we are stopping + TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time + GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID; for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) { - // if session is not the one we are stopping and either smallest interval is not set - // or there is a new smallest interval, then set the new smallest interval - if (it2->first != key && (0 == smallestIntervalOptions.size || - it2->second.minInterval < smallestIntervalOptions.minInterval)) { - smallestIntervalOptions = it2->second; + // if session is not the one we are stopping and either interval + // is not set or there is a new smallest interval, then set the new interval + if (it2->first != key && (0 == multiplexedOptions.size || + it2->second.minInterval < multiplexedOptions.minInterval)) { + multiplexedOptions = it2->second; + } + // if session is not the one we are stopping and either powerMode + // is not set or there is a new smallest powerMode, then set the new powerMode + if (it2->first != key && (GNSS_POWER_MODE_INVALID == multiplexedPowerMode || + it2->second.powerMode < multiplexedPowerMode)) { + multiplexedPowerMode = it2->second.powerMode; } } - // if session we are stopping has smaller interval then next smallest - if (it->second.minInterval < smallestIntervalOptions.minInterval) { - // restart time based tracking with next smallest interval - reportToClientWithNoWait = startTracking(client, id, smallestIntervalOptions); + // if session we are stopping has smaller interval then next smallest or + // if session we are stopping has smaller powerMode then next smallest + if (it->second.minInterval < multiplexedOptions.minInterval || + it->second.powerMode < multiplexedPowerMode) { + multiplexedOptions.powerMode = multiplexedPowerMode; + // restart time based tracking with the newly updated options + reportToClientWithNoWait = startTracking(client, id, multiplexedOptions); } } } diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index b906e484..ff66de43 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -94,7 +94,7 @@ class GnssAdapter : public LocAdapterBase { ClientDataMap mClientData; /* ==== TRACKING ======================================================================= */ - LocationSessionMap mTrackingSessions; + TrackingOptionsMap mTrackingSessions; LocPosMode mUlpPositionMode; GnssSvUsedInPosition mGnssSvIdUsedInPosition; bool mGnssSvIdUsedInPosAvail; @@ -122,7 +122,7 @@ class GnssAdapter : public LocAdapterBase { XtraSystemStatusObserver mXtraObserver; /*==== CONVERSION ===================================================================*/ - static void convertOptions(LocPosMode& out, const LocationOptions& options); + static void convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions); static void convertLocation(Location& out, const UlpLocation& ulpLocation, const GpsLocationExtended& locationExtended, const LocPosTechMask techMask); @@ -164,8 +164,10 @@ public: /* ==== TRACKING ======================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ - uint32_t startTrackingCommand(LocationAPI* client, LocationOptions& options); - void updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocationOptions& options); + uint32_t startTrackingCommand( + LocationAPI* client, TrackingOptions& trackingOptions); + void updateTrackingOptionsCommand( + LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions); void stopTrackingCommand(LocationAPI* client, uint32_t id); /* ======================(Called from ULP Thread)======================================= */ virtual void setPositionModeCommand(LocPosMode& locPosMode); @@ -179,20 +181,20 @@ public: bool hasMeasurementsCallback(LocationAPI* client); bool isTrackingSession(LocationAPI* client, uint32_t sessionId); void saveTrackingSession(LocationAPI* client, uint32_t sessionId, - const LocationOptions& options); + const TrackingOptions& trackingOptions); void eraseTrackingSession(LocationAPI* client, uint32_t sessionId); bool setUlpPositionMode(const LocPosMode& mode); LocPosMode& getUlpPositionMode() { return mUlpPositionMode; } bool startTrackingMultiplex(LocationAPI* client, uint32_t sessionId, - const LocationOptions& options); + const TrackingOptions& trackingOptions); bool startTracking(LocationAPI* client, uint32_t sessionId, - const LocationOptions& options); + const TrackingOptions& trackingOptions); bool stopTrackingMultiplex(LocationAPI* client, uint32_t id); bool stopTracking(LocationAPI* client, uint32_t id); bool updateTrackingMultiplex(LocationAPI* client, uint32_t id, - const LocationOptions& options); + const TrackingOptions& trackingOptions); bool updateTracking(LocationAPI* client, uint32_t sessionId, - const LocationOptions& updatedOptions, const LocationOptions& oldOptions); + const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions); /* ==== NI ============================================================================= */ /* ======== COMMANDS ====(Called from Client Thread)==================================== */ diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp index 0dac13d5..34903950 100644 --- a/gnss/location_gnss.cpp +++ b/gnss/location_gnss.cpp @@ -39,8 +39,8 @@ static void addClient(LocationAPI* client, const LocationCallbacks& callbacks); static void removeClient(LocationAPI* client); static void requestCapabilities(LocationAPI* client); -static uint32_t startTracking(LocationAPI* client, LocationOptions& options); -static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options); +static uint32_t startTracking(LocationAPI* client, TrackingOptions&); +static void updateTrackingOptions(LocationAPI* client, uint32_t id, TrackingOptions&); static void stopTracking(LocationAPI* client, uint32_t id); static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response); @@ -143,19 +143,22 @@ static void requestCapabilities(LocationAPI* client) } } -static uint32_t startTracking(LocationAPI* client, LocationOptions& options) +static uint32_t startTracking( + LocationAPI* client, TrackingOptions& trackingOptions) { if (NULL != gGnssAdapter) { - return gGnssAdapter->startTrackingCommand(client, options); + return gGnssAdapter->startTrackingCommand(client, trackingOptions); } else { return 0; } } -static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options) +static void updateTrackingOptions( + LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions) { if (NULL != gGnssAdapter) { - gGnssAdapter->updateTrackingOptionsCommand(client, id, options); + gGnssAdapter->updateTrackingOptionsCommand( + client, id, trackingOptions); } } diff --git a/location/ILocationAPI.h b/location/ILocationAPI.h index ae695cf8..3df6f799 100644 --- a/location/ILocationAPI.h +++ b/location/ILocationAPI.h @@ -53,7 +53,7 @@ public: 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(LocationOptions&) = 0; + virtual uint32_t startTracking(TrackingOptions&) = 0; /** @brief Stops a tracking session associated with id parameter. responseCallback returns: @@ -66,7 +66,7 @@ public: LOCATION_ERROR_SUCCESS if successful LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */ - virtual void updateTrackingOptions(uint32_t id, LocationOptions&) = 0; + virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) = 0; /* ================================== BATCHING ================================== */ @@ -86,7 +86,7 @@ public: 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(LocationOptions&, BatchingOptions&) = 0; + virtual uint32_t startBatching(BatchingOptions&) = 0; /** @brief Stops a batching session associated with id parameter. responseCallback returns: @@ -99,7 +99,7 @@ public: LOCATION_ERROR_SUCCESS if successful LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */ - virtual void updateBatchingOptions(uint32_t id, LocationOptions&, BatchingOptions&) = 0; + 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. diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp index 060ce5f2..581158bd 100644 --- a/location/LocationAPI.cpp +++ b/location/LocationAPI.cpp @@ -25,6 +25,7 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define LOG_NDEBUG 0 #define LOG_TAG "LocSvc_LocationAPI" #include @@ -289,21 +290,21 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks) } uint32_t -LocationAPI::startTracking(LocationOptions& locationOptions) +LocationAPI::startTracking(TrackingOptions& trackingOptions) { uint32_t id = 0; pthread_mutex_lock(&gDataMutex); auto it = gData.clientData.find(this); if (it != gData.clientData.end()) { - if (gData.flpInterface != NULL && locationOptions.minDistance > 0) { - id = gData.flpInterface->startTracking(this, locationOptions); - } else if (gData.gnssInterface != NULL && needsGnssTrackingInfo(it->second)) { - id = gData.gnssInterface->startTracking(this, locationOptions); - } else if (gData.flpInterface != NULL) { - id = gData.flpInterface->startTracking(this, locationOptions); - } else if (gData.gnssInterface != NULL) { - id = gData.gnssInterface->startTracking(this, locationOptions); + if (NULL != gData.flpInterface && trackingOptions.minDistance > 0) { + id = gData.flpInterface->startTracking(this, trackingOptions); + } else if (NULL != gData.gnssInterface && needsGnssTrackingInfo(it->second)) { + id = gData.gnssInterface->startTracking(this, trackingOptions); + } else if (NULL != gData.flpInterface) { + id = gData.flpInterface->startTracking(this, trackingOptions); + } else if (NULL != gData.gnssInterface) { + id = gData.gnssInterface->startTracking(this, trackingOptions); } else { LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ", __func__, __LINE__, this); @@ -345,7 +346,8 @@ LocationAPI::stopTracking(uint32_t id) } void -LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions) +LocationAPI::updateTrackingOptions( + uint32_t id, TrackingOptions& trackingOptions) { pthread_mutex_lock(&gDataMutex); @@ -354,10 +356,10 @@ LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions // we don't know if tracking was started on flp or gnss, so we call update on both, where // updateTracking call to the incorrect interface will fail without response back to client if (gData.gnssInterface != NULL) { - gData.gnssInterface->updateTrackingOptions(this, id, locationOptions); + gData.gnssInterface->updateTrackingOptions(this, id, trackingOptions); } if (gData.flpInterface != NULL) { - gData.flpInterface->updateTrackingOptions(this, id, locationOptions); + gData.flpInterface->updateTrackingOptions(this, id, trackingOptions); } if (gData.flpInterface == NULL && gData.gnssInterface == NULL) { LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ", @@ -372,13 +374,13 @@ LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions } uint32_t -LocationAPI::startBatching(LocationOptions& locationOptions, BatchingOptions &batchingOptions) +LocationAPI::startBatching(BatchingOptions &batchingOptions) { uint32_t id = 0; pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { - id = gData.flpInterface->startBatching(this, locationOptions, batchingOptions); + if (NULL != gData.flpInterface) { + id = gData.flpInterface->startBatching(this, batchingOptions); } else { LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", __func__, __LINE__, this); @@ -393,7 +395,7 @@ LocationAPI::stopBatching(uint32_t id) { pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { + if (NULL != gData.flpInterface) { gData.flpInterface->stopBatching(this, id); } else { LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", @@ -404,16 +406,12 @@ LocationAPI::stopBatching(uint32_t id) } void -LocationAPI::updateBatchingOptions(uint32_t id, - LocationOptions& locationOptions, BatchingOptions& batchOptions) +LocationAPI::updateBatchingOptions(uint32_t id, BatchingOptions& batchOptions) { pthread_mutex_lock(&gDataMutex); - if (gData.flpInterface != NULL) { - gData.flpInterface->updateBatchingOptions(this, - id, - locationOptions, - batchOptions); + if (NULL != gData.flpInterface) { + gData.flpInterface->updateBatchingOptions(this, id, batchOptions); } else { LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ", __func__, __LINE__, this); diff --git a/location/LocationAPI.h b/location/LocationAPI.h index cfdb19f2..f4f31f96 100644 --- a/location/LocationAPI.h +++ b/location/LocationAPI.h @@ -63,8 +63,8 @@ public: 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 LocationOptions parameter is invalid */ - virtual uint32_t startTracking(LocationOptions&) override; + 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: @@ -72,12 +72,12 @@ public: LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */ virtual void stopTracking(uint32_t id) override; - /* updateTrackingOptions changes the LocationOptions of a tracking session associated with id + /* updateTrackingOptions changes the TrackingOptions 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_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, LocationOptions&) override; + virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) override; /* ================================== BATCHING ================================== */ @@ -96,7 +96,7 @@ public: LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */ - virtual uint32_t startBatching(LocationOptions&, BatchingOptions&) override; + virtual uint32_t startBatching(BatchingOptions&) override; /* stopBatching stops a batching session associated with id parameter. responseCallback returns: @@ -104,12 +104,12 @@ public: LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */ virtual void stopBatching(uint32_t id) override; - /* updateBatchingOptions changes the LocationOptions of a batching session associated with id + /* updateBatchingOptions changes the BatchingOptions 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_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, LocationOptions&, BatchingOptions&) override; + 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. diff --git a/location/LocationAPIClientBase.cpp b/location/LocationAPIClientBase.cpp index 65a09847..67e559b9 100644 --- a/location/LocationAPIClientBase.cpp +++ b/location/LocationAPIClientBase.cpp @@ -330,7 +330,7 @@ LocationAPIClientBase::~LocationAPIClientBase() pthread_mutex_destroy(&mMutex); } -uint32_t LocationAPIClientBase::locAPIStartTracking(LocationOptions& options) +uint32_t LocationAPIClientBase::locAPIStartTracking(TrackingOptions& options) { uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE; pthread_mutex_lock(&mMutex); @@ -372,7 +372,7 @@ void LocationAPIClientBase::locAPIStopTracking() pthread_mutex_unlock(&mMutex); } -void LocationAPIClientBase::locAPIUpdateTrackingOptions(LocationOptions& options) +void LocationAPIClientBase::locAPIUpdateTrackingOptions(TrackingOptions& options) { pthread_mutex_lock(&mMutex); if (mLocationAPI) { @@ -404,9 +404,8 @@ int32_t LocationAPIClientBase::locAPIGetBatchSize() return mBatchSize; } - -uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t sessionMode, - LocationOptions& locationOptions) +uint32_t LocationAPIClientBase::locAPIStartSession( + uint32_t id, uint32_t sessionMode, TrackingOptions&& options) { uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE; pthread_mutex_lock(&mMutex); @@ -420,7 +419,7 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session uint32_t batchingSession = 0; if (sessionMode == SESSION_MODE_ON_FIX) { - trackingSession = mLocationAPI->startTracking(locationOptions); + trackingSession = mLocationAPI->startTracking(options); LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession); mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this)); } else { @@ -439,7 +438,12 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session break; } - batchingSession = mLocationAPI->startBatching(locationOptions, batchOptions); + // 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)); @@ -496,8 +500,8 @@ uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id) return retVal; } -uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode, - LocationOptions& options) +uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions( + uint32_t id, uint32_t sessionMode, TrackingOptions&& options) { uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE; pthread_mutex_lock(&mMutex); @@ -554,13 +558,18 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t 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(options, batchOptions); + batchingSession = mLocationAPI->startBatching(batchOptions); LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession); mRequestQueues[REQUEST_SESSION].setSession(batchingSession); } else { - mLocationAPI->updateBatchingOptions(batchingSession, options, batchOptions); + mLocationAPI->updateBatchingOptions(batchingSession, batchOptions); } } diff --git a/location/LocationAPIClientBase.h b/location/LocationAPIClientBase.h index 4d48932a..bcc39f3c 100644 --- a/location/LocationAPIClientBase.h +++ b/location/LocationAPIClientBase.h @@ -209,16 +209,16 @@ public: LocationAPIRequest* getRequestBySession(uint32_t session); // LocationAPI - uint32_t locAPIStartTracking(LocationOptions& options); + uint32_t locAPIStartTracking(TrackingOptions& trackingOptions); void locAPIStopTracking(); - void locAPIUpdateTrackingOptions(LocationOptions& options); + void locAPIUpdateTrackingOptions(TrackingOptions& trackingOptions); int32_t locAPIGetBatchSize(); - uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode, - LocationOptions& options); + 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, - LocationOptions& options); + 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, diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h index 5d1c8093..9809e616 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -533,18 +533,60 @@ typedef struct { LocationTechnologyMask techMask; } Location; -typedef struct { +struct LocationOptions { size_t size; // set to sizeof(LocationOptions) uint32_t minInterval; // in milliseconds uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/ // gnssMeasurementsCallback may not be called GnssSuplMode mode; // Standalone/MS-Based/MS-Assisted -} LocationOptions; -typedef struct { - size_t size; + inline LocationOptions() : + size(0), minInterval(0), minDistance(0), mode(GNSS_SUPL_MODE_STANDALONE) {} +}; + +typedef enum { + GNSS_POWER_MODE_INVALID = 0, + GNSS_POWER_MODE_M1, /* Improved Accuracy Mode */ + GNSS_POWER_MODE_M2, /* Normal Mode */ + GNSS_POWER_MODE_M3, /* Background Mode */ + GNSS_POWER_MODE_M4, /* Background Mode */ + GNSS_POWER_MODE_M5 /* Background Mode */ +} GnssPowerMode; + +struct TrackingOptions : LocationOptions { + GnssPowerMode powerMode; /* Power Mode to be used for time based tracking + sessions */ + uint32_t tbm; /* Time interval between measurements specified in millis. + Applicable to background power modes */ + + inline TrackingOptions() : + LocationOptions(), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {} + inline TrackingOptions(size_t s, GnssPowerMode m, uint32_t t) : + LocationOptions(), powerMode(m), tbm(t) { LocationOptions::size = s; } + inline TrackingOptions(const LocationOptions& options) : + LocationOptions(options), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {} + inline void setLocationOptions(const LocationOptions& options) { + minInterval = options.minInterval; + minDistance = options.minDistance; + mode = options.mode; + } +}; + +struct BatchingOptions : LocationOptions { BatchingMode batchingMode; -} BatchingOptions; + + inline BatchingOptions() : + LocationOptions(), batchingMode(BATCHING_MODE_ROUTINE) {} + inline BatchingOptions(size_t s, BatchingMode m) : + LocationOptions(), batchingMode(m) { LocationOptions::size = s; } + inline BatchingOptions(const LocationOptions& options) : + LocationOptions(options), batchingMode(BATCHING_MODE_ROUTINE) {} + inline void setLocationOptions(const LocationOptions& options) { + minInterval = options.minInterval; + minDistance = options.minDistance; + mode = options.mode; + } +}; typedef struct { size_t size; diff --git a/location/location_interface.h b/location/location_interface.h index f4f904d9..a460bb62 100644 --- a/location/location_interface.h +++ b/location/location_interface.h @@ -39,8 +39,8 @@ struct GnssInterface { void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks); void (*removeClient)(LocationAPI* client); void (*requestCapabilities)(LocationAPI* client); - uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options); - void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options); + 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); @@ -70,13 +70,12 @@ struct FlpInterface { void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks); void (*removeClient)(LocationAPI* client); void (*requestCapabilities)(LocationAPI* client); - uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options); - void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options); + uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&); + void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&); void (*stopTracking)(LocationAPI* client, uint32_t id); - uint32_t (*startBatching)(LocationAPI* client, LocationOptions&, BatchingOptions&); + uint32_t (*startBatching)(LocationAPI* client, BatchingOptions&); void (*stopBatching)(LocationAPI* client, uint32_t id); - void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, LocationOptions&, - BatchingOptions&); + void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, BatchingOptions&); void (*getBatchedLocations)(LocationAPI* client, uint32_t id, size_t count); void (*getPowerStateChanges)(void* powerStateCb); }; diff --git a/utils/gps_extended.h b/utils/gps_extended.h index dc6ad1eb..24556299 100644 --- a/utils/gps_extended.h +++ b/utils/gps_extended.h @@ -55,14 +55,19 @@ struct LocPosMode bool share_position; char credentials[14]; char provider[8]; + GnssPowerMode powerMode; + uint32_t timeBetweenMeasurements; LocPosMode(LocPositionMode m, LocGpsPositionRecurrence recr, uint32_t gap, uint32_t accu, uint32_t time, - bool sp, const char* cred, const char* prov) : + bool sp, const char* cred, const char* prov, + GnssPowerMode pMode = GNSS_POWER_MODE_INVALID, + uint32_t tbm = 0) : mode(m), recurrence(recr), min_interval(gap < GPS_MIN_POSSIBLE_FIX_INTERVAL_MS ? GPS_MIN_POSSIBLE_FIX_INTERVAL_MS : gap), preferred_accuracy(accu), preferred_time(time), - share_position(sp) { + share_position(sp), powerMode(pMode), + timeBetweenMeasurements(tbm) { memset(credentials, 0, sizeof(credentials)); memset(provider, 0, sizeof(provider)); if (NULL != cred) { @@ -78,7 +83,8 @@ struct LocPosMode recurrence(LOC_GPS_POSITION_RECURRENCE_PERIODIC), min_interval(GPS_DEFAULT_FIX_INTERVAL_MS), preferred_accuracy(50), preferred_time(120000), - share_position(true) { + share_position(true), powerMode(GNSS_POWER_MODE_INVALID), + timeBetweenMeasurements(GPS_DEFAULT_FIX_INTERVAL_MS) { memset(credentials, 0, sizeof(credentials)); memset(provider, 0, sizeof(provider)); } @@ -90,6 +96,8 @@ struct LocPosMode anotherMode.min_interval == min_interval && anotherMode.preferred_accuracy == preferred_accuracy && anotherMode.preferred_time == preferred_time && + anotherMode.powerMode == powerMode && + anotherMode.timeBetweenMeasurements == timeBetweenMeasurements && !strncmp(anotherMode.credentials, credentials, sizeof(credentials)-1) && !strncmp(anotherMode.provider, provider, sizeof(provider)-1); } diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index 5c5405fe..5db1b130 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -95,6 +95,9 @@ typedef uint32_t LocSvInfoSource; #define LOC_AGPS_CERTIFICATE_MAX_LENGTH 2000 #define LOC_AGPS_CERTIFICATE_MAX_SLOTS 10 +/* TBM Threshold for tracking in background power mode : in millis */ +#define TRACKING_TBM_THRESHOLD_MILLIS 480000 + typedef uint32_t LocPosTechMask; #define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000) #define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)