GNSS HAL must be notified correctly when networks disconnect

When a network connection is lost, we cannot reliably get the
network connection status information from the method
ConnectivityManager.getNetworkInfo(). Sometimes, it returns
null and other times it returns network information with
incorrect connection status. It is a synchronous method and
should not be called from within an async NetworkCallback class
method such as onLost().

The GnssLocationProvider class should be modified to maintain
the network type and other information of all connected networks
reported to GNSS HAL and provide that information to GNSS HAL
when a network disconnects so that the GNSS HAL knows which
network actually disconnected.

The impact of this bug is noted in b/110186412 and b/93175534.

Fixes: 110186412
Fixes: 93175534
Test: On a Pixel device, tested XTRA/SUPL download in the
      following cases:
      WiFi/Cell OFF on boot
      1. WiFi ON only - WiFi ON, Cell ON, Cell OFF
      2. Cell ON only -  WiFi ON, Cell ON, WiFi OFF
      3. Both WiFi/Cell ON - WiFi ON, Cell ON
      4. Both WiFi/Cell ON - WiFi ON, Cell ON, Cell OFF, Cell ON
      4. Both WiFi/Cell ON - WiFi ON, Cell ON, WiFi OFF, WiFi ON
      6. Both WiFi/Cell OFF - WiFi ON, Cell ON, Cell OFF, WiFi OFF
      7. And few other sequences.

      Repeated similar test sequences with WiFi ON and
      Cell OFF on boot and with WiFi oFF and Cell ON boot.

      Reviewed the GNSS Framework/HAL log messages to confirm
      correct connect/disconnect notification to HAL. Observed
      issue noted in b/64816395.

Change-Id: I0db44108b195c6d5c75f8247fe1796951d546e56
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index b47dbfa..071d4d4 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1301,7 +1301,7 @@
     return (gnssHal != nullptr) ?  JNI_TRUE : JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
+static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
         JNIEnv* /* env */, jclass /* clazz */) {
     return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
 }
@@ -1573,7 +1573,7 @@
     env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
 }
 
-static void android_location_GnssLocationProvider_agps_data_conn_open(
+static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
         JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
     if (agnssIface == nullptr) {
         ALOGE("no AGPS interface in agps_data_conn_open");
@@ -1593,7 +1593,7 @@
     env->ReleaseStringUTFChars(apn, apnStr);
 }
 
-static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
+static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
                                                                        jobject /* obj */) {
     if (agnssIface == nullptr) {
         ALOGE("%s: AGPS interface not supported", __func__);
@@ -1606,7 +1606,7 @@
     }
 }
 
-static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
+static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
                                                                        jobject /* obj */) {
     if (agnssIface == nullptr) {
         ALOGE("%s: AGPS interface not supported", __func__);
@@ -1720,7 +1720,7 @@
     return result;
 }
 
-static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
+static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
                                                                        jobject /* obj */,
                                                                        jboolean connected,
                                                                        jint type,
@@ -2120,8 +2120,6 @@
             android_location_GnssLocationProvider_class_init_native)},
     {"native_is_supported", "()Z", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_is_supported)},
-    {"native_is_agps_ril_supported", "()Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
     {"native_is_gnss_configuration_supported", "()Z",
             reinterpret_cast<void *>(
                     android_location_gpsLocationProvider_is_gnss_configuration_supported)},
@@ -2153,15 +2151,6 @@
     {"native_inject_xtra_data",
             "([BI)V",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
-    {"native_agps_data_conn_open",
-            "(Ljava/lang/String;I)V",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
-    {"native_agps_data_conn_closed",
-            "()V",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
-    {"native_agps_data_conn_failed",
-            "()V",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
     {"native_agps_set_id",
             "(ILjava/lang/String;)V",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
@@ -2178,9 +2167,6 @@
     {"native_get_internal_state",
             "()Ljava/lang/String;",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
-    {"native_update_network_state",
-            "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
     {"native_set_supl_es",
             "(I)Z",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
@@ -2280,6 +2266,24 @@
                     android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
 };
 
+static const JNINativeMethod sNetworkConnectivityMethods[] = {
+     /* name, signature, funcPtr */
+    {"native_is_agps_ril_supported", "()Z",
+            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
+    {"native_update_network_state",
+            "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
+            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
+    {"native_agps_data_conn_open",
+            "(Ljava/lang/String;I)V",
+            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
+    {"native_agps_data_conn_closed",
+            "()V",
+            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
+    {"native_agps_data_conn_failed",
+            "()V",
+            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
+};
+
 int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
     jniRegisterNativeMethods(
             env,
@@ -2301,6 +2305,11 @@
             "com/android/server/location/GnssNavigationMessageProvider",
             sNavigationMessageMethods,
             NELEM(sNavigationMessageMethods));
+    jniRegisterNativeMethods(
+            env,
+            "com/android/server/location/GnssNetworkConnectivityHandler",
+            sNetworkConnectivityMethods,
+            NELEM(sNetworkConnectivityMethods));
     return jniRegisterNativeMethods(
             env,
             "com/android/server/location/GnssLocationProvider",