From 5205762e457257ec55c6a1352871b5dd04a1df19 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 25 Apr 2018 00:51:22 -0700 Subject: [PATCH] Handle Gnss Hal service death gracefully Bug: 37460011 Fixes: 37460011 Test: adb shell ps -A | grep 'gnss@1.0' | awk '{print $2}' | xargs kill Change-Id: I6ff675fc198ab709d50637367f0b4648b55b021f --- .../server/location/GnssLocationProvider.java | 36 ++++++++++++++++++- ...d_server_location_GnssLocationProvider.cpp | 10 +++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 64750b00368b4..4e6307dbca8ad 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1887,9 +1887,26 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt GPS_CAPABILITY_MEASUREMENTS)); mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasCapability( GPS_CAPABILITY_NAV_MESSAGES)); + restartRequests(); } }); - } + } + + private void restartRequests() { + Log.i(TAG, "restartRequests"); + + restartLocationRequest(); + mGnssMeasurementsProvider.resumeIfStarted(); + mGnssNavigationMessageProvider.resumeIfStarted(); + mGnssBatchingProvider.resumeIfStarted(); + mGnssGeofenceProvider.resumeIfStarted(); + } + + private void restartLocationRequest() { + if (DEBUG) Log.d(TAG, "restartLocationRequest"); + mStarted = false; + updateRequirements(); + } /** * Called from native code to inform us the hardware year. @@ -1909,6 +1926,23 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mHardwareModelName = modelName; } + /** + * Called from native code to inform us GNSS HAL service died. + */ + private void reportGnssServiceDied() { + if (DEBUG) Log.d(TAG, "reportGnssServiceDied"); + mHandler.post(() -> { + class_init_native(); + native_init_once(); + if (isEnabled()) { + // re-calls native_init() and other setup. + handleEnable(); + // resend configuration into the restarted HAL service. + reloadGpsProperties(mContext, mProperties); + } + }); + } + public interface GnssSystemInfoProvider { /** * Returns the year of underlying GPS hardware. diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index a3a7e1e7d1b2a..288f3509b3937 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -64,6 +64,7 @@ static jmethodID method_reportGeofenceResumeStatus; static jmethodID method_reportMeasurementData; static jmethodID method_reportNavigationMessages; static jmethodID method_reportLocationBatch; +static jmethodID method_reportGnssServiceDied; /* * Save a pointer to JavaVm to attach/detach threads executing @@ -120,10 +121,10 @@ struct GnssDeathRecipient : virtual public hidl_death_recipient { // hidl_death_recipient interface virtual void serviceDied(uint64_t cookie, const wp& who) override { - // TODO(b/37460011): implement a better death recovery mechanism without - // crashing system server process as described in go//treble-gnss-death - LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure," - " restarting system server"); + ALOGE("IGNSS hidl service failed, trying to recover..."); + + JNIEnv* env = android::AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied); } }; @@ -1177,6 +1178,7 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz, "reportLocationBatch", "([Landroid/location/Location;)V"); + method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V"); /* * Save a pointer to JVM.