summaryrefslogtreecommitdiffstats
path: root/base/android
diff options
context:
space:
mode:
authorbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-02 21:13:55 +0000
committerbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-02 21:13:55 +0000
commit3764dddb64111f17e929e76de2835a63088593b8 (patch)
tree5068f08fb7109953e993be724e3113d5f25e4af7 /base/android
parentdc544e6407ca42364b7ac9b5e79eb1ff6f3fa219 (diff)
downloadchromium_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.cc70
-rw-r--r--base/android/jni_android.h11
-rwxr-xr-xbase/android/jni_generator/jni_generator.py5
-rwxr-xr-xbase/android/jni_generator/jni_generator_tests.py22
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>",