From 0d4a792e8d5ebfd182acc8db7cd9b40f3bc51640 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 30 Aug 2011 12:09:43 -0700 Subject: Fix JNI for warning about failure to unlink DeathRecipients We now (a) use the right Class getName() method, and (b) look it up once at setup time rather than doing that lookup every time we want to emit the warning. Verified to work properly and no longer crash or throw or otherwise complain. Change-Id: If0767f8845588ba7f34bac21474f4e2ad5c111d6 --- core/jni/android_util_Binder.cpp | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'core/jni/android_util_Binder.cpp') diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 4cf4afa..494a2b3 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -119,6 +119,11 @@ static struct binderproxy_offsets_t } gBinderProxyOffsets; +static struct class_offsets_t +{ + jmethodID mGetName; +} gClassOffsets; + // ---------------------------------------------------------------------------- static struct parcel_offsets_t @@ -452,22 +457,18 @@ public: // Okay, something is wrong -- we have a hard reference to a live death // recipient on the VM side, but the list is being torn down. JNIEnv* env = javavm_to_jnienv(mVM); - ScopedLocalRef classRef(env, env->GetObjectClass(mObject)); - jmethodID getnameMethod = env->GetMethodID(classRef.get(), - "getName", "()Ljava/lang/String;"); - if (getnameMethod) { - ScopedLocalRef nameRef(env, - (jstring) env->CallObjectMethod(classRef.get(), getnameMethod)); - ScopedUtfChars nameUtf(env, nameRef.get()); - if (nameUtf.c_str() != NULL) { - LOGW("BinderProxy is being destroyed but the application did not call " - "unlinkToDeath to unlink all of its death recipients beforehand. " - "Releasing leaked death recipient: %s", nameUtf.c_str()); - } else { - LOGW("BinderProxy being destroyed; unable to get DR object name"); - env->ExceptionClear(); - } - } else LOGW("BinderProxy being destroyed; unable to find DR class getName"); + ScopedLocalRef objClassRef(env, env->GetObjectClass(mObject)); + ScopedLocalRef nameRef(env, + (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName)); + ScopedUtfChars nameUtf(env, nameRef.get()); + if (nameUtf.c_str() != NULL) { + LOGW("BinderProxy is being destroyed but the application did not call " + "unlinkToDeath to unlink all of its death recipients beforehand. " + "Releasing leaked death recipient: %s", nameUtf.c_str()); + } else { + LOGW("BinderProxy being destroyed; unable to get DR object name"); + env->ExceptionClear(); + } } } @@ -1230,6 +1231,11 @@ static int int_register_android_os_BinderProxy(JNIEnv* env) = env->GetFieldID(clazz, "mOrgue", "I"); assert(gBinderProxyOffsets.mOrgue); + clazz = env->FindClass("java/lang/Class"); + LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class"); + gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;"); + assert(gClassOffsets.mGetName); + return AndroidRuntime::registerNativeMethods( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); -- cgit v1.1