From bece5990c7ad14fff494204e68ca251f4c9c626b Mon Sep 17 00:00:00 2001 From: Greg Kaiser Date: Mon, 9 May 2016 10:23:56 -0700 Subject: [PATCH] ContextHub: Avoid reference leaks We were leaking references in each call to onMessageReceipt(), leading us to eventually run out of references and crash. We now delete our local references prior to leaving the function. Also, since especially our message size can be quite large, we put in logic to gracefully fail if the system is out of memory. In addition, we fix up reference leaks within constructJContextHubInfo(). These were one-time leaks at initialization, so not the root cause of our crash, but still unnecessary leaks which are easily fixed. Bug: 28655628 Change-Id: I3a3dc8e069c6c1810f3152872d8d8410e8ad0683 --- ...id_hardware_location_ContextHubService.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp index 98d6b247429c6..3881d6d9e99f4 100644 --- a/core/jni/android_hardware_location_ContextHubService.cpp +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -319,14 +319,27 @@ static int onMessageReceipt(uint32_t *header, size_t headerLen, char *msg, size_ } jbyteArray jmsg = env->NewByteArray(msgLen); + if (jmsg == nullptr) { + ALOGW("Can't allocate %zu byte array", msgLen); + return -1; + } jintArray jheader = env->NewIntArray(headerLen); + if (jheader == nullptr) { + env->DeleteLocalRef(jmsg); + ALOGW("Can't allocate %zu int array", headerLen); + return -1; + } env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg); env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header); - return (env->CallIntMethod(db.jniInfo.jContextHubService, + int ret = (env->CallIntMethod(db.jniInfo.jContextHubService, db.jniInfo.contextHubServiceMsgReceiptCallback, jheader, jmsg) != 0); + env->DeleteLocalRef(jmsg); + env->DeleteLocalRef(jheader); + + return ret; } int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) { @@ -529,12 +542,15 @@ static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t jstrBuf = env->NewStringUTF(hub->name); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf); + env->DeleteLocalRef(jstrBuf); jstrBuf = env->NewStringUTF(hub->vendor); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf); + env->DeleteLocalRef(jstrBuf); jstrBuf = env->NewStringUTF(hub->toolchain); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf); + env->DeleteLocalRef(jstrBuf); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version); @@ -555,11 +571,13 @@ static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t jintBuf = env->NewIntArray(array_length(dummyConnectedSensors)); env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors); env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf); + env->DeleteLocalRef(jintBuf); // We are not getting the memory regions from the CH Hal - change this when it is available jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr); // Note the zero size above. We do not need to set any elements env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf); + env->DeleteLocalRef(jmemBuf); return jHub;