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.