From 0c2b21bdc0c5fdcb4ea0ff2975f58465498e90bd Mon Sep 17 00:00:00 2001 From: Anil Admal Date: Fri, 3 May 2019 18:29:02 -0700 Subject: [PATCH] Cache GNSS JNI methodIds/classes at system initialization Fixes: 77808332 Test: Tested on a Pixel device Change-Id: Iaf466dceb332636e52236b9865219cc3f07e186a --- .../server/location/GnssLocationProvider.java | 12 +++++------ ...d_server_location_GnssLocationProvider.cpp | 21 ++++++++++++++++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 44228eec8e945..5f1f20294bc1c 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1597,8 +1597,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private void reportGnssServiceDied() { if (DEBUG) Log.d(TAG, "reportGnssServiceDied"); mHandler.post(() -> { - class_init_native(); - setupNativeGnssService(); + setupNativeGnssService(/* reinitializeGnssServiceHandle = */ true); if (isEnabled()) { synchronized (mLock) { mEnabled = false; @@ -2052,7 +2051,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements * this handler. */ private void handleInitialize() { - setupNativeGnssService(); + // class_init_native() already initializes the GNSS service handle during class loading. + setupNativeGnssService(/* reinitializeGnssServiceHandle = */ false); if (native_is_gnss_visibility_control_supported()) { mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper); @@ -2214,8 +2214,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements pw.append(s); } - private void setupNativeGnssService() { - native_init_once(); + private void setupNativeGnssService(boolean reinitializeGnssServiceHandle) { + native_init_once(reinitializeGnssServiceHandle); /* * A cycle of native_init() and native_cleanup() is needed so that callbacks are @@ -2244,7 +2244,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static native boolean native_is_gnss_visibility_control_supported(); - private static native void native_init_once(); + private static native void native_init_once(boolean reinitializeGnssServiceHandle); private native boolean native_init(); diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 89a1ec8507d6c..da175792268f6 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -1495,7 +1495,8 @@ struct GnssBatchingCallback_V2_0 : public IGnssBatchingCallback_V2_0 { } }; -static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { +/* Initializes the GNSS service handle. */ +static void android_location_GnssLocationProvider_set_gps_service_handle() { gnssHal_V2_0 = IGnss_V2_0::getService(); if (gnssHal_V2_0 != nullptr) { gnssHal = gnssHal_V2_0; @@ -1514,7 +1515,12 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, gnssHal = IGnss_V1_0::getService(); } -static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) { +/* One time initialization at system boot */ +static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { + // Initialize the top level gnss HAL handle. + android_location_GnssLocationProvider_set_gps_service_handle(); + + // Cache methodIDs and class IDs. method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(ZLandroid/location/Location;)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); @@ -1638,7 +1644,11 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass (jclass) env->NewGlobalRef(gnssConfiguration_halInterfaceVersionClass); method_halInterfaceVersionCtor = env->GetMethodID(class_gnssConfiguration_halInterfaceVersion, "", "(II)V"); +} +/* Initialization needed at system boot and whenever GNSS service dies. */ +static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz, + jboolean reinitializeGnssServiceHandle) { /* * Save a pointer to JVM. */ @@ -1647,6 +1657,10 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus); } + if (reinitializeGnssServiceHandle) { + android_location_GnssLocationProvider_set_gps_service_handle(); + } + if (gnssHal == nullptr) { ALOGE("Unable to get GPS service\n"); return; @@ -1871,6 +1885,7 @@ static jobject android_location_GnssConfiguration_get_gnss_configuration_version return createHalInterfaceVersionJavaObject(env, major, minor); } +/* Initialization needed each time the GPS service is shutdown. */ static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) { /* * This must be set before calling into the HAL library. @@ -3026,7 +3041,7 @@ static const JNINativeMethod sMethods[] = { android_location_GnssLocationProvider_class_init_native)}, {"native_is_supported", "()Z", reinterpret_cast( android_location_GnssLocationProvider_is_supported)}, - {"native_init_once", "()V", reinterpret_cast( + {"native_init_once", "(Z)V", reinterpret_cast( android_location_GnssLocationProvider_init_once)}, {"native_init", "()Z", reinterpret_cast(android_location_GnssLocationProvider_init)}, {"native_cleanup", "()V", reinterpret_cast(