GNSS Service handling System death
Stops all GNSS HAL operations, as system doesn't need them any more:
normal, measurements, navigation message, batching
Update default implementation to resend capabilities and system info
and corresponding VTS to enforce
Minor fixes completing the location check
Softens GPS VTS to pass with no signal (still applies better checks
if there is signal)
Bug:36291274
Bug:36066672
Bug:35678469
Bug:35799723
Fixes:36291274
Fixes:36066672
Fixes:35799723
Test: VTS test passes, GPS stops after system server is killed
Basic GPS tests (including delete Xtra) work (before VTS is run)
Change-Id: Ic2ab0f8a79b4aff26eef468615bfee97a83e672f
diff --git a/gnss/1.0/default/Gnss.cpp b/gnss/1.0/default/Gnss.cpp
index 9493737..afb659c 100644
--- a/gnss/1.0/default/Gnss.cpp
+++ b/gnss/1.0/default/Gnss.cpp
@@ -46,7 +46,11 @@
.gnss_sv_status_cb = gnssSvStatusCb,
};
-Gnss::Gnss(gps_device_t* gnssDevice) {
+uint32_t Gnss::sCapabilitiesCached = 0;
+uint16_t Gnss::sYearOfHwCached = 0;
+
+Gnss::Gnss(gps_device_t* gnssDevice) :
+ mDeathRecipient(new GnssHidlDeathRecipient(this)) {
/* Error out if an instance of the interface already exists. */
LOG_ALWAYS_FATAL_IF(sInterfaceExists);
sInterfaceExists = true;
@@ -271,6 +275,9 @@
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
+
+ // Save for reconnection when some legacy hal's don't resend this info
+ sCapabilitiesCached = capabilities;
}
void Gnss::acquireWakelockCb() {
@@ -373,6 +380,9 @@
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
+
+ // Save for reconnection when some legacy hal's don't resend this info
+ sYearOfHwCached = info->year_of_hw;
}
@@ -383,7 +393,30 @@
return false;
}
+ if (callback == nullptr) {
+ ALOGE("%s: Null callback ignored", __func__);
+ return false;
+ }
+
+ if (sGnssCbIface != NULL) {
+ ALOGW("%s called more than once. Unexpected unless test.", __func__);
+ sGnssCbIface->unlinkToDeath(mDeathRecipient);
+ }
+
sGnssCbIface = callback;
+ callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
+
+ // If this was received in the past, send it up again to refresh caller.
+ // mGnssIface will override after init() is called below, if needed
+ // (though it's unlikely the gps.h capabilities or system info will change.)
+ if (sCapabilitiesCached != 0) {
+ setCapabilitiesCb(sCapabilitiesCached);
+ }
+ if (sYearOfHwCached != 0) {
+ LegacyGnssSystemInfo info;
+ info.year_of_hw = sYearOfHwCached;
+ setSystemInfoCb(&info);
+ }
return (mGnssIface->init(&sGnssCb) == 0);
}
@@ -676,6 +709,30 @@
return mGnssBatching;
}
+void Gnss::handleHidlDeath() {
+ ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
+
+ // commands down to the HAL implementation
+ stop(); // stop ongoing GPS tracking
+ if (mGnssMeasurement != nullptr) {
+ mGnssMeasurement->close();
+ }
+ if (mGnssNavigationMessage != nullptr) {
+ mGnssNavigationMessage->close();
+ }
+ if (mGnssBatching != nullptr) {
+ mGnssBatching->stop();
+ mGnssBatching->cleanup();
+ }
+ cleanup();
+
+ /*
+ * This has died, so close it off in case (race condition) callbacks happen
+ * before HAL processes above messages.
+ */
+ sGnssCbIface = nullptr;
+}
+
IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
hw_module_t* module;
IGnss* iface = nullptr;
diff --git a/gnss/1.0/default/Gnss.h b/gnss/1.0/default/Gnss.h
index 63614fa..faf903c 100644
--- a/gnss/1.0/default/Gnss.h
+++ b/gnss/1.0/default/Gnss.h
@@ -52,7 +52,8 @@
* Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
* IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
*/
-struct Gnss : public IGnss {
+class Gnss : public IGnss {
+ public:
Gnss(gps_device_t* gnss_device);
~Gnss();
@@ -122,6 +123,22 @@
static GpsCallbacks sGnssCb;
private:
+ /*
+ * For handling system-server death while GNSS service lives on.
+ */
+ class GnssHidlDeathRecipient : public hidl_death_recipient {
+ public:
+ GnssHidlDeathRecipient(const sp<Gnss> gnss) : mGnss(gnss) {
+ }
+
+ virtual void serviceDied(uint64_t /*cookie*/,
+ const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+ mGnss->handleHidlDeath();
+ }
+ private:
+ sp<Gnss> mGnss;
+ };
+
// for wakelock consolidation, see above
static void acquireWakelockGnss();
static void releaseWakelockGnss();
@@ -129,6 +146,11 @@
static bool sWakelockHeldGnss;
static bool sWakelockHeldFused;
+ /*
+ * Cleanup for death notification
+ */
+ void handleHidlDeath();
+
sp<GnssXtra> mGnssXtraIface = nullptr;
sp<AGnssRil> mGnssRil = nullptr;
sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
@@ -139,10 +161,17 @@
sp<GnssDebug> mGnssDebug = nullptr;
sp<GnssConfiguration> mGnssConfig = nullptr;
sp<GnssBatching> mGnssBatching = nullptr;
+
+ sp<GnssHidlDeathRecipient> mDeathRecipient;
+
const GpsInterface* mGnssIface = nullptr;
static sp<IGnssCallback> sGnssCbIface;
static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
static bool sInterfaceExists;
+
+ // Values saved for resend
+ static uint32_t sCapabilitiesCached;
+ static uint16_t sYearOfHwCached;
};
extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);