diff options
-rwxr-xr-x | base/android/jni_generator/jni_generator.py | 14 | ||||
-rwxr-xr-x | base/android/jni_generator/jni_generator_tests.py | 96 | ||||
-rw-r--r-- | build/jni_generator.gypi | 3 |
3 files changed, 105 insertions, 8 deletions
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index 782e76a..649182a 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py @@ -53,7 +53,7 @@ class NativeMethod(object): assert type(self.params) is list assert type(self.params[0]) is Param if (self.params and - self.params[0].datatype == 'int' and + self.params[0].datatype == kwargs.get('ptr_type', 'int') and self.params[0].name.startswith('native')): self.type = 'method' self.p0_type = self.params[0].name[len('native'):] @@ -290,7 +290,7 @@ def ExtractFullyQualifiedJavaClassName(java_file_name, contents): os.path.splitext(os.path.basename(java_file_name))[0]) -def ExtractNatives(contents): +def ExtractNatives(contents, ptr_type): """Returns a list of dict containing information about a native method.""" contents = contents.replace('\n', '') natives = [] @@ -307,7 +307,8 @@ def ExtractNatives(contents): native_class_name=match.group('native_class_name'), return_type=match.group('return_type'), name=match.group('name').replace('native', ''), - params=JniParams.Parse(match.group('params'))) + params=JniParams.Parse(match.group('params')), + ptr_type=ptr_type) natives += [native] return natives @@ -530,7 +531,7 @@ class JNIFromJavaSource(object): JniParams.SetFullyQualifiedClass(fully_qualified_class) JniParams.ExtractImportsAndInnerClasses(contents) jni_namespace = ExtractJNINamespace(contents) - natives = ExtractNatives(contents) + natives = ExtractNatives(contents, options.ptr_type) called_by_natives = ExtractCalledByNatives(contents) if len(natives) == 0 and len(called_by_natives) == 0: raise SyntaxError('Unable to find any JNI methods for %s.' % @@ -1073,6 +1074,11 @@ See SampleForTests.java for more details. option_parser.add_option('--script_name', default=GetScriptName(), help='The name of this script in the generated ' 'header.') + option_parser.add_option('--ptr_type', default='int', + type='choice', choices=['int', 'long'], + help='The type used to represent native pointers in ' + 'Java code. For 32-bit, use int; ' + 'for 64-bit, use long.') options, args = option_parser.parse_args(argv) if options.jar_file: input_file = ExtractJarInputFile(options.jar_file, options.input_file, diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py index bf78d9c..cb32501 100755 --- a/base/android/jni_generator/jni_generator_tests.py +++ b/base/android/jni_generator/jni_generator_tests.py @@ -28,6 +28,7 @@ class TestOptions(object): def __init__(self): self.namespace = None self.script_name = SCRIPT_NAME + self.ptr_type = 'int' class TestGenerator(unittest.TestCase): @@ -95,7 +96,7 @@ class TestGenerator(unittest.TestCase): double alpha, double beta, double gamma); """ jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data) - natives = jni_generator.ExtractNatives(test_data) + natives = jni_generator.ExtractNatives(test_data, 'int') golden_natives = [ NativeMethod(return_type='int', static=False, name='Init', @@ -445,7 +446,7 @@ static bool RegisterNativesImpl(JNIEnv* env) { private native int nativeInit(); } """ - natives = jni_generator.ExtractNatives(test_data) + natives = jni_generator.ExtractNatives(test_data, 'int') golden_natives = [ NativeMethod(return_type='int', static=False, name='Init', params=[], @@ -528,7 +529,7 @@ static bool RegisterNativesImpl(JNIEnv* env) { private native int nativeInit(); } """ - natives = jni_generator.ExtractNatives(test_data) + natives = jni_generator.ExtractNatives(test_data, 'int') golden_natives = [ NativeMethod(return_type='int', static=False, name='Init', params=[], @@ -634,7 +635,7 @@ static bool RegisterNativesImpl(JNIEnv* env) { } } """ - natives = jni_generator.ExtractNatives(test_data) + natives = jni_generator.ExtractNatives(test_data, 'int') golden_natives = [ NativeMethod(return_type='int', static=False, name='Init', params=[], @@ -2172,6 +2173,93 @@ class Foo { self.assertTextEquals( '[Ljava/nio/ByteBuffer;', JniParams.JavaToJni('java/nio/ByteBuffer[]')) + def testNativesLong(self): + test_options = TestOptions() + test_options.ptr_type = 'long' + test_data = """" + private native void nativeDestroy(long nativeChromeBrowserProvider); + """ + jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data) + natives = jni_generator.ExtractNatives(test_data, test_options.ptr_type) + golden_natives = [ + NativeMethod(return_type='void', static=False, name='Destroy', + params=[Param(datatype='long', + name='nativeChromeBrowserProvider')], + java_class_name=None, + type='method', + p0_type='ChromeBrowserProvider', + ptr_type=test_options.ptr_type), + ] + self.assertListEquals(golden_natives, natives) + h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', + natives, [], test_options) + golden_content = """\ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is autogenerated by +// base/android/jni_generator/jni_generator.py +// For +// org/chromium/TestJni + +#ifndef org_chromium_TestJni_JNI +#define org_chromium_TestJni_JNI + +#include <jni.h> + +#include "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" +#include "base/basictypes.h" +#include "base/logging.h" + +using base::android::ScopedJavaLocalRef; + +// Step 1: forward declarations. +namespace { +const char kTestJniClassPath[] = "org/chromium/TestJni"; +// Leaking this jclass as we cannot use LazyInstance from some threads. +jclass g_TestJni_clazz = NULL; +} // namespace + +// Step 2: method stubs. +static void Destroy(JNIEnv* env, jobject obj, + jlong nativeChromeBrowserProvider) { + DCHECK(nativeChromeBrowserProvider) << "Destroy"; + ChromeBrowserProvider* native = + reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); + return native->Destroy(env, obj); +} + +// Step 3: RegisterNatives. + +static bool RegisterNativesImpl(JNIEnv* env) { + + g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( + base::android::GetClass(env, kTestJniClassPath).obj())); + static const JNINativeMethod kMethodsTestJni[] = { + { "nativeDestroy", +"(" +"J" +")" +"V", reinterpret_cast<void*>(Destroy) }, + }; + const int kMethodsTestJniSize = arraysize(kMethodsTestJni); + + if (env->RegisterNatives(g_TestJni_clazz, + kMethodsTestJni, + kMethodsTestJniSize) < 0) { + LOG(ERROR) << "RegisterNatives failed in " << __FILE__; + return false; + } + + return true; +} + +#endif // org_chromium_TestJni_JNI +""" + self.assertTextEquals(golden_content, h.GetContent()) + if __name__ == '__main__': unittest.main() diff --git a/build/jni_generator.gypi b/build/jni_generator.gypi index 680a0ee..a6c8364 100644 --- a/build/jni_generator.gypi +++ b/build/jni_generator.gypi @@ -31,6 +31,7 @@ 'variables': { 'jni_generator': '<(DEPTH)/base/android/jni_generator/jni_generator.py', 'jni_generator_jarjar_file%': '', + 'jni_generator_ptr_type%': 'int', }, 'rules': [ { @@ -52,6 +53,8 @@ '<(optimize_jni_generation)', '--jarjar', '<(jni_generator_jarjar_file)', + '--ptr_type', + '<(jni_generator_ptr_type)', ], 'message': 'Generating JNI bindings from <(RULE_INPUT_PATH)', 'process_outputs_as_sources': 1, |