diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-02 21:13:55 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-02 21:13:55 +0000 |
commit | 3764dddb64111f17e929e76de2835a63088593b8 (patch) | |
tree | 5068f08fb7109953e993be724e3113d5f25e4af7 /base/android | |
parent | dc544e6407ca42364b7ac9b5e79eb1ff6f3fa219 (diff) | |
download | chromium_src-3764dddb64111f17e929e76de2835a63088593b8.zip chromium_src-3764dddb64111f17e929e76de2835a63088593b8.tar.gz chromium_src-3764dddb64111f17e929e76de2835a63088593b8.tar.bz2 |
Android: adds Get(Static)MethodIDOrNULL.
When generating JNI bindings for system classes, we try to get the ids
for methods based in the .class file in the SDK.
However, this may trigger run-time errors when trying to run on an older
SDK.
For these system classes, the JNI generator will bind using the "OrNULL"
variation.
BUG=152987
TEST=
Review URL: https://chromiumcodereview.appspot.com/10996063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159769 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/android')
-rw-r--r-- | base/android/jni_android.cc | 70 | ||||
-rw-r--r-- | base/android/jni_android.h | 11 | ||||
-rwxr-xr-x | base/android/jni_generator/jni_generator.py | 5 | ||||
-rwxr-xr-x | base/android/jni_generator/jni_generator_tests.py | 22 |
4 files changed, 79 insertions, 29 deletions
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc index d3b4e79..a34bc18 100644 --- a/base/android/jni_android.cc +++ b/base/android/jni_android.cc @@ -96,6 +96,36 @@ std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) { return ConvertJavaStringToUTF8(exception_string); } + +enum MethodType { + METHODTYPE_STATIC, + METHODTYPE_NORMAL, +}; + +enum ExceptionCheck { + EXCEPTIONCHECK_YES, + EXCEPTIONCHECK_NO, +}; + +template<MethodType method_type, ExceptionCheck exception_check> +jmethodID GetMethodIDInternal(JNIEnv* env, + jclass clazz, + const char* method_name, + const char* jni_signature) { + jmethodID method_id = method_type == METHODTYPE_STATIC ? + env->GetStaticMethodID(clazz, method_name, jni_signature) : + env->GetMethodID(clazz, method_name, jni_signature); + if (exception_check == EXCEPTIONCHECK_YES) { + CHECK(!base::android::ClearException(env) && method_id) << + "Failed to find " << + (method_type == METHODTYPE_STATIC ? "static " : "") << + "method " << method_name << " " << jni_signature; + } else if (base::android::HasException(env)) { + env->ExceptionClear(); + } + return method_id; +} + } // namespace namespace base { @@ -138,7 +168,7 @@ ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) { jclass GetUnscopedClass(JNIEnv* env, const char* class_name) { jclass clazz = env->FindClass(class_name); - CHECK(clazz && !ClearException(env)) << "Failed to find class " << class_name; + CHECK(!ClearException(env) && clazz) << "Failed to find class " << class_name; return clazz; } @@ -165,11 +195,16 @@ jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char* method_name, const char* jni_signature) { - jmethodID method_id = - env->GetMethodID(clazz, method_name, jni_signature); - CHECK(method_id && !ClearException(env)) << "Failed to find method " << - method_name << " " << jni_signature; - return method_id; + return GetMethodIDInternal<METHODTYPE_NORMAL, EXCEPTIONCHECK_YES>( + env, clazz, method_name, jni_signature); +} + +jmethodID GetMethodIDOrNull(JNIEnv* env, + jclass clazz, + const char* method_name, + const char* jni_signature) { + return GetMethodIDInternal<METHODTYPE_NORMAL, EXCEPTIONCHECK_NO>( + env, clazz, method_name, jni_signature); } jmethodID GetStaticMethodID(JNIEnv* env, @@ -184,11 +219,16 @@ jmethodID GetStaticMethodID(JNIEnv* env, jclass clazz, const char* method_name, const char* jni_signature) { - jmethodID method_id = - env->GetStaticMethodID(clazz, method_name, jni_signature); - CHECK(method_id && !ClearException(env)) << "Failed to find static method " << - method_name << " " << jni_signature; - return method_id; + return GetMethodIDInternal<METHODTYPE_STATIC, EXCEPTIONCHECK_YES>( + env, clazz, method_name, jni_signature); +} + +jmethodID GetStaticMethodIDOrNull(JNIEnv* env, + jclass clazz, + const char* method_name, + const char* jni_signature) { + return GetMethodIDInternal<METHODTYPE_STATIC, EXCEPTIONCHECK_NO>( + env, clazz, method_name, jni_signature); } bool HasMethod(JNIEnv* env, @@ -211,10 +251,8 @@ jfieldID GetFieldID(JNIEnv* env, const char* field_name, const char* jni_signature) { jfieldID field_id = env->GetFieldID(clazz.obj(), field_name, jni_signature); - CHECK(field_id && !ClearException(env)) << "Failed to find field " << + CHECK(!ClearException(env) && field_id) << "Failed to find field " << field_name << " " << jni_signature; - bool error = ClearException(env); - DCHECK(!error); return field_id; } @@ -238,10 +276,8 @@ jfieldID GetStaticFieldID(JNIEnv* env, const char* jni_signature) { jfieldID field_id = env->GetStaticFieldID(clazz.obj(), field_name, jni_signature); - CHECK(field_id && !ClearException(env)) << "Failed to find static field " << + CHECK(!ClearException(env) && field_id) << "Failed to find static field " << field_name << " " << jni_signature; - bool error = ClearException(env); - DCHECK(!error); return field_id; } diff --git a/base/android/jni_android.h b/base/android/jni_android.h index 492f11f..40e2359 100644 --- a/base/android/jni_android.h +++ b/base/android/jni_android.h @@ -71,6 +71,12 @@ jmethodID GetMethodID(JNIEnv* env, const char* method_name, const char* jni_signature); +// Unlike GetMethodID, returns NULL if the method could not be found. +jmethodID GetMethodIDOrNull(JNIEnv* env, + jclass clazz, + const char* method_name, + const char* jni_signature); + // Returns the method ID for the static method with the specified name and // signature. // This method triggers a fatal assertion if the method could not be found. @@ -86,6 +92,11 @@ jmethodID GetStaticMethodID(JNIEnv* env, const char* method_name, const char* jni_signature); +// Unlike GetStaticMethodID, returns NULL if the method could not be found. +jmethodID GetStaticMethodIDOrNull(JNIEnv* env, + jclass clazz, + const char* method_name, + const char* jni_signature); // Returns true iff |clazz| has a method with the specified name and signature. bool HasMethod(JNIEnv* env, diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index de3532f..354e33a 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py @@ -471,7 +471,7 @@ class JNIFromJavaP(object): if not match: continue self.called_by_natives += [CalledByNative( - system_class=False, + system_class=True, unchecked=False, static=False, java_class_name='', @@ -923,7 +923,7 @@ jclass g_${JAVA_CLASS}_clazz = NULL;""") """Returns the implementation of GetMethodID.""" template = Template("""\ g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = - base::android::Get${STATIC}MethodID( + base::android::Get${STATIC}MethodID${SUFFIX}( env, g_${JAVA_CLASS}_clazz, "${JNI_NAME}", ${JNI_SIGNATURE}); @@ -938,6 +938,7 @@ jclass g_${JAVA_CLASS}_clazz = NULL;""") 'JNI_NAME': jni_name, 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 'STATIC': 'Static' if called_by_native.static else '', + 'SUFFIX': 'OrNull' if called_by_native.system_class else '', 'JNI_SIGNATURE': JniSignature(called_by_native.params, jni_return_type, True) diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py index fdedc97..ba9ee21 100755 --- a/base/android/jni_generator/jni_generator_tests.py +++ b/base/android/jni_generator/jni_generator_tests.py @@ -1349,6 +1349,8 @@ static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) { } static jmethodID g_InputStream_Constructor = 0; +static ScopedJavaLocalRef<jobject> Java_InputStream_Constructor(JNIEnv* env) +__attribute__ ((unused)); static ScopedJavaLocalRef<jobject> Java_InputStream_Constructor(JNIEnv* env) { /* Must call RegisterNativesImpl() */ DCHECK(g_InputStream_clazz); @@ -1365,7 +1367,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { g_InputStream_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( base::android::GetUnscopedClass(env, kInputStreamClassPath))); g_InputStream_available = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "available", @@ -1374,7 +1376,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "I"); g_InputStream_close = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "close", @@ -1383,7 +1385,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "V"); g_InputStream_mark = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "mark", @@ -1393,7 +1395,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "V"); g_InputStream_markSupported = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "markSupported", @@ -1402,7 +1404,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "Z"); g_InputStream_readI = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "read", @@ -1411,7 +1413,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "I"); g_InputStream_readI_AB = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "read", @@ -1421,7 +1423,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "I"); g_InputStream_readI_AB_I_I = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "read", @@ -1433,7 +1435,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "I"); g_InputStream_reset = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "reset", @@ -1442,7 +1444,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "V"); g_InputStream_skip = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "skip", @@ -1452,7 +1454,7 @@ static void GetMethodIDsImpl(JNIEnv* env) { "J"); g_InputStream_Constructor = - base::android::GetMethodID( + base::android::GetMethodIDOrNull( env, g_InputStream_clazz, "<init>", |