Merge "Handle Gnss Hal service death gracefully" into pi-dev
am: 3ac00caddf

Change-Id: I948cb5334c26287dd53f1960ab49e71c02abc626
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 64750b0..4e6307d 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 @@
                         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 @@
         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 a3a7e1e..288f350 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_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 @@
 {
     // hidl_death_recipient interface
     virtual void serviceDied(uint64_t cookie, const wp<IBase>& 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 @@
             clazz,
             "reportLocationBatch",
             "([Landroid/location/Location;)V");
+    method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
 
     /*
      * Save a pointer to JVM.