Index: base/android/jni_generator/jni_generator.py |
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py |
index 35a75101088c076c421a274dd9637830968eb2b3..5018cf53531bb205d79e7c5fc91d232abe90312a 100755 |
--- a/base/android/jni_generator/jni_generator.py |
+++ b/base/android/jni_generator/jni_generator.py |
@@ -793,6 +793,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") |
for native in self.natives: |
if native.type != 'method': |
ret += [self.GetForwardDeclaration(native)] |
+ if self.options.native_exports and ret: |
+ return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"' |
return '\n'.join(ret) |
def GetConstantFieldsString(self): |
@@ -814,6 +816,9 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") |
ret += self.GetEagerCalledByNativeMethodStubs() |
else: |
ret += self.GetLazyCalledByNativeMethodStubs() |
+ |
+ if self.options.native_exports and ret: |
+ return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"' |
return '\n'.join(ret) |
def GetLazyCalledByNativeMethodStubs(self): |
@@ -859,6 +864,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") |
def GetJNINativeMethodsString(self): |
"""Returns the implementation of the array of native methods.""" |
+ if self.options.native_exports: |
+ return '' |
template = Template("""\ |
static const JNINativeMethod kMethods${JAVA_CLASS}[] = { |
${KMETHODS} |
@@ -913,6 +920,9 @@ ${CALLED_BY_NATIVES} |
def GetRegisterNativesImplString(self): |
"""Returns the shared implementation for RegisterNatives.""" |
+ if self.options.native_exports: |
+ return '' |
+ |
template = Template("""\ |
const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); |
@@ -937,11 +947,17 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { |
return ${NAMESPACE}RegisterNativesImpl(env, clazz); |
} |
""") |
- fully_qualified_class = self.fully_qualified_class.replace('/', '_') |
+ |
+ if self.options.native_exports: |
+ java_name = JniParams.RemapClassName(self.fully_qualified_class) |
+ java_name = java_name.replace('_', '_1').replace('/', '_') |
+ else: |
+ java_name = self.fully_qualified_class.replace('/', '_') |
+ |
namespace = '' |
if self.namespace: |
namespace = self.namespace + '::' |
- values = {'FULLY_QUALIFIED_CLASS': fully_qualified_class, |
+ values = {'FULLY_QUALIFIED_CLASS': java_name, |
'INIT_NATIVE_NAME': 'native' + self.init_native.name, |
'NAMESPACE': namespace, |
'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString() |
@@ -995,23 +1011,52 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { |
for param in called_by_native.params]) |
def GetForwardDeclaration(self, native): |
- template = Template(""" |
+ template_str = """ |
static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); |
-""") |
+""" |
+ if self.options.native_exports: |
+ template_str += """ |
+__attribute__((visibility("default"))) |
+${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS}) { |
+ return ${NAME}(${PARAMS_IN_CALL}); |
+} |
+""" |
+ template = Template(template_str) |
+ params_in_call = [] |
+ if not self.options.pure_native_methods: |
+ params_in_call = ['env', 'jcaller'] |
+ params_in_call = ', '.join(params_in_call + [p.name for p in native.params]) |
+ |
+ java_name = JniParams.RemapClassName(self.fully_qualified_class) |
+ java_name = java_name.replace('_', '_1').replace('/', '_') |
+ if native.java_class_name: |
+ java_name += '_00024' + native.java_class_name |
+ |
values = {'RETURN': JavaDataTypeToC(native.return_type), |
'NAME': native.name, |
- 'PARAMS': self.GetParamsInDeclaration(native)} |
+ 'JAVA_NAME': java_name, |
+ 'PARAMS': self.GetParamsInDeclaration(native), |
+ 'PARAMS_IN_CALL': params_in_call} |
return template.substitute(values) |
def GetNativeMethodStubString(self, native): |
"""Returns stubs for native methods.""" |
- template = Template("""\ |
-static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { |
+ if self.options.native_exports: |
+ template_str = """\ |
+__attribute__((visibility("default"))) |
+${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, |
+ ${PARAMS_IN_DECLARATION}) {""" |
+ else: |
+ template_str = """\ |
+static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {""" |
+ template_str += """ |
${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); |
CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); |
return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; |
} |
-""") |
+""" |
+ |
+ template = Template(template_str) |
params = [] |
if not self.options.pure_native_methods: |
params = ['env', 'jcaller'] |
@@ -1024,9 +1069,19 @@ static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { |
post_call = '' |
if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): |
post_call = '.Release()' |
+ |
+ if self.options.native_exports: |
+ java_name = JniParams.RemapClassName(self.fully_qualified_class) |
+ java_name = java_name.replace('_', '_1').replace('/', '_') |
+ if native.java_class_name: |
+ java_name += '_00024' + native.java_class_name |
+ else: |
+ java_name = '' |
+ |
values = { |
'RETURN': return_type, |
'OPTIONAL_ERROR_RETURN': optional_error_return, |
+ 'JAVA_NAME': java_name, |
'NAME': native.name, |
'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), |
'PARAM0_NAME': native.params[0].name, |
@@ -1174,8 +1229,12 @@ ${FUNCTION_HEADER} |
const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") |
native_classes = self.GetUniqueClasses(self.natives) |
called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) |
- all_classes = native_classes |
- all_classes.update(called_by_native_classes) |
+ if self.options.native_exports: |
+ all_classes = called_by_native_classes |
+ else: |
+ all_classes = native_classes |
+ all_classes.update(called_by_native_classes) |
+ |
for clazz in all_classes: |
values = { |
'JAVA_CLASS': clazz, |
@@ -1394,6 +1453,9 @@ See SampleForTests.java for more details. |
help='The path to cpp command.') |
option_parser.add_option('--javap', default='javap', |
help='The path to javap command.') |
+ option_parser.add_option('--native_exports', action='store_true', |
+ help='Native method registration through .so ' |
+ 'exports.') |
options, args = option_parser.parse_args(argv) |
if options.jar_file: |
input_file = ExtractJarInputFile(options.jar_file, options.input_file, |