diff options
author | Kevin Tang <zhikait@codeaurora.org> | 2021-09-09 20:53:33 -0700 |
---|---|---|
committer | Kevin Tang <zhikait@codeaurora.org> | 2021-09-22 17:38:04 -0700 |
commit | fe3a618c12adabd7cc6703c3bd90c21d1d9471a6 (patch) | |
tree | 04c5d95c1fe4c59ca0499059c36b51142a0570b7 | |
parent | fa47d4d4bc9ba5da76284435cf24adfd95827b55 (diff) |
Resource leaks and some other issues in android.hardware.gnss@*-impl-qti
Fixes to several issues in android.hardware.gnss@*-impl-qti:
1) HW Geofence leaks if AFW resets, as deleteAllGeofences not implemented; and
2) When AFW resets, one of the bugs will happen, depending on if IGnss handle
is deleted and regenerated:
a) HW Geofence callbacks may not get updated after AFW resets; or
b) Double free of iface implementations for those that implement own
deathRecipients, since the deathRecipients take *this* raw pointers to
make own sp<>, but Gnss obj already holds sp<> from the same *this*.
4) older versions of impl do not compile.
Change-Id: I2c6370005f887d62e6021fca66d9cf73f942f57f
CRs-Fixed: 3032780
63 files changed, 504 insertions, 455 deletions
diff --git a/android/1.0/Android.mk b/android/1.0/Android.mk index dea2b26..9d05878 100644 --- a/android/1.0/Android.mk +++ b/android/1.0/Android.mk @@ -42,6 +42,7 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.gnss@1.0 \ android.hardware.health@1.0 \ android.hardware.health@2.0 \ + android.hardware.health@2.1 \ android.hardware.power@1.2 \ libbase diff --git a/android/1.0/Gnss.cpp b/android/1.0/Gnss.cpp index 308cc7c..c7fca33 100644 --- a/android/1.0/Gnss.cpp +++ b/android/1.0/Gnss.cpp @@ -42,10 +42,10 @@ static sp<Gnss> sGnss; void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnss != nullptr) { - mGnss->getGnssInterface()->resetNetworkInfo(); - mGnss->stop(); - mGnss->cleanup(); + auto gnss = mGnss.promote(); + if (gnss != nullptr) { + gnss->getGnssInterface()->resetNetworkInfo(); + gnss->cleanup(); } } @@ -65,7 +65,7 @@ Gnss::Gnss() { // clear pending GnssConfig memset(&mPendingConfig, 0, sizeof(GnssConfig)); - mGnssDeathRecipient = new GnssDeathRecipient(this); + mGnssDeathRecipient = new GnssDeathRecipient(sGnss); } Gnss::~Gnss() { @@ -297,7 +297,7 @@ Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() { Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { ENTRY_LOG_CALLFLOW(); if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; } @@ -309,12 +309,12 @@ Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() { Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { ENTRY_LOG_CALLFLOW(); - mGnssGeofencingIface = new GnssGeofencing(); + mGnssGeofencingIface = new GnssGeofencing(mGnssGeofencingIface); return mGnssGeofencingIface; } Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() { - mGnssBatching = new GnssBatching(); + mGnssBatching = new GnssBatching(mGnssBatching); return mGnssBatching; } diff --git a/android/1.0/Gnss.h b/android/1.0/Gnss.h index 900a510..6e88509 100644 --- a/android/1.0/Gnss.h +++ b/android/1.0/Gnss.h @@ -106,11 +106,11 @@ struct Gnss : public IGnss { private: struct GnssDeathRecipient : hidl_death_recipient { - GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) { + GnssDeathRecipient(const sp<Gnss>& gnss) : mGnss(gnss) { } ~GnssDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<Gnss> mGnss; + const wp<Gnss> mGnss; }; private: diff --git a/android/1.0/GnssBatching.cpp b/android/1.0/GnssBatching.cpp index f92697f..1d2d378 100644 --- a/android/1.0/GnssBatching.cpp +++ b/android/1.0/GnssBatching.cpp @@ -34,16 +34,13 @@ void GnssBatching::GnssBatchingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssBatching != nullptr) { - mGnssBatching->stop(); - mGnssBatching->cleanup(); + auto gnssBatching = mGnssBatching.promote(); + if (gnssBatching != nullptr) { + gnssBatching->stop(); + gnssBatching->cleanup(); } } -GnssBatching::GnssBatching() : mApi(nullptr) { - mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this); -} - GnssBatching::~GnssBatching() { if (mApi != nullptr) { mApi->destroy(); @@ -54,16 +51,14 @@ GnssBatching::~GnssBatching() { // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__); - mApi->destroy(); - mApi = nullptr; + if (mGnssBatchingDeathRecipient == nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(mSelf); } - mApi = new BatchingAPIClient(callback); - if (mApi == nullptr) { - LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); - return false; + if (mApi != nullptr) { + mApi->gnssUpdateCallbacks(callback); + } else { + mApi = new BatchingAPIClient(callback); } if (mGnssBatchingCbIface != nullptr) { diff --git a/android/1.0/GnssBatching.h b/android/1.0/GnssBatching.h index 8fab857..1bd102b 100644 --- a/android/1.0/GnssBatching.h +++ b/android/1.0/GnssBatching.h @@ -44,7 +44,7 @@ using ::android::sp; class BatchingAPIClient; struct GnssBatching : public IGnssBatching { - GnssBatching(); + inline GnssBatching(const sp<GnssBatching>& self) : mSelf(self), mApi(nullptr) {} ~GnssBatching(); // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. @@ -57,15 +57,18 @@ struct GnssBatching : public IGnssBatching { private: struct GnssBatchingDeathRecipient : hidl_death_recipient { - GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) : + GnssBatchingDeathRecipient(const sp<GnssBatching>& gnssBatching) : mGnssBatching(gnssBatching) { } ~GnssBatchingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssBatching> mGnssBatching; + const wp<GnssBatching> mGnssBatching; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssBatching>& mSelf; sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr; sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr; BatchingAPIClient* mApi = nullptr; diff --git a/android/1.0/GnssGeofencing.cpp b/android/1.0/GnssGeofencing.cpp index 4be6d8a..5accd5c 100644 --- a/android/1.0/GnssGeofencing.cpp +++ b/android/1.0/GnssGeofencing.cpp @@ -34,15 +34,12 @@ void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssGeofencing != nullptr) { - mGnssGeofencing->removeAllGeofences(); + auto gnssGeofencing = mGnssGeofencing.promote(); + if (gnssGeofencing != nullptr) { + gnssGeofencing->removeAllGeofences(); } } -GnssGeofencing::GnssGeofencing() : mApi(nullptr) { - mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this); -} - GnssGeofencing::~GnssGeofencing() { if (mApi != nullptr) { mApi->destroy(); @@ -52,12 +49,15 @@ GnssGeofencing::~GnssGeofencing() { // Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow. Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGE("%s]: mApi is NOT nullptr", __FUNCTION__); - return Void(); + if (mGnssGeofencingDeathRecipient == nullptr) { + mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(mSelf); } - mApi = new GeofenceAPIClient(callback); + if (mApi != nullptr) { + mApi->upcateCallback(callback); + } else { + mApi = new GeofenceAPIClient(callback); + } if (mApi == nullptr) { LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); } diff --git a/android/1.0/GnssGeofencing.h b/android/1.0/GnssGeofencing.h index db5f9d2..64f74a9 100644 --- a/android/1.0/GnssGeofencing.h +++ b/android/1.0/GnssGeofencing.h @@ -40,7 +40,7 @@ using ::android::sp; class GeofenceAPIClient; struct GnssGeofencing : public IGnssGeofencing { - GnssGeofencing(); + inline GnssGeofencing(const sp<GnssGeofencing>& self) : mSelf(self), mApi(nullptr) {} ~GnssGeofencing(); /* @@ -68,15 +68,18 @@ struct GnssGeofencing : public IGnssGeofencing { private: struct GnssGeofencingDeathRecipient : hidl_death_recipient { - GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) : + GnssGeofencingDeathRecipient(const sp<GnssGeofencing>& gnssGeofencing) : mGnssGeofencing(gnssGeofencing) { } ~GnssGeofencingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssGeofencing> mGnssGeofencing; + const wp<GnssGeofencing> mGnssGeofencing; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssGeofencing>& mSelf; sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr; sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr; GeofenceAPIClient* mApi = nullptr; diff --git a/android/1.0/GnssMeasurement.cpp b/android/1.0/GnssMeasurement.cpp index 7af9e27..6ee9c76 100644 --- a/android/1.0/GnssMeasurement.cpp +++ b/android/1.0/GnssMeasurement.cpp @@ -34,14 +34,14 @@ void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssMeasurement != nullptr) { - mGnssMeasurement->close(); + auto gssMeasurement = mGnssMeasurement.promote(); + if (gssMeasurement != nullptr) { + gssMeasurement->close(); } } -GnssMeasurement::GnssMeasurement() { - mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this); - mApi = new MeasurementAPIClient(); +GnssMeasurement::GnssMeasurement(const sp<GnssMeasurement>& self) : + mSelf(self), mApi(new MeasurementAPIClient()) { } GnssMeasurement::~GnssMeasurement() { @@ -73,6 +73,9 @@ Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback( } mGnssMeasurementCbIface = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0); return mApi->measurementSetCallback(callback); diff --git a/android/1.0/GnssMeasurement.h b/android/1.0/GnssMeasurement.h index 4247dbf..3cf962a 100644 --- a/android/1.0/GnssMeasurement.h +++ b/android/1.0/GnssMeasurement.h @@ -41,7 +41,7 @@ using ::android::sp; class MeasurementAPIClient; struct GnssMeasurement : public IGnssMeasurement { - GnssMeasurement(); + GnssMeasurement(const sp<GnssMeasurement>& self); ~GnssMeasurement(); /* @@ -54,15 +54,18 @@ struct GnssMeasurement : public IGnssMeasurement { private: struct GnssMeasurementDeathRecipient : hidl_death_recipient { - GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) : + GnssMeasurementDeathRecipient(const sp<GnssMeasurement>& gnssMeasurement) : mGnssMeasurement(gnssMeasurement) { } ~GnssMeasurementDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssMeasurement> mGnssMeasurement; + const wp<GnssMeasurement> mGnssMeasurement; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssMeasurement>& mSelf; sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr; sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr; MeasurementAPIClient* mApi; diff --git a/android/1.0/GnssNi.cpp b/android/1.0/GnssNi.cpp index d06cc20..3e08e5b 100644 --- a/android/1.0/GnssNi.cpp +++ b/android/1.0/GnssNi.cpp @@ -30,15 +30,7 @@ namespace gnss { namespace V1_0 { namespace implementation { -void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { - LOC_LOGE("%s] service died. cookie: %llu, who: %p", - __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - // we do nothing here - // Gnss::GnssDeathRecipient will stop the session -} - GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) { - mGnssNiDeathRecipient = new GnssNiDeathRecipient(this); } // Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. @@ -49,14 +41,7 @@ Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) { } mGnss->setGnssNiCb(callback); - - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient); - } mGnssNiCbIface = callback; - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/); - } return Void(); } diff --git a/android/1.0/GnssNi.h b/android/1.0/GnssNi.h index 90f62d5..d7ba5c2 100644 --- a/android/1.0/GnssNi.h +++ b/android/1.0/GnssNi.h @@ -52,16 +52,6 @@ struct GnssNi : public IGnssNi { IGnssNiCallback::GnssUserResponseType userResponse) override; private: - struct GnssNiDeathRecipient : hidl_death_recipient { - GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) { - } - ~GnssNiDeathRecipient() = default; - virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssNi> mGnssNi; - }; - - private: - sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr; sp<IGnssNiCallback> mGnssNiCbIface = nullptr; Gnss* mGnss = nullptr; }; diff --git a/android/1.0/location_api/BatchingAPIClient.cpp b/android/1.0/location_api/BatchingAPIClient.cpp index 94a234d..37ed46e 100644 --- a/android/1.0/location_api/BatchingAPIClient.cpp +++ b/android/1.0/location_api/BatchingAPIClient.cpp @@ -67,12 +67,10 @@ BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) locationCallbacks.trackingCb = nullptr; locationCallbacks.batchingCb = nullptr; - if (mGnssBatchingCbIface != nullptr) { - locationCallbacks.batchingCb = [this](size_t count, Location* location, + locationCallbacks.batchingCb = [this](size_t count, Location* location, BatchingOptions batchOptions) { - onBatchingCb(count, location, batchOptions); - }; - } + onBatchingCb(count, location, batchOptions); + }; locationCallbacks.geofenceBreachCb = nullptr; locationCallbacks.geofenceStatusCb = nullptr; locationCallbacks.gnssLocationInfoCb = nullptr; @@ -89,6 +87,13 @@ BatchingAPIClient::~BatchingAPIClient() LOC_LOGD("%s]: ()", __FUNCTION__); } +void BatchingAPIClient::gnssUpdateCallbacks(const sp<IGnssBatchingCallback>& callback) +{ + mMutex.lock(); + mGnssBatchingCbIface = callback; + mMutex.unlock(); +} + int BatchingAPIClient::getBatchSize() { LOC_LOGD("%s]: ()", __FUNCTION__); @@ -162,13 +167,16 @@ void BatchingAPIClient::onBatchingCb(size_t count, Location* location, BatchingOptions /*batchOptions*/) { LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count); - if (mGnssBatchingCbIface != nullptr && count > 0) { + mMutex.lock(); + auto cbiface = mGnssBatchingCbIface; + mMutex.unlock(); + if (cbiface != nullptr && count > 0) { hidl_vec<GnssLocation> locationVec; locationVec.resize(count); for (size_t i = 0; i < count; i++) { convertGnssLocation(location[i], locationVec[i]); } - auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec); + auto r = cbiface->gnssLocationBatchCb(locationVec); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s", __func__, r.description().c_str()); diff --git a/android/1.0/location_api/BatchingAPIClient.h b/android/1.0/location_api/BatchingAPIClient.h index c3b0a7b..2a1a663 100644 --- a/android/1.0/location_api/BatchingAPIClient.h +++ b/android/1.0/location_api/BatchingAPIClient.h @@ -30,6 +30,7 @@ #ifndef BATCHING_API_CLINET_H #define BATCHING_API_CLINET_H +#include <mutex> #include <android/hardware/gnss/1.0/IGnssBatching.h> #include <android/hardware/gnss/1.0/IGnssBatchingCallback.h> #include <pthread.h> @@ -46,6 +47,7 @@ class BatchingAPIClient : public LocationAPIClientBase { public: BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback); + void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback); int getBatchSize(); int startSession(const V1_0::IGnssBatching::Options& options); int updateSessionOptions(const V1_0::IGnssBatching::Options& options); @@ -61,7 +63,7 @@ public: private: ~BatchingAPIClient(); - + std::mutex mMutex; sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface; uint32_t mDefaultId; LocationCapabilitiesMask mLocationCapabilitiesMask; diff --git a/android/1.0/location_api/GeofenceAPIClient.cpp b/android/1.0/location_api/GeofenceAPIClient.cpp index 774a049..4d703f8 100644 --- a/android/1.0/location_api/GeofenceAPIClient.cpp +++ b/android/1.0/location_api/GeofenceAPIClient.cpp @@ -59,17 +59,15 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locationCallbacks.batchingCb = nullptr; locationCallbacks.geofenceBreachCb = nullptr; - if (mGnssGeofencingCbIface != nullptr) { - locationCallbacks.geofenceBreachCb = + locationCallbacks.geofenceBreachCb = [this](GeofenceBreachNotification geofenceBreachNotification) { - onGeofenceBreachCb(geofenceBreachNotification); - }; + onGeofenceBreachCb(geofenceBreachNotification); + }; - locationCallbacks.geofenceStatusCb = + locationCallbacks.geofenceStatusCb = [this](GeofenceStatusNotification geofenceStatusNotification) { - onGeofenceStatusCb(geofenceStatusNotification); - }; - } + onGeofenceStatusCb(geofenceStatusNotification); + }; locationCallbacks.gnssLocationInfoCb = nullptr; locationCallbacks.gnssNiCb = nullptr; @@ -80,6 +78,12 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locAPISetCallbacks(locationCallbacks); } +void GeofenceAPIClient::upcateCallback(const sp<IGnssGeofenceCallback>& callback) { + mMutex.lock(); + mGnssGeofencingCbIface = callback; + mMutex.unlock(); +} + void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms) @@ -135,14 +139,17 @@ void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id) void GeofenceAPIClient::geofenceRemoveAll() { LOC_LOGD("%s]", __FUNCTION__); - // TODO locAPIRemoveAllGeofences(); + locAPIRemoveAllGeofences(); } // callbacks void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < geofenceBreachNotification.count; i++) { GnssLocation gnssLocation; convertGnssLocation(geofenceBreachNotification.location, gnssLocation); @@ -158,7 +165,7 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr continue; } - auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb( + auto r = cbIface->gnssGeofenceTransitionCb( geofenceBreachNotification.ids[i], gnssLocation, transition, static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp)); if (!r.isOk()) { @@ -172,7 +179,10 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) { LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { IGnssGeofenceCallback::GeofenceAvailability status = IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE; if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) { @@ -180,7 +190,7 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt } GnssLocation gnssLocation; memset(&gnssLocation, 0, sizeof(GnssLocation)); - auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation); + auto r = cbIface->gnssGeofenceStatusCb(status, gnssLocation); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s", __func__, r.description().c_str()); @@ -191,7 +201,10 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -199,7 +212,7 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_EXISTS) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS; - auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status); + auto r = cbIface->gnssGeofenceAddCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s", __func__, r.description().c_str()); @@ -211,7 +224,10 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -219,7 +235,7 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status); + auto r = cbIface->gnssGeofenceRemoveCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s", __func__, r.description().c_str()); @@ -231,7 +247,10 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -239,7 +258,7 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status); + auto r = cbIface->gnssGeofencePauseCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s", __func__, r.description().c_str()); @@ -251,7 +270,10 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -259,7 +281,7 @@ void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status); + auto r = cbIface->gnssGeofenceResumeCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s", __func__, r.description().c_str()); diff --git a/android/1.0/location_api/GeofenceAPIClient.h b/android/1.0/location_api/GeofenceAPIClient.h index b6a009b..ec9c93d 100644 --- a/android/1.0/location_api/GeofenceAPIClient.h +++ b/android/1.0/location_api/GeofenceAPIClient.h @@ -30,7 +30,7 @@ #ifndef GEOFENCE_API_CLINET_H #define GEOFENCE_API_CLINET_H - +#include <mutex> #include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h> #include <LocationAPIClientBase.h> @@ -46,7 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback); - + void upcateCallback(const sp<V1_0::IGnssGeofenceCallback>& callback); void geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms); @@ -65,7 +65,7 @@ public: private: virtual ~GeofenceAPIClient() = default; - + std::mutex mMutex; sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface; }; diff --git a/android/1.0/location_api/LocationUtil.cpp b/android/1.0/location_api/LocationUtil.cpp index 870a8aa..54cf91d 100644 --- a/android/1.0/location_api/LocationUtil.cpp +++ b/android/1.0/location_api/LocationUtil.cpp @@ -27,6 +27,7 @@ * */ +#include <gps_extended_c.h> #include <LocationUtil.h> namespace android { diff --git a/android/1.1/Android.mk b/android/1.1/Android.mk index ec6165c..8ed6e5e 100644 --- a/android/1.1/Android.mk +++ b/android/1.1/Android.mk @@ -43,6 +43,7 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.gnss@1.1 \ android.hardware.health@1.0 \ android.hardware.health@2.0 \ + android.hardware.health@2.1 \ android.hardware.power@1.2 \ libbase diff --git a/android/1.1/Gnss.cpp b/android/1.1/Gnss.cpp index 5ee0ed6..39e7128 100644 --- a/android/1.1/Gnss.cpp +++ b/android/1.1/Gnss.cpp @@ -83,10 +83,10 @@ static std::string getVersionString() { void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnss != nullptr) { - mGnss->getGnssInterface()->resetNetworkInfo(); - mGnss->stop(); - mGnss->cleanup(); + auto gnss = mGnss.promote(); + if (gnss != nullptr) { + gnss->getGnssInterface()->resetNetworkInfo(); + gnss->cleanup(); } } @@ -106,7 +106,7 @@ Gnss::Gnss() { // clear pending GnssConfig memset(&mPendingConfig, 0, sizeof(GnssConfig)); - mGnssDeathRecipient = new GnssDeathRecipient(this); + mGnssDeathRecipient = new GnssDeathRecipient(sGnss); } Gnss::~Gnss() { @@ -338,7 +338,7 @@ Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() { Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { ENTRY_LOG_CALLFLOW(); if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; } @@ -350,12 +350,12 @@ Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() { Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { ENTRY_LOG_CALLFLOW(); - mGnssGeofencingIface = new GnssGeofencing(); + mGnssGeofencingIface = new GnssGeofencing(mGnssGeofencingIface); return mGnssGeofencingIface; } Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() { - mGnssBatching = new GnssBatching(); + mGnssBatching = new GnssBatching(mGnssBatching); return mGnssBatching; } @@ -406,7 +406,7 @@ Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode, Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() { ENTRY_LOG_CALLFLOW(); if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; } diff --git a/android/1.1/Gnss.h b/android/1.1/Gnss.h index 15645eb..31d8823 100644 --- a/android/1.1/Gnss.h +++ b/android/1.1/Gnss.h @@ -116,11 +116,11 @@ struct Gnss : public IGnss { private: struct GnssDeathRecipient : hidl_death_recipient { - GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) { + GnssDeathRecipient(const sp<Gnss>& gnss) : mGnss(gnss) { } ~GnssDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<Gnss> mGnss; + const wp<Gnss> mGnss; }; private: diff --git a/android/1.1/GnssBatching.cpp b/android/1.1/GnssBatching.cpp index 8ab264d..b78e3b3 100644 --- a/android/1.1/GnssBatching.cpp +++ b/android/1.1/GnssBatching.cpp @@ -34,16 +34,13 @@ void GnssBatching::GnssBatchingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssBatching != nullptr) { - mGnssBatching->stop(); - mGnssBatching->cleanup(); + auto gnssBatching = mGnssBatching.promote(); + if (gnssBatching != nullptr) { + gnssBatching->stop(); + gnssBatching->cleanup(); } } -GnssBatching::GnssBatching() : mApi(nullptr) { - mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this); -} - GnssBatching::~GnssBatching() { if (mApi != nullptr) { mApi->destroy(); @@ -54,16 +51,14 @@ GnssBatching::~GnssBatching() { // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__); - mApi->destroy(); - mApi = nullptr; + if (mGnssBatchingDeathRecipient == nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(mSelf); } - mApi = new BatchingAPIClient(callback); - if (mApi == nullptr) { - LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); - return false; + if (mApi != nullptr) { + mApi->gnssUpdateCallbacks(callback); + } else { + mApi = new BatchingAPIClient(callback); } if (mGnssBatchingCbIface != nullptr) { diff --git a/android/1.1/GnssBatching.h b/android/1.1/GnssBatching.h index 8e235d8..0697ecb 100644 --- a/android/1.1/GnssBatching.h +++ b/android/1.1/GnssBatching.h @@ -44,7 +44,7 @@ using ::android::sp; class BatchingAPIClient; struct GnssBatching : public IGnssBatching { - GnssBatching(); + inline GnssBatching(const sp<GnssBatching>& self) : mSelf(self), mApi(nullptr) {} ~GnssBatching(); // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. @@ -57,15 +57,18 @@ struct GnssBatching : public IGnssBatching { private: struct GnssBatchingDeathRecipient : hidl_death_recipient { - GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) : + GnssBatchingDeathRecipient(const sp<GnssBatching>& gnssBatching) : mGnssBatching(gnssBatching) { } ~GnssBatchingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssBatching> mGnssBatching; + const wp<GnssBatching> mGnssBatching; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssBatching>& mSelf; sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr; sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr; BatchingAPIClient* mApi = nullptr; diff --git a/android/1.1/GnssGeofencing.cpp b/android/1.1/GnssGeofencing.cpp index a4aaf88..4e45ae0 100644 --- a/android/1.1/GnssGeofencing.cpp +++ b/android/1.1/GnssGeofencing.cpp @@ -34,15 +34,12 @@ void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssGeofencing != nullptr) { - mGnssGeofencing->removeAllGeofences(); + auto gnssGeofencing = mGnssGeofencing.promote(); + if (gnssGeofencing != nullptr) { + gnssGeofencing->removeAllGeofences(); } } -GnssGeofencing::GnssGeofencing() : mApi(nullptr) { - mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this); -} - GnssGeofencing::~GnssGeofencing() { if (mApi != nullptr) { mApi->destroy(); @@ -52,12 +49,15 @@ GnssGeofencing::~GnssGeofencing() { // Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow. Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGd("mApi is NOT nullptr"); - return Void(); + if (mGnssGeofencingDeathRecipient == nullptr) { + mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(mSelf); } - mApi = new GeofenceAPIClient(callback); + if (mApi != nullptr) { + mApi->upcateCallback(callback); + } else { + mApi = new GeofenceAPIClient(callback); + } if (mApi == nullptr) { LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); } diff --git a/android/1.1/GnssGeofencing.h b/android/1.1/GnssGeofencing.h index 94a73de..892bae4 100644 --- a/android/1.1/GnssGeofencing.h +++ b/android/1.1/GnssGeofencing.h @@ -40,7 +40,7 @@ using ::android::sp; class GeofenceAPIClient; struct GnssGeofencing : public IGnssGeofencing { - GnssGeofencing(); + inline GnssGeofencing(const sp<GnssGeofencing>& self) : mSelf(self), mApi(nullptr) {} ~GnssGeofencing(); /* @@ -68,15 +68,18 @@ struct GnssGeofencing : public IGnssGeofencing { private: struct GnssGeofencingDeathRecipient : hidl_death_recipient { - GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) : + GnssGeofencingDeathRecipient(const sp<GnssGeofencing>& gnssGeofencing) : mGnssGeofencing(gnssGeofencing) { } ~GnssGeofencingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssGeofencing> mGnssGeofencing; + const wp<GnssGeofencing> mGnssGeofencing; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssGeofencing>& mSelf; sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr; sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr; GeofenceAPIClient* mApi = nullptr; diff --git a/android/1.1/GnssMeasurement.cpp b/android/1.1/GnssMeasurement.cpp index 6f8c14d..a43dc11 100644 --- a/android/1.1/GnssMeasurement.cpp +++ b/android/1.1/GnssMeasurement.cpp @@ -34,14 +34,14 @@ void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssMeasurement != nullptr) { - mGnssMeasurement->close(); + auto gssMeasurement = mGnssMeasurement.promote(); + if (gssMeasurement != nullptr) { + gssMeasurement->close(); } } -GnssMeasurement::GnssMeasurement() { - mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this); - mApi = new MeasurementAPIClient(); +GnssMeasurement::GnssMeasurement(const sp<GnssMeasurement>& self) : + mSelf(self), mApi(new MeasurementAPIClient()) { } GnssMeasurement::~GnssMeasurement() { @@ -73,6 +73,9 @@ Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback( } mGnssMeasurementCbIface = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0); return mApi->measurementSetCallback(callback); @@ -119,6 +122,9 @@ Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1( } mGnssMeasurementCbIface_1_1 = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0); GnssPowerMode powerMode = enableFullTracking? diff --git a/android/1.1/GnssMeasurement.h b/android/1.1/GnssMeasurement.h index 373f0d0..bb0d10f 100644 --- a/android/1.1/GnssMeasurement.h +++ b/android/1.1/GnssMeasurement.h @@ -41,7 +41,7 @@ using ::android::sp; class MeasurementAPIClient; struct GnssMeasurement : public IGnssMeasurement { - GnssMeasurement(); + GnssMeasurement(const sp<GnssMeasurement>& self); ~GnssMeasurement(); /* @@ -59,15 +59,18 @@ struct GnssMeasurement : public IGnssMeasurement { private: struct GnssMeasurementDeathRecipient : hidl_death_recipient { - GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) : + GnssMeasurementDeathRecipient(const sp<GnssMeasurement>& gnssMeasurement) : mGnssMeasurement(gnssMeasurement) { } ~GnssMeasurementDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssMeasurement> mGnssMeasurement; + const wp<GnssMeasurement> mGnssMeasurement; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssMeasurement>& mSelf; sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr; sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr; sp<IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr; diff --git a/android/1.1/GnssNi.cpp b/android/1.1/GnssNi.cpp index 5ce9569..692ece0 100644 --- a/android/1.1/GnssNi.cpp +++ b/android/1.1/GnssNi.cpp @@ -30,15 +30,7 @@ namespace gnss { namespace V1_1 { namespace implementation { -void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { - LOC_LOGE("%s] service died. cookie: %llu, who: %p", - __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - // we do nothing here - // Gnss::GnssDeathRecipient will stop the session -} - GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) { - mGnssNiDeathRecipient = new GnssNiDeathRecipient(this); } // Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. @@ -49,14 +41,7 @@ Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) { } mGnss->setGnssNiCb(callback); - - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient); - } mGnssNiCbIface = callback; - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/); - } return Void(); } diff --git a/android/1.1/GnssNi.h b/android/1.1/GnssNi.h index 6733e5b..153656d 100644 --- a/android/1.1/GnssNi.h +++ b/android/1.1/GnssNi.h @@ -52,16 +52,6 @@ struct GnssNi : public IGnssNi { IGnssNiCallback::GnssUserResponseType userResponse) override; private: - struct GnssNiDeathRecipient : hidl_death_recipient { - GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) { - } - ~GnssNiDeathRecipient() = default; - virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssNi> mGnssNi; - }; - - private: - sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr; sp<IGnssNiCallback> mGnssNiCbIface = nullptr; Gnss* mGnss = nullptr; }; diff --git a/android/1.1/location_api/BatchingAPIClient.cpp b/android/1.1/location_api/BatchingAPIClient.cpp index 6ec27a9..0e97a97 100644 --- a/android/1.1/location_api/BatchingAPIClient.cpp +++ b/android/1.1/location_api/BatchingAPIClient.cpp @@ -67,12 +67,10 @@ BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) locationCallbacks.trackingCb = nullptr; locationCallbacks.batchingCb = nullptr; - if (mGnssBatchingCbIface != nullptr) { - locationCallbacks.batchingCb = [this](size_t count, Location* location, + locationCallbacks.batchingCb = [this](size_t count, Location* location, BatchingOptions batchOptions) { - onBatchingCb(count, location, batchOptions); - }; - } + onBatchingCb(count, location, batchOptions); + }; locationCallbacks.geofenceBreachCb = nullptr; locationCallbacks.geofenceStatusCb = nullptr; locationCallbacks.gnssLocationInfoCb = nullptr; @@ -89,6 +87,13 @@ BatchingAPIClient::~BatchingAPIClient() LOC_LOGD("%s]: ()", __FUNCTION__); } +void BatchingAPIClient::gnssUpdateCallbacks(const sp<IGnssBatchingCallback>& callback) +{ + mMutex.lock(); + mGnssBatchingCbIface = callback; + mMutex.unlock(); +} + int BatchingAPIClient::getBatchSize() { LOC_LOGD("%s]: ()", __FUNCTION__); @@ -162,13 +167,16 @@ void BatchingAPIClient::onBatchingCb(size_t count, Location* location, BatchingOptions /*batchOptions*/) { LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count); - if (mGnssBatchingCbIface != nullptr && count > 0) { + mMutex.lock(); + auto cbiface = mGnssBatchingCbIface; + mMutex.unlock(); + if (cbiface != nullptr && count > 0) { hidl_vec<GnssLocation> locationVec; locationVec.resize(count); for (size_t i = 0; i < count; i++) { convertGnssLocation(location[i], locationVec[i]); } - auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec); + auto r = cbiface->gnssLocationBatchCb(locationVec); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s", __func__, r.description().c_str()); diff --git a/android/1.1/location_api/BatchingAPIClient.h b/android/1.1/location_api/BatchingAPIClient.h index 4c90626..7063b46 100644 --- a/android/1.1/location_api/BatchingAPIClient.h +++ b/android/1.1/location_api/BatchingAPIClient.h @@ -30,6 +30,7 @@ #ifndef BATCHING_API_CLINET_H #define BATCHING_API_CLINET_H +#include <mutex> #include <android/hardware/gnss/1.0/IGnssBatching.h> #include <android/hardware/gnss/1.0/IGnssBatchingCallback.h> #include <pthread.h> @@ -46,6 +47,7 @@ class BatchingAPIClient : public LocationAPIClientBase { public: BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback); + void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback); int getBatchSize(); int startSession(const V1_0::IGnssBatching::Options& options); int updateSessionOptions(const V1_0::IGnssBatching::Options& options); @@ -61,7 +63,7 @@ public: private: ~BatchingAPIClient(); - + std::mutex mMutex; sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface; uint32_t mDefaultId; LocationCapabilitiesMask mLocationCapabilitiesMask; diff --git a/android/1.1/location_api/GeofenceAPIClient.cpp b/android/1.1/location_api/GeofenceAPIClient.cpp index 93d175e..d828c69 100644 --- a/android/1.1/location_api/GeofenceAPIClient.cpp +++ b/android/1.1/location_api/GeofenceAPIClient.cpp @@ -59,17 +59,15 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locationCallbacks.batchingCb = nullptr; locationCallbacks.geofenceBreachCb = nullptr; - if (mGnssGeofencingCbIface != nullptr) { - locationCallbacks.geofenceBreachCb = + locationCallbacks.geofenceBreachCb = [this](GeofenceBreachNotification geofenceBreachNotification) { - onGeofenceBreachCb(geofenceBreachNotification); - }; + onGeofenceBreachCb(geofenceBreachNotification); + }; - locationCallbacks.geofenceStatusCb = + locationCallbacks.geofenceStatusCb = [this](GeofenceStatusNotification geofenceStatusNotification) { - onGeofenceStatusCb(geofenceStatusNotification); - }; - } + onGeofenceStatusCb(geofenceStatusNotification); + }; locationCallbacks.gnssLocationInfoCb = nullptr; locationCallbacks.gnssNiCb = nullptr; @@ -80,6 +78,12 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locAPISetCallbacks(locationCallbacks); } +void GeofenceAPIClient::upcateCallback(const sp<IGnssGeofenceCallback>& callback) { + mMutex.lock(); + mGnssGeofencingCbIface = callback; + mMutex.unlock(); +} + void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms) @@ -135,14 +139,17 @@ void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id) void GeofenceAPIClient::geofenceRemoveAll() { LOC_LOGD("%s]", __FUNCTION__); - // TODO locAPIRemoveAllGeofences(); + locAPIRemoveAllGeofences(); } // callbacks void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < geofenceBreachNotification.count; i++) { GnssLocation gnssLocation; convertGnssLocation(geofenceBreachNotification.location, gnssLocation); @@ -158,7 +165,7 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr continue; } - auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb( + auto r = cbIface->gnssGeofenceTransitionCb( geofenceBreachNotification.ids[i], gnssLocation, transition, static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp)); if (!r.isOk()) { @@ -172,7 +179,10 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) { LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { IGnssGeofenceCallback::GeofenceAvailability status = IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE; if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) { @@ -180,7 +190,7 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt } GnssLocation gnssLocation; memset(&gnssLocation, 0, sizeof(GnssLocation)); - auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation); + auto r = cbIface->gnssGeofenceStatusCb(status, gnssLocation); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s", __func__, r.description().c_str()); @@ -191,7 +201,10 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -199,7 +212,7 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_EXISTS) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS; - auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status); + auto r = cbIface->gnssGeofenceAddCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s", __func__, r.description().c_str()); @@ -211,7 +224,10 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -219,7 +235,7 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status); + auto r = cbIface->gnssGeofenceRemoveCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s", __func__, r.description().c_str()); @@ -231,7 +247,10 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -239,7 +258,7 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status); + auto r = cbIface->gnssGeofencePauseCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s", __func__, r.description().c_str()); @@ -251,7 +270,10 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -259,7 +281,7 @@ void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status); + auto r = cbIface->gnssGeofenceResumeCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s", __func__, r.description().c_str()); diff --git a/android/1.1/location_api/GeofenceAPIClient.h b/android/1.1/location_api/GeofenceAPIClient.h index 0ffff91..30be2c4 100644 --- a/android/1.1/location_api/GeofenceAPIClient.h +++ b/android/1.1/location_api/GeofenceAPIClient.h @@ -30,7 +30,7 @@ #ifndef GEOFENCE_API_CLINET_H #define GEOFENCE_API_CLINET_H - +#include <mutex> #include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h> #include <LocationAPIClientBase.h> @@ -46,7 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback); - + void upcateCallback(const sp<V1_0::IGnssGeofenceCallback>& callback); void geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms); @@ -65,7 +65,7 @@ public: private: virtual ~GeofenceAPIClient() = default; - + std::mutex mMutex; sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface; }; diff --git a/android/1.1/location_api/LocationUtil.cpp b/android/1.1/location_api/LocationUtil.cpp index 26fd920..7b2b12e 100644 --- a/android/1.1/location_api/LocationUtil.cpp +++ b/android/1.1/location_api/LocationUtil.cpp @@ -27,6 +27,7 @@ * */ +#include <gps_extended_c.h> #include <LocationUtil.h> namespace android { diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp index 9825569..48afc1e 100644 --- a/android/2.0/Gnss.cpp +++ b/android/2.0/Gnss.cpp @@ -83,9 +83,10 @@ static std::string getVersionString() { void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnss != nullptr) { - mGnss->getGnssInterface()->resetNetworkInfo(); - mGnss->cleanup(); + auto gnss = mGnss.promote(); + if (gnss != nullptr) { + gnss->getGnssInterface()->resetNetworkInfo(); + gnss->cleanup(); } } @@ -104,7 +105,7 @@ Gnss::Gnss() { loc_extn_battery_properties_listener_init(location_on_battery_status_changed); // clear pending GnssConfig memset(&mPendingConfig, 0, sizeof(GnssConfig)); - mGnssDeathRecipient = new GnssDeathRecipient(this); + mGnssDeathRecipient = new GnssDeathRecipient(sGnss); } Gnss::~Gnss() { @@ -364,7 +365,7 @@ Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() { Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { ENTRY_LOG_CALLFLOW(); if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; } @@ -379,7 +380,7 @@ Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() { Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { ENTRY_LOG_CALLFLOW(); if (mGnssGeofencingIface == nullptr) { - mGnssGeofencingIface = new GnssGeofencing(); + mGnssGeofencingIface = new GnssGeofencing(mGnssGeofencingIface); } return mGnssGeofencingIface; } @@ -387,7 +388,7 @@ Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() { ENTRY_LOG_CALLFLOW(); if (mGnssBatching == nullptr) { - mGnssBatching = new GnssBatching(); + mGnssBatching = new GnssBatching(mGnssBatching); } return mGnssBatching; } @@ -483,7 +484,7 @@ Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() { return nullptr; #else if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; #endif } @@ -620,7 +621,7 @@ Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() { return nullptr; #else if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; #endif } diff --git a/android/2.0/Gnss.h b/android/2.0/Gnss.h index a403d61..d1eefea 100644 --- a/android/2.0/Gnss.h +++ b/android/2.0/Gnss.h @@ -145,25 +145,25 @@ struct Gnss : public IGnss { private: struct GnssDeathRecipient : hidl_death_recipient { - GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) { + GnssDeathRecipient(const sp<Gnss>& gnss) : mGnss(gnss) { } ~GnssDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<Gnss> mGnss; + const wp<Gnss> mGnss; }; private: sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr; sp<V1_0::IGnssNi> mGnssNi = nullptr; - sp<V1_0::IGnssGeofencing> mGnssGeofencingIface = nullptr; + sp<GnssGeofencing> mGnssGeofencingIface = nullptr; sp<V1_0::IAGnss> mAGnssIface = nullptr; sp<V1_0::IGnssCallback> mGnssCbIface = nullptr; sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr; sp<V1_1::IGnssCallback> mGnssCbIface_1_1 = nullptr; sp<V2_0::IAGnss> mAGnssIface_2_0 = nullptr; sp<V2_0::IAGnssRil> mGnssRil = nullptr; - sp<V2_0::IGnssMeasurement> mGnssMeasurement = nullptr; + sp<GnssMeasurement> mGnssMeasurement = nullptr; sp<V2_0::IGnssConfiguration> mGnssConfig = nullptr; sp<V2_0::IGnssBatching> mGnssBatching = nullptr; sp<V2_0::IGnssDebug> mGnssDebug = nullptr; diff --git a/android/2.0/GnssBatching.cpp b/android/2.0/GnssBatching.cpp index 6a2a09e..6bc79b2 100644 --- a/android/2.0/GnssBatching.cpp +++ b/android/2.0/GnssBatching.cpp @@ -34,14 +34,6 @@ void GnssBatching::GnssBatchingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssBatching != nullptr) { - mGnssBatching->stop(); - mGnssBatching->cleanup(); - } -} - -GnssBatching::GnssBatching() : mApi(nullptr) { - mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this); } GnssBatching::~GnssBatching() { @@ -54,16 +46,14 @@ GnssBatching::~GnssBatching() { // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. Return<bool> GnssBatching::init(const sp<V1_0::IGnssBatchingCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__); - mApi->destroy(); - mApi = nullptr; + if (mGnssBatchingDeathRecipient == nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(mSelf); } - mApi = new BatchingAPIClient(callback); - if (mApi == nullptr) { - LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); - return false; + if (mApi != nullptr) { + mApi->gnssUpdateCallbacks(callback); + } else { + mApi = new BatchingAPIClient(callback); } if (mGnssBatchingCbIface != nullptr) { @@ -133,16 +123,14 @@ Return<void> GnssBatching::cleanup() { // Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow. Return<bool> GnssBatching::init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__); - mApi->destroy(); - mApi = nullptr; + if (mGnssBatchingDeathRecipient == nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(mSelf); } - mApi = new BatchingAPIClient(callback); - if (mApi == nullptr) { - LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); - return false; + if (mApi != nullptr) { + mApi->gnssUpdateCallbacks_2_0(callback); + } else { + mApi = new BatchingAPIClient(callback); } if (mGnssBatchingCbIface_2_0 != nullptr) { diff --git a/android/2.0/GnssBatching.h b/android/2.0/GnssBatching.h index 4c8d1db..d8d689d 100644 --- a/android/2.0/GnssBatching.h +++ b/android/2.0/GnssBatching.h @@ -44,7 +44,7 @@ using ::android::sp; class BatchingAPIClient; struct GnssBatching : public IGnssBatching { - GnssBatching(); + inline GnssBatching(const sp<IGnssBatching>& self) : mSelf(self), mApi(nullptr) {} ~GnssBatching(); // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. @@ -60,15 +60,18 @@ struct GnssBatching : public IGnssBatching { private: struct GnssBatchingDeathRecipient : hidl_death_recipient { - GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) : + GnssBatchingDeathRecipient(const sp<IGnssBatching>& gnssBatching) : mGnssBatching(gnssBatching) { } ~GnssBatchingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssBatching> mGnssBatching; + const wp<IGnssBatching> mGnssBatching; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<IGnssBatching>& mSelf; sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr; sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface = nullptr; BatchingAPIClient* mApi = nullptr; diff --git a/android/2.0/GnssGeofencing.cpp b/android/2.0/GnssGeofencing.cpp index b6fc94b..44c514b 100644 --- a/android/2.0/GnssGeofencing.cpp +++ b/android/2.0/GnssGeofencing.cpp @@ -34,15 +34,12 @@ void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssGeofencing != nullptr) { - mGnssGeofencing->removeAllGeofences(); + auto gnssGeofencing = mGnssGeofencing.promote(); + if (gnssGeofencing != nullptr) { + gnssGeofencing->removeAllGeofences(); } } -GnssGeofencing::GnssGeofencing() : mApi(nullptr) { - mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this); -} - GnssGeofencing::~GnssGeofencing() { if (mApi != nullptr) { mApi->destroy(); @@ -52,12 +49,15 @@ GnssGeofencing::~GnssGeofencing() { // Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow. Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGd("mApi is NOT nullptr"); - return Void(); + if (mGnssGeofencingDeathRecipient == nullptr) { + mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(mSelf); } - mApi = new GeofenceAPIClient(callback); + if (mApi != nullptr) { + mApi->upcateCallback(callback); + } else { + mApi = new GeofenceAPIClient(callback); + } if (mApi == nullptr) { LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); } diff --git a/android/2.0/GnssGeofencing.h b/android/2.0/GnssGeofencing.h index caa56d0..42b22ac 100644 --- a/android/2.0/GnssGeofencing.h +++ b/android/2.0/GnssGeofencing.h @@ -40,7 +40,7 @@ using ::android::sp; class GeofenceAPIClient; struct GnssGeofencing : public IGnssGeofencing { - GnssGeofencing(); + inline GnssGeofencing(const sp<GnssGeofencing>& self) : mSelf(self), mApi(nullptr) {} ~GnssGeofencing(); /* @@ -68,15 +68,18 @@ struct GnssGeofencing : public IGnssGeofencing { private: struct GnssGeofencingDeathRecipient : hidl_death_recipient { - GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) : + GnssGeofencingDeathRecipient(const sp<GnssGeofencing>& gnssGeofencing) : mGnssGeofencing(gnssGeofencing) { } ~GnssGeofencingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssGeofencing> mGnssGeofencing; + const wp<GnssGeofencing> mGnssGeofencing; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssGeofencing>& mSelf; sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr; sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr; GeofenceAPIClient* mApi = nullptr; diff --git a/android/2.0/GnssMeasurement.cpp b/android/2.0/GnssMeasurement.cpp index 6cb55ca..a1c22cf 100644 --- a/android/2.0/GnssMeasurement.cpp +++ b/android/2.0/GnssMeasurement.cpp @@ -34,14 +34,14 @@ void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssMeasurement != nullptr) { - mGnssMeasurement->close(); + auto gssMeasurement = mGnssMeasurement.promote(); + if (gssMeasurement != nullptr) { + gssMeasurement->close(); } } -GnssMeasurement::GnssMeasurement() { - mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this); - mApi = new MeasurementAPIClient(); +GnssMeasurement::GnssMeasurement(const sp<GnssMeasurement>& self) : + mSelf(self), mApi(new MeasurementAPIClient()) { } GnssMeasurement::~GnssMeasurement() { @@ -74,6 +74,9 @@ Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback( clearInterfaces(); mGnssMeasurementCbIface = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0); return mApi->measurementSetCallback(callback); @@ -129,6 +132,9 @@ Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1( clearInterfaces(); mGnssMeasurementCbIface_1_1 = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0); GnssPowerMode powerMode = enableFullTracking? @@ -160,6 +166,9 @@ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallba clearInterfaces(); mGnssMeasurementCbIface_2_0 = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0); GnssPowerMode powerMode = enableFullTracking ? diff --git a/android/2.0/GnssMeasurement.h b/android/2.0/GnssMeasurement.h index 7fa66b4..95abc97 100644 --- a/android/2.0/GnssMeasurement.h +++ b/android/2.0/GnssMeasurement.h @@ -39,7 +39,7 @@ using ::android::sp; class MeasurementAPIClient; struct GnssMeasurement : public V2_0::IGnssMeasurement { - GnssMeasurement(); + GnssMeasurement(const sp<GnssMeasurement>& self); ~GnssMeasurement(); /* @@ -61,15 +61,18 @@ struct GnssMeasurement : public V2_0::IGnssMeasurement { bool enableFullTracking) override; private: struct GnssMeasurementDeathRecipient : hidl_death_recipient { - GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) : + GnssMeasurementDeathRecipient(const sp<GnssMeasurement>& gnssMeasurement) : mGnssMeasurement(gnssMeasurement) { } ~GnssMeasurementDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssMeasurement> mGnssMeasurement; + const wp<GnssMeasurement> mGnssMeasurement; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssMeasurement>& mSelf; sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr; sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr; sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr; diff --git a/android/2.0/GnssNi.cpp b/android/2.0/GnssNi.cpp index d65a488..7201288 100644 --- a/android/2.0/GnssNi.cpp +++ b/android/2.0/GnssNi.cpp @@ -30,15 +30,7 @@ namespace gnss { namespace V2_0 { namespace implementation { -void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { - LOC_LOGE("%s] service died. cookie: %llu, who: %p", - __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - // we do nothing here - // Gnss::GnssDeathRecipient will stop the session -} - GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) { - mGnssNiDeathRecipient = new GnssNiDeathRecipient(this); } // Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. @@ -49,14 +41,7 @@ Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) { } mGnss->setGnssNiCb(callback); - - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient); - } mGnssNiCbIface = callback; - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/); - } return Void(); } diff --git a/android/2.0/GnssNi.h b/android/2.0/GnssNi.h index 26e281f..7ad19a1 100644 --- a/android/2.0/GnssNi.h +++ b/android/2.0/GnssNi.h @@ -52,16 +52,6 @@ struct GnssNi : public IGnssNi { IGnssNiCallback::GnssUserResponseType userResponse) override; private: - struct GnssNiDeathRecipient : hidl_death_recipient { - GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) { - } - ~GnssNiDeathRecipient() = default; - virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssNi> mGnssNi; - }; - - private: - sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr; sp<IGnssNiCallback> mGnssNiCbIface = nullptr; Gnss* mGnss = nullptr; }; diff --git a/android/2.0/GnssVisibilityControl.cpp b/android/2.0/GnssVisibilityControl.cpp index 5a8c697..e0d784d 100644 --- a/android/2.0/GnssVisibilityControl.cpp +++ b/android/2.0/GnssVisibilityControl.cpp @@ -128,15 +128,12 @@ Return<bool> GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::and return false; } - /* If the vector is empty we need to disable all NFW clients - If there is at least one app in the vector we need to enable - all NFW clients */ - if (0 == proxyApps.size()) { - mGnss->getGnssInterface()->enableNfwLocationAccess(false); - } else { - mGnss->getGnssInterface()->enableNfwLocationAccess(true); + std::vector<std::string> apps; + for (auto i = 0; i < proxyApps.size(); i++) { + apps.push_back((std::string)proxyApps[i]); } + mGnss->getGnssInterface()->enableNfwLocationAccess(apps); return true; } /** diff --git a/android/2.0/location_api/BatchingAPIClient.cpp b/android/2.0/location_api/BatchingAPIClient.cpp index 766c37a..5f5b250 100644 --- a/android/2.0/location_api/BatchingAPIClient.cpp +++ b/android/2.0/location_api/BatchingAPIClient.cpp @@ -114,10 +114,12 @@ void BatchingAPIClient::setCallbacks() void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback) { mMutex.lock(); + bool cbWasNull = (mGnssBatchingCbIface == nullptr); mGnssBatchingCbIface = callback; + mGnssBatchingCbIface_2_0 = nullptr; mMutex.unlock(); - if (mGnssBatchingCbIface != nullptr) { + if (cbWasNull) { setCallbacks(); } } @@ -125,10 +127,12 @@ void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) { mMutex.lock(); + bool cbWasNull = (mGnssBatchingCbIface_2_0 == nullptr); + mGnssBatchingCbIface = nullptr; mGnssBatchingCbIface_2_0 = callback; mMutex.unlock(); - if (mGnssBatchingCbIface_2_0 != nullptr) { + if (cbWasNull) { setCallbacks(); } } diff --git a/android/2.0/location_api/GeofenceAPIClient.cpp b/android/2.0/location_api/GeofenceAPIClient.cpp index a93c988..f29b4ec 100644 --- a/android/2.0/location_api/GeofenceAPIClient.cpp +++ b/android/2.0/location_api/GeofenceAPIClient.cpp @@ -59,17 +59,15 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locationCallbacks.batchingCb = nullptr; locationCallbacks.geofenceBreachCb = nullptr; - if (mGnssGeofencingCbIface != nullptr) { - locationCallbacks.geofenceBreachCb = + locationCallbacks.geofenceBreachCb = [this](GeofenceBreachNotification geofenceBreachNotification) { - onGeofenceBreachCb(geofenceBreachNotification); - }; + onGeofenceBreachCb(geofenceBreachNotification); + }; - locationCallbacks.geofenceStatusCb = + locationCallbacks.geofenceStatusCb = [this](GeofenceStatusNotification geofenceStatusNotification) { - onGeofenceStatusCb(geofenceStatusNotification); - }; - } + onGeofenceStatusCb(geofenceStatusNotification); + }; locationCallbacks.gnssLocationInfoCb = nullptr; locationCallbacks.gnssNiCb = nullptr; @@ -80,6 +78,12 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locAPISetCallbacks(locationCallbacks); } +void GeofenceAPIClient::upcateCallback(const sp<IGnssGeofenceCallback>& callback) { + mMutex.lock(); + mGnssGeofencingCbIface = callback; + mMutex.unlock(); +} + void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms) @@ -135,14 +139,17 @@ void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id) void GeofenceAPIClient::geofenceRemoveAll() { LOC_LOGD("%s]", __FUNCTION__); - // TODO locAPIRemoveAllGeofences(); + locAPIRemoveAllGeofences(); } // callbacks void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) { LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceBreachNotification.count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < geofenceBreachNotification.count; i++) { GnssLocation gnssLocation; convertGnssLocation(geofenceBreachNotification.location, gnssLocation); @@ -158,7 +165,7 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr continue; } - auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb( + auto r = cbIface->gnssGeofenceTransitionCb( geofenceBreachNotification.ids[i], gnssLocation, transition, static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp)); if (!r.isOk()) { @@ -172,7 +179,10 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) { LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { IGnssGeofenceCallback::GeofenceAvailability status = IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE; if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) { @@ -180,7 +190,7 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt } GnssLocation gnssLocation; memset(&gnssLocation, 0, sizeof(GnssLocation)); - auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation); + auto r = cbIface->gnssGeofenceStatusCb(status, gnssLocation); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s", __func__, r.description().c_str()); @@ -191,7 +201,10 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -199,7 +212,7 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_EXISTS) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS; - auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status); + auto r = cbIface->gnssGeofenceAddCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s", __func__, r.description().c_str()); @@ -211,7 +224,10 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -219,7 +235,7 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status); + auto r = cbIface->gnssGeofenceRemoveCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s", __func__, r.description().c_str()); @@ -231,7 +247,10 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -239,7 +258,7 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status); + auto r = cbIface->gnssGeofencePauseCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s", __func__, r.description().c_str()); @@ -251,7 +270,10 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -259,7 +281,7 @@ void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status); + auto r = cbIface->gnssGeofenceResumeCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s", __func__, r.description().c_str()); diff --git a/android/2.0/location_api/GeofenceAPIClient.h b/android/2.0/location_api/GeofenceAPIClient.h index 5bce476..104b52b 100644 --- a/android/2.0/location_api/GeofenceAPIClient.h +++ b/android/2.0/location_api/GeofenceAPIClient.h @@ -30,7 +30,7 @@ #ifndef GEOFENCE_API_CLINET_H #define GEOFENCE_API_CLINET_H - +#include <mutex> #include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h> #include <LocationAPIClientBase.h> @@ -46,7 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback); - + void upcateCallback(const sp<V1_0::IGnssGeofenceCallback>& callback); void geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms); @@ -65,7 +65,7 @@ public: private: virtual ~GeofenceAPIClient() = default; - + std::mutex mMutex; sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface; }; diff --git a/android/2.1/Gnss.cpp b/android/2.1/Gnss.cpp index 913f1fa..ec297f9 100644 --- a/android/2.1/Gnss.cpp +++ b/android/2.1/Gnss.cpp @@ -85,9 +85,10 @@ static std::string getVersionString() { void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnss != nullptr) { - mGnss->getGnssInterface()->resetNetworkInfo(); - mGnss->cleanup(); + auto gnss = mGnss.promote(); + if (gnss != nullptr) { + gnss->getGnssInterface()->resetNetworkInfo(); + gnss->cleanup(); } } @@ -106,7 +107,7 @@ Gnss::Gnss() { loc_extn_battery_properties_listener_init(location_on_battery_status_changed); // clear pending GnssConfig memset(&mPendingConfig, 0, sizeof(GnssConfig)); - mGnssDeathRecipient = new GnssDeathRecipient(this); + mGnssDeathRecipient = new GnssDeathRecipient(sGnss); } Gnss::~Gnss() { @@ -371,7 +372,7 @@ Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() { Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { ENTRY_LOG_CALLFLOW(); if (mGnssMeasurement == nullptr) { - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); } return mGnssMeasurement; } @@ -387,7 +388,7 @@ Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() { Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { ENTRY_LOG_CALLFLOW(); if (mGnssGeofencingIface == nullptr) { - mGnssGeofencingIface = new GnssGeofencing(); + mGnssGeofencingIface = new GnssGeofencing(mGnssGeofencingIface); } return mGnssGeofencingIface; } @@ -395,7 +396,7 @@ Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() { ENTRY_LOG_CALLFLOW(); if (mGnssBatching == nullptr) { - mGnssBatching = new GnssBatching(); + mGnssBatching = new GnssBatching(mGnssBatching); } return mGnssBatching; } @@ -496,7 +497,7 @@ Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() { return nullptr; #else if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; #endif } @@ -652,7 +653,7 @@ Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() { return nullptr; #else if (mGnssMeasurement == nullptr) - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); return mGnssMeasurement; #endif } @@ -765,7 +766,7 @@ Return<bool> Gnss::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) { Return<sp<V2_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_1() { ENTRY_LOG_CALLFLOW(); if (mGnssMeasurement == nullptr) { - mGnssMeasurement = new GnssMeasurement(); + mGnssMeasurement = new GnssMeasurement(mGnssMeasurement); } return mGnssMeasurement; } diff --git a/android/2.1/Gnss.h b/android/2.1/Gnss.h index c383882..885191c 100644 --- a/android/2.1/Gnss.h +++ b/android/2.1/Gnss.h @@ -149,18 +149,18 @@ struct Gnss : public IGnss { private: struct GnssDeathRecipient : hidl_death_recipient { - GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) { + GnssDeathRecipient(const sp<Gnss>& gnss) : mGnss(gnss) { } ~GnssDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<Gnss> mGnss; + const wp<Gnss> mGnss; }; private: sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr; sp<V1_0::IGnssNi> mGnssNi = nullptr; - sp<V1_0::IGnssGeofencing> mGnssGeofencingIface = nullptr; + sp<GnssGeofencing> mGnssGeofencingIface = nullptr; sp<V1_0::IAGnss> mAGnssIface = nullptr; sp<V1_0::IGnssCallback> mGnssCbIface = nullptr; sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr; @@ -171,7 +171,7 @@ struct Gnss : public IGnss { sp<V2_0::IGnssDebug> mGnssDebug = nullptr; sp<V2_0::IGnssCallback> mGnssCbIface_2_0 = nullptr; sp<V2_1::IGnssCallback> mGnssCbIface_2_1 = nullptr; - sp<V2_1::IGnssMeasurement> mGnssMeasurement = nullptr; + sp<GnssMeasurement> mGnssMeasurement = nullptr; sp<V2_1::IGnssConfiguration> mGnssConfig = nullptr; sp<V2_1::IGnssAntennaInfo> mGnssAntennaInfo = nullptr; sp<IMeasurementCorrectionsV1_1> mGnssMeasCorr = nullptr; diff --git a/android/2.1/GnssAntennaInfo.cpp b/android/2.1/GnssAntennaInfo.cpp index 62c4cc7..e7f7d72 100644 --- a/android/2.1/GnssAntennaInfo.cpp +++ b/android/2.1/GnssAntennaInfo.cpp @@ -131,7 +131,7 @@ static void convertGnssAntennaInfo(std::vector<GnssAntennaInformation>& in, } GnssAntennaInfo::GnssAntennaInfo(Gnss* gnss) : mGnss(gnss) { - mGnssAntennaInfoDeathRecipient = new GnssAntennaInfoDeathRecipient(this); + mGnssAntennaInfoDeathRecipient = new GnssAntennaInfoDeathRecipient(); spGnssAntennaInfo = this; } diff --git a/android/2.1/GnssAntennaInfo.h b/android/2.1/GnssAntennaInfo.h index 02ddd28..cfd9bbf 100644 --- a/android/2.1/GnssAntennaInfo.h +++ b/android/2.1/GnssAntennaInfo.h @@ -67,12 +67,9 @@ struct GnssAntennaInfo : public IGnssAntennaInfo { private: struct GnssAntennaInfoDeathRecipient : hidl_death_recipient { - GnssAntennaInfoDeathRecipient(sp<GnssAntennaInfo> gnssAntennaInfo) : - mGnssAntennaInfo(gnssAntennaInfo) { - } + GnssAntennaInfoDeathRecipient() {} ~GnssAntennaInfoDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssAntennaInfo> mGnssAntennaInfo; }; private: diff --git a/android/2.1/GnssBatching.cpp b/android/2.1/GnssBatching.cpp index 73e3532..1165bd8 100644 --- a/android/2.1/GnssBatching.cpp +++ b/android/2.1/GnssBatching.cpp @@ -34,16 +34,13 @@ void GnssBatching::GnssBatchingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssBatching != nullptr) { - mGnssBatching->stop(); - mGnssBatching->cleanup(); + auto gnssBatching = mGnssBatching.promote(); + if (gnssBatching != nullptr) { + gnssBatching->stop(); + gnssBatching->cleanup(); } } -GnssBatching::GnssBatching() : mApi(nullptr) { - mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this); -} - GnssBatching::~GnssBatching() { if (mApi != nullptr) { mApi->destroy(); @@ -54,16 +51,14 @@ GnssBatching::~GnssBatching() { // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. Return<bool> GnssBatching::init(const sp<V1_0::IGnssBatchingCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__); - mApi->destroy(); - mApi = nullptr; + if (mGnssBatchingDeathRecipient == nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(mSelf); } - mApi = new BatchingAPIClient(callback); - if (mApi == nullptr) { - LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); - return false; + if (mApi != nullptr) { + mApi->gnssUpdateCallbacks(callback); + } else { + mApi = new BatchingAPIClient(callback); } if (mGnssBatchingCbIface != nullptr) { @@ -133,16 +128,14 @@ Return<void> GnssBatching::cleanup() { // Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow. Return<bool> GnssBatching::init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__); - mApi->destroy(); - mApi = nullptr; + if (mGnssBatchingDeathRecipient == nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(mSelf); } - mApi = new BatchingAPIClient(callback); - if (mApi == nullptr) { - LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); - return false; + if (mApi != nullptr) { + mApi->gnssUpdateCallbacks_2_0(callback); + } else { + mApi = new BatchingAPIClient(callback); } if (mGnssBatchingCbIface_2_0 != nullptr) { diff --git a/android/2.1/GnssBatching.h b/android/2.1/GnssBatching.h index 908748f..84cbd91 100644 --- a/android/2.1/GnssBatching.h +++ b/android/2.1/GnssBatching.h @@ -44,7 +44,7 @@ using ::android::sp; class BatchingAPIClient; struct GnssBatching : public IGnssBatching { - GnssBatching(); + inline GnssBatching(const sp<IGnssBatching>& self) : mSelf(self), mApi(nullptr) {} ~GnssBatching(); // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. @@ -60,15 +60,18 @@ struct GnssBatching : public IGnssBatching { private: struct GnssBatchingDeathRecipient : hidl_death_recipient { - GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) : + GnssBatchingDeathRecipient(const sp<IGnssBatching>& gnssBatching) : mGnssBatching(gnssBatching) { } ~GnssBatchingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssBatching> mGnssBatching; + const wp<IGnssBatching> mGnssBatching; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<IGnssBatching>& mSelf; sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr; sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface = nullptr; BatchingAPIClient* mApi = nullptr; diff --git a/android/2.1/GnssGeofencing.cpp b/android/2.1/GnssGeofencing.cpp index 0ca3e6d..d309731 100644 --- a/android/2.1/GnssGeofencing.cpp +++ b/android/2.1/GnssGeofencing.cpp @@ -34,15 +34,12 @@ void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssGeofencing != nullptr) { - mGnssGeofencing->removeAllGeofences(); + auto gnssGeofencing = mGnssGeofencing.promote(); + if (gnssGeofencing != nullptr) { + gnssGeofencing->removeAllGeofences(); } } -GnssGeofencing::GnssGeofencing() : mApi(nullptr) { - mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this); -} - GnssGeofencing::~GnssGeofencing() { if (mApi != nullptr) { mApi->destroy(); @@ -52,12 +49,15 @@ GnssGeofencing::~GnssGeofencing() { // Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow. Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) { - if (mApi != nullptr) { - LOC_LOGd("mApi is NOT nullptr"); - return Void(); + if (mGnssGeofencingDeathRecipient == nullptr) { + mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(mSelf); } - mApi = new GeofenceAPIClient(callback); + if (mApi != nullptr) { + mApi->upcateCallback(callback); + } else { + mApi = new GeofenceAPIClient(callback); + } if (mApi == nullptr) { LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); } diff --git a/android/2.1/GnssGeofencing.h b/android/2.1/GnssGeofencing.h index 1cdca12..2860134 100644 --- a/android/2.1/GnssGeofencing.h +++ b/android/2.1/GnssGeofencing.h @@ -40,7 +40,7 @@ using ::android::sp; class GeofenceAPIClient; struct GnssGeofencing : public IGnssGeofencing { - GnssGeofencing(); + inline GnssGeofencing(const sp<GnssGeofencing>& self) : mSelf(self), mApi(nullptr) {} ~GnssGeofencing(); /* @@ -68,15 +68,18 @@ struct GnssGeofencing : public IGnssGeofencing { private: struct GnssGeofencingDeathRecipient : hidl_death_recipient { - GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) : + GnssGeofencingDeathRecipient(const sp<GnssGeofencing>& gnssGeofencing) : mGnssGeofencing(gnssGeofencing) { } ~GnssGeofencingDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssGeofencing> mGnssGeofencing; + const wp<GnssGeofencing> mGnssGeofencing; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssGeofencing>& mSelf; sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr; sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr; GeofenceAPIClient* mApi = nullptr; diff --git a/android/2.1/GnssMeasurement.cpp b/android/2.1/GnssMeasurement.cpp index af75802..dfb464d 100644 --- a/android/2.1/GnssMeasurement.cpp +++ b/android/2.1/GnssMeasurement.cpp @@ -34,14 +34,14 @@ void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - if (mGnssMeasurement != nullptr) { - mGnssMeasurement->close(); + auto gssMeasurement = mGnssMeasurement.promote(); + if (gssMeasurement != nullptr) { + gssMeasurement->close(); } } -GnssMeasurement::GnssMeasurement() { - mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this); - mApi = new MeasurementAPIClient(); +GnssMeasurement::GnssMeasurement(const sp<GnssMeasurement>& self) : + mSelf(self), mApi(new MeasurementAPIClient()) { } GnssMeasurement::~GnssMeasurement() { @@ -74,6 +74,9 @@ Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback( clearInterfaces(); mGnssMeasurementCbIface = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0); return mApi->measurementSetCallback(callback); @@ -133,6 +136,9 @@ Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1( clearInterfaces(); mGnssMeasurementCbIface_1_1 = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0); GnssPowerMode powerMode = enableFullTracking? @@ -164,6 +170,9 @@ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallba clearInterfaces(); mGnssMeasurementCbIface_2_0 = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0); GnssPowerMode powerMode = enableFullTracking ? @@ -195,6 +204,9 @@ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallba clearInterfaces(); mGnssMeasurementCbIface_2_1 = callback; + if (mGnssMeasurementDeathRecipient == nullptr) { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(mSelf); + } mGnssMeasurementCbIface_2_1->linkToDeath(mGnssMeasurementDeathRecipient, 0); GnssPowerMode powerMode = enableFullTracking ? diff --git a/android/2.1/GnssMeasurement.h b/android/2.1/GnssMeasurement.h index 2ac45c6..65e4ee3 100644 --- a/android/2.1/GnssMeasurement.h +++ b/android/2.1/GnssMeasurement.h @@ -39,7 +39,7 @@ using ::android::sp; class MeasurementAPIClient; struct GnssMeasurement : public V2_1::IGnssMeasurement { - GnssMeasurement(); + GnssMeasurement(const sp<GnssMeasurement>& self); ~GnssMeasurement(); /* @@ -66,15 +66,18 @@ struct GnssMeasurement : public V2_1::IGnssMeasurement { private: struct GnssMeasurementDeathRecipient : hidl_death_recipient { - GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) : + GnssMeasurementDeathRecipient(const sp<GnssMeasurement>& gnssMeasurement) : mGnssMeasurement(gnssMeasurement) { } ~GnssMeasurementDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssMeasurement> mGnssMeasurement; + const wp<GnssMeasurement> mGnssMeasurement; }; private: + // this has to be a reference, not a copy + // because the pointer is not set when mSelf is assigned + const sp<GnssMeasurement>& mSelf; sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr; sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr; sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr; diff --git a/android/2.1/GnssNi.cpp b/android/2.1/GnssNi.cpp index ba5e8d9..4c93cea 100644 --- a/android/2.1/GnssNi.cpp +++ b/android/2.1/GnssNi.cpp @@ -30,15 +30,7 @@ namespace gnss { namespace V2_1 { namespace implementation { -void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) { - LOC_LOGE("%s] service died. cookie: %llu, who: %p", - __FUNCTION__, static_cast<unsigned long long>(cookie), &who); - // we do nothing here - // Gnss::GnssDeathRecipient will stop the session -} - GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) { - mGnssNiDeathRecipient = new GnssNiDeathRecipient(this); } // Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. @@ -49,14 +41,7 @@ Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) { } mGnss->setGnssNiCb(callback); - - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient); - } mGnssNiCbIface = callback; - if (mGnssNiCbIface != nullptr) { - mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/); - } return Void(); } diff --git a/android/2.1/GnssNi.h b/android/2.1/GnssNi.h index 9a8fb69..76efc87 100644 --- a/android/2.1/GnssNi.h +++ b/android/2.1/GnssNi.h @@ -52,16 +52,6 @@ struct GnssNi : public IGnssNi { IGnssNiCallback::GnssUserResponseType userResponse) override; private: - struct GnssNiDeathRecipient : hidl_death_recipient { - GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) { - } - ~GnssNiDeathRecipient() = default; - virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<GnssNi> mGnssNi; - }; - - private: - sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr; sp<IGnssNiCallback> mGnssNiCbIface = nullptr; Gnss* mGnss = nullptr; }; diff --git a/android/2.1/MeasurementCorrections.cpp b/android/2.1/MeasurementCorrections.cpp index 5159f2f..7dc8af3 100644 --- a/android/2.1/MeasurementCorrections.cpp +++ b/android/2.1/MeasurementCorrections.cpp @@ -73,7 +73,7 @@ void MeasurementCorrections::GnssMeasurementCorrectionsDeathRecipient::serviceDi } MeasurementCorrections::MeasurementCorrections(Gnss* gnss) : mGnss(gnss) { - mGnssMeasurementCorrectionsDeathRecipient = new GnssMeasurementCorrectionsDeathRecipient(this); + mGnssMeasurementCorrectionsDeathRecipient = new GnssMeasurementCorrectionsDeathRecipient(); spMeasurementCorrections = this; } diff --git a/android/2.1/MeasurementCorrections.h b/android/2.1/MeasurementCorrections.h index 0247231..eac148d 100644 --- a/android/2.1/MeasurementCorrections.h +++ b/android/2.1/MeasurementCorrections.h @@ -82,13 +82,9 @@ struct MeasurementCorrections : public V1_1::IMeasurementCorrections { private: mutable std::mutex mMutex; struct GnssMeasurementCorrectionsDeathRecipient : hidl_death_recipient { - GnssMeasurementCorrectionsDeathRecipient( - sp<MeasurementCorrections> gnssMeasurementCorrections) : - mGnssMeasurementCorrections(gnssMeasurementCorrections) { - } + GnssMeasurementCorrectionsDeathRecipient() = default; ~GnssMeasurementCorrectionsDeathRecipient() = default; virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override; - sp<MeasurementCorrections> mGnssMeasurementCorrections; }; Gnss* mGnss = nullptr; sp<GnssMeasurementCorrectionsDeathRecipient> mGnssMeasurementCorrectionsDeathRecipient = diff --git a/android/2.1/location_api/BatchingAPIClient.cpp b/android/2.1/location_api/BatchingAPIClient.cpp index 0c871b7..5f53e03 100644 --- a/android/2.1/location_api/BatchingAPIClient.cpp +++ b/android/2.1/location_api/BatchingAPIClient.cpp @@ -114,10 +114,12 @@ void BatchingAPIClient::setCallbacks() void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback) { mMutex.lock(); + bool cbWasNull = (mGnssBatchingCbIface == nullptr); mGnssBatchingCbIface = callback; + mGnssBatchingCbIface_2_0 = nullptr; mMutex.unlock(); - if (mGnssBatchingCbIface != nullptr) { + if (cbWasNull) { setCallbacks(); } } @@ -125,10 +127,12 @@ void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) { mMutex.lock(); + bool cbWasNull = (mGnssBatchingCbIface_2_0 == nullptr); + mGnssBatchingCbIface = nullptr; mGnssBatchingCbIface_2_0 = callback; mMutex.unlock(); - if (mGnssBatchingCbIface_2_0 != nullptr) { + if (cbWasNull) { setCallbacks(); } } diff --git a/android/2.1/location_api/GeofenceAPIClient.cpp b/android/2.1/location_api/GeofenceAPIClient.cpp index 6e63465..9bc8626 100755 --- a/android/2.1/location_api/GeofenceAPIClient.cpp +++ b/android/2.1/location_api/GeofenceAPIClient.cpp @@ -59,17 +59,15 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locationCallbacks.batchingCb = nullptr; locationCallbacks.geofenceBreachCb = nullptr; - if (mGnssGeofencingCbIface != nullptr) { - locationCallbacks.geofenceBreachCb = + locationCallbacks.geofenceBreachCb = [this](GeofenceBreachNotification geofenceBreachNotification) { - onGeofenceBreachCb(geofenceBreachNotification); - }; + onGeofenceBreachCb(geofenceBreachNotification); + }; - locationCallbacks.geofenceStatusCb = + locationCallbacks.geofenceStatusCb = [this](GeofenceStatusNotification geofenceStatusNotification) { - onGeofenceStatusCb(geofenceStatusNotification); - }; - } + onGeofenceStatusCb(geofenceStatusNotification); + }; locationCallbacks.gnssLocationInfoCb = nullptr; locationCallbacks.gnssNiCb = nullptr; @@ -80,6 +78,12 @@ GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) locAPISetCallbacks(locationCallbacks); } +void GeofenceAPIClient::upcateCallback(const sp<IGnssGeofenceCallback>& callback) { + mMutex.lock(); + mGnssGeofencingCbIface = callback; + mMutex.unlock(); +} + void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms) @@ -135,14 +139,17 @@ void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id) void GeofenceAPIClient::geofenceRemoveAll() { LOC_LOGD("%s]", __FUNCTION__); - // TODO locAPIRemoveAllGeofences(); + locAPIRemoveAllGeofences(); } // callbacks void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) { LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceBreachNotification.count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < geofenceBreachNotification.count; i++) { GnssLocation gnssLocation; convertGnssLocation(geofenceBreachNotification.location, gnssLocation); @@ -158,7 +165,7 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr continue; } - auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb( + auto r = cbIface->gnssGeofenceTransitionCb( geofenceBreachNotification.ids[i], gnssLocation, transition, static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp)); if (!r.isOk()) { @@ -172,7 +179,10 @@ void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBr void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) { LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { IGnssGeofenceCallback::GeofenceAvailability status = IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE; if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) { @@ -180,7 +190,7 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt } GnssLocation gnssLocation; memset(&gnssLocation, 0, sizeof(GnssLocation)); - auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation); + auto r = cbIface->gnssGeofenceStatusCb(status, gnssLocation); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s", __func__, r.description().c_str()); @@ -191,7 +201,10 @@ void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceSt void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -199,7 +212,7 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_EXISTS) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS; - auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status); + auto r = cbIface->gnssGeofenceAddCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s", __func__, r.description().c_str()); @@ -211,7 +224,10 @@ void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, ui void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -219,7 +235,7 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status); + auto r = cbIface->gnssGeofenceRemoveCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s", __func__, r.description().c_str()); @@ -231,7 +247,10 @@ void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -239,7 +258,7 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status); + auto r = cbIface->gnssGeofencePauseCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s", __func__, r.description().c_str()); @@ -251,7 +270,10 @@ void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); - if (mGnssGeofencingCbIface != nullptr) { + mMutex.lock(); + auto cbIface = mGnssGeofencingCbIface; + mMutex.unlock(); + if (cbIface != nullptr) { for (size_t i = 0; i < count; i++) { IGnssGeofenceCallback::GeofenceStatus status = IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; @@ -259,7 +281,7 @@ void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; - auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status); + auto r = cbIface->gnssGeofenceResumeCb(ids[i], status); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s", __func__, r.description().c_str()); diff --git a/android/2.1/location_api/GeofenceAPIClient.h b/android/2.1/location_api/GeofenceAPIClient.h index 9ed289f..7237ebe 100755 --- a/android/2.1/location_api/GeofenceAPIClient.h +++ b/android/2.1/location_api/GeofenceAPIClient.h @@ -30,7 +30,7 @@ #ifndef GEOFENCE_API_CLINET_H #define GEOFENCE_API_CLINET_H - +#include <mutex> #include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h> #include <LocationAPIClientBase.h> @@ -46,7 +46,7 @@ class GeofenceAPIClient : public LocationAPIClientBase { public: GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback); - + void upcateCallback(const sp<V1_0::IGnssGeofenceCallback>& callback); void geofenceAdd(uint32_t geofence_id, double latitude, double longitude, double radius_meters, int32_t last_transition, int32_t monitor_transitions, uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms); @@ -65,7 +65,7 @@ public: private: virtual ~GeofenceAPIClient() = default; - + std::mutex mMutex; sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface; }; |