From 0ab954a3c4c8c23fc841e994eaa182d237a12333 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 4 Sep 2012 10:39:44 +0400 Subject: [PATCH] Issue #2270 OpenCV Manager fails with JNI error fixed. Local reference table overflow in JNI code fixed. (cherry picked from commit 457c8785383c89c766f613d8b581ec00ddd2a4d7) --- .../engine/jni/JNIWrapper/JavaBasedPackageManager.cpp | 11 +++++++++-- android/service/engine/jni/Tests/Tests.mk | 2 +- android/service/push_native.py | 0 android/service/test_native.py | 0 4 files changed, 10 insertions(+), 3 deletions(-) mode change 100644 => 100755 android/service/push_native.py mode change 100644 => 100755 android/service/test_native.py diff --git a/android/service/engine/jni/JNIWrapper/JavaBasedPackageManager.cpp b/android/service/engine/jni/JNIWrapper/JavaBasedPackageManager.cpp index 26b073a0a4..a146b29bbe 100644 --- a/android/service/engine/jni/JNIWrapper/JavaBasedPackageManager.cpp +++ b/android/service/engine/jni/JNIWrapper/JavaBasedPackageManager.cpp @@ -46,6 +46,7 @@ bool JavaBasedPackageManager::InstallPackage(const PackageInfo& package) LOGD("Calling java package manager with package name %s\n", package.GetFullName().c_str()); jobject jpkgname = jenv->NewStringUTF(package.GetFullName().c_str()); bool result = jenv->CallNonvirtualBooleanMethod(JavaPackageManager, jclazz, jmethod, jpkgname); + jenv->DeleteLocalRef(jpkgname); if (self_attached) { @@ -99,10 +100,14 @@ vector JavaBasedPackageManager::GetInstalledPackages() { jobject jtmp = jenv->GetObjectArrayElement(jpkgs, i); PackageInfo tmp = ConvertPackageFromJava(jtmp, jenv); + jenv->DeleteLocalRef(jtmp); + if (tmp.IsValid()) result.push_back(tmp); } + jenv->DeleteLocalRef(jpkgs); + if (self_attached) { JavaContext->DetachCurrentThread(); @@ -113,6 +118,7 @@ vector JavaBasedPackageManager::GetInstalledPackages() return result; } +// IMPORTANT: This method can be called only if thread is attached to Dalvik PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNIEnv* jenv) { jclass jclazz = jenv->GetObjectClass(package); @@ -120,11 +126,13 @@ PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNI jstring jnameobj = static_cast(jenv->GetObjectField(package, jfield)); const char* jnamestr = jenv->GetStringUTFChars(jnameobj, NULL); string name(jnamestr); + jenv->DeleteLocalRef(jnameobj); jfield = jenv->GetFieldID(jclazz, "versionName", "Ljava/lang/String;"); jstring jversionobj = static_cast(jenv->GetObjectField(package, jfield)); const char* jversionstr = jenv->GetStringUTFChars(jversionobj, NULL); string verison(jversionstr); + jenv->DeleteLocalRef(jversionobj); string path; jclazz = jenv->FindClass("android/os/Build$VERSION"); @@ -134,15 +142,14 @@ PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNI { jclazz = jenv->GetObjectClass(package); jfield = jenv->GetFieldID(jclazz, "applicationInfo", "Landroid/content/pm/ApplicationInfo;"); - jobject japp_info = jenv->GetObjectField(package, jfield); jclazz = jenv->GetObjectClass(japp_info); jfield = jenv->GetFieldID(jclazz, "nativeLibraryDir", "Ljava/lang/String;"); jstring jpathobj = static_cast(jenv->GetObjectField(japp_info, jfield)); - const char* jpathstr = jenv->GetStringUTFChars(jpathobj, NULL); path = string(jpathstr); jenv->ReleaseStringUTFChars(jpathobj, jpathstr); + jenv->DeleteLocalRef(jpathobj); } else { diff --git a/android/service/engine/jni/Tests/Tests.mk b/android/service/engine/jni/Tests/Tests.mk index 9027e15fbc..935feb323d 100644 --- a/android/service/engine/jni/Tests/Tests.mk +++ b/android/service/engine/jni/Tests/Tests.mk @@ -39,7 +39,7 @@ LOCAL_LDFLAGS = -Wl,-allow-shlib-undefined LOCAL_MODULE := OpenCVEngineTestApp -LOCAL_LDLIBS += -lz -lbinder -llog +LOCAL_LDLIBS += -lz -lbinder -llog -lutils LOCAL_SHARED_LIBRARIES += libOpenCVEngine diff --git a/android/service/push_native.py b/android/service/push_native.py old mode 100644 new mode 100755 diff --git a/android/service/test_native.py b/android/service/test_native.py old mode 100644 new mode 100755