OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Extracts native methods from a Java file and generates the JNI bindings. | 7 """Extracts native methods from a Java file and generates the JNI bindings. |
8 If you change this, please run and update the tests.""" | 8 If you change this, please run and update the tests.""" |
9 | 9 |
10 import collections | 10 import collections |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 return '\n'.join(ret) | 598 return '\n'.join(ret) |
599 | 599 |
600 def GetRegisterNativesImplString(self): | 600 def GetRegisterNativesImplString(self): |
601 """Returns the implementation for RegisterNatives.""" | 601 """Returns the implementation for RegisterNatives.""" |
602 template = Template("""\ | 602 template = Template("""\ |
603 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { | 603 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { |
604 ${KMETHODS} | 604 ${KMETHODS} |
605 }; | 605 }; |
606 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); | 606 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); |
607 | 607 |
608 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz.obj(), | 608 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, |
609 kMethods${JAVA_CLASS}, | 609 kMethods${JAVA_CLASS}, |
610 kMethods${JAVA_CLASS}Size) < 0) { | 610 kMethods${JAVA_CLASS}Size) < 0) { |
611 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; | 611 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
612 return false; | 612 return false; |
613 } | 613 } |
614 """) | 614 """) |
615 ret = [] | 615 ret = [] |
616 all_classes = self.GetUniqueClasses(self.natives) | 616 all_classes = self.GetUniqueClasses(self.natives) |
617 all_classes[self.class_name] = self.fully_qualified_class | 617 all_classes[self.class_name] = self.fully_qualified_class |
618 for clazz in all_classes: | 618 for clazz in all_classes: |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 JNIEnv* env${FIRST_PARAM_IN_DECLARATION}${PARAMS_IN_DECLARATION})""") | 717 JNIEnv* env${FIRST_PARAM_IN_DECLARATION}${PARAMS_IN_DECLARATION})""") |
718 function_header_template = Template("""\ | 718 function_header_template = Template("""\ |
719 ${FUNCTION_SIGNATURE} {""") | 719 ${FUNCTION_SIGNATURE} {""") |
720 function_header_with_unused_template = Template("""\ | 720 function_header_with_unused_template = Template("""\ |
721 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); | 721 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); |
722 ${FUNCTION_SIGNATURE} {""") | 722 ${FUNCTION_SIGNATURE} {""") |
723 template = Template(""" | 723 template = Template(""" |
724 static jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; | 724 static jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; |
725 ${FUNCTION_HEADER} | 725 ${FUNCTION_HEADER} |
726 /* Must call RegisterNativesImpl() */ | 726 /* Must call RegisterNativesImpl() */ |
727 DCHECK(!g_${JAVA_CLASS}_clazz.is_null()); | 727 DCHECK(g_${JAVA_CLASS}_clazz); |
728 DCHECK(g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); | 728 DCHECK(g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); |
729 ${RETURN_DECLARATION} | 729 ${RETURN_DECLARATION} |
730 ${PRE_CALL}env->Call${STATIC}${ENV_CALL}Method(${FIRST_PARAM_IN_CALL}, | 730 ${PRE_CALL}env->Call${STATIC}${ENV_CALL}Method(${FIRST_PARAM_IN_CALL}, |
731 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}${PARAMS_IN_CALL})${POST_CALL}; | 731 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}${PARAMS_IN_CALL})${POST_CALL}; |
732 ${CHECK_EXCEPTION} | 732 ${CHECK_EXCEPTION} |
733 ${RETURN_CLAUSE} | 733 ${RETURN_CLAUSE} |
734 }""") | 734 }""") |
735 if called_by_native.static: | 735 if called_by_native.static: |
736 first_param_in_declaration = '' | 736 first_param_in_declaration = '' |
737 first_param_in_call = ('g_%s_clazz.obj()' % | 737 first_param_in_call = ('g_%s_clazz' % |
738 (called_by_native.java_class_name or | 738 (called_by_native.java_class_name or |
739 self.class_name)) | 739 self.class_name)) |
740 else: | 740 else: |
741 first_param_in_declaration = ', jobject obj' | 741 first_param_in_declaration = ', jobject obj' |
742 first_param_in_call = 'obj' | 742 first_param_in_call = 'obj' |
743 params_in_declaration = self.GetCalledByNativeParamsInDeclaration( | 743 params_in_declaration = self.GetCalledByNativeParamsInDeclaration( |
744 called_by_native) | 744 called_by_native) |
745 if params_in_declaration: | 745 if params_in_declaration: |
746 params_in_declaration = ', ' + params_in_declaration | 746 params_in_declaration = ', ' + params_in_declaration |
747 params_for_call = ', '.join(param.name | 747 params_for_call = ', '.join(param.name |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 if entry.java_class_name: | 809 if entry.java_class_name: |
810 class_name = entry.java_class_name | 810 class_name = entry.java_class_name |
811 jni_class_path = self.fully_qualified_class + '$' + class_name | 811 jni_class_path = self.fully_qualified_class + '$' + class_name |
812 ret[class_name] = jni_class_path | 812 ret[class_name] = jni_class_path |
813 return ret | 813 return ret |
814 | 814 |
815 def GetClassPathDefinitions(self): | 815 def GetClassPathDefinitions(self): |
816 """Returns the ClassPath constants.""" | 816 """Returns the ClassPath constants.""" |
817 ret = [] | 817 ret = [] |
818 template = Template("""\ | 818 template = Template("""\ |
819 const char* const k${JAVA_CLASS}ClassPath = "${JNI_CLASS_PATH}";""") | 819 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") |
820 native_classes = self.GetUniqueClasses(self.natives) | 820 native_classes = self.GetUniqueClasses(self.natives) |
821 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) | 821 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) |
822 all_classes = native_classes | 822 all_classes = native_classes |
823 all_classes.update(called_by_native_classes) | 823 all_classes.update(called_by_native_classes) |
824 for clazz in all_classes: | 824 for clazz in all_classes: |
825 values = { | 825 values = { |
826 'JAVA_CLASS': clazz, | 826 'JAVA_CLASS': clazz, |
827 'JNI_CLASS_PATH': all_classes[clazz], | 827 'JNI_CLASS_PATH': all_classes[clazz], |
828 } | 828 } |
829 ret += [template.substitute(values)] | 829 ret += [template.substitute(values)] |
830 ret += '' | 830 ret += '' |
831 for clazz in called_by_native_classes: | 831 for clazz in called_by_native_classes: |
832 template = Template("""\ | 832 template = Template("""\ |
833 // Leaking this JavaRef as we cannot use LazyInstance from some threads. | 833 // Leaking this jclass as we cannot use LazyInstance from some threads. |
834 base::android::ScopedJavaGlobalRef<jclass>& | 834 jclass g_${JAVA_CLASS}_clazz = NULL;""") |
835 g_${JAVA_CLASS}_clazz = | |
836 *(new base::android::ScopedJavaGlobalRef<jclass>());""") | |
837 values = { | 835 values = { |
838 'JAVA_CLASS': clazz, | 836 'JAVA_CLASS': clazz, |
839 } | 837 } |
840 ret += [template.substitute(values)] | 838 ret += [template.substitute(values)] |
841 return '\n'.join(ret) | 839 return '\n'.join(ret) |
842 | 840 |
843 def GetFindClasses(self): | 841 def GetFindClasses(self): |
844 """Returns the imlementation of FindClass for all known classes.""" | 842 """Returns the imlementation of FindClass for all known classes.""" |
845 template = Template("""\ | 843 template = Template("""\ |
846 g_${JAVA_CLASS}_clazz.Reset( | 844 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( |
847 base::android::GetClass(env, k${JAVA_CLASS}ClassPath));""") | 845 base::android::GetUnscopedClass(env, k${JAVA_CLASS}ClassPath)));""") |
848 ret = [] | 846 ret = [] |
849 for clazz in self.GetUniqueClasses(self.called_by_natives): | 847 for clazz in self.GetUniqueClasses(self.called_by_natives): |
850 values = {'JAVA_CLASS': clazz} | 848 values = {'JAVA_CLASS': clazz} |
851 ret += [template.substitute(values)] | 849 ret += [template.substitute(values)] |
852 return '\n'.join(ret) | 850 return '\n'.join(ret) |
853 | 851 |
854 def GetMethodIDImpl(self, called_by_native): | 852 def GetMethodIDImpl(self, called_by_native): |
855 """Returns the implementation of GetMethodID.""" | 853 """Returns the implementation of GetMethodID.""" |
856 template = Template("""\ | 854 template = Template("""\ |
857 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = base::android::Get${STATIC}MethodID( | 855 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = |
858 env, g_${JAVA_CLASS}_clazz, | 856 base::android::Get${STATIC}MethodID( |
859 "${NAME}", | 857 env, g_${JAVA_CLASS}_clazz, |
860 ${JNI_SIGNATURE}); | 858 "${NAME}", |
| 859 ${JNI_SIGNATURE}); |
861 """) | 860 """) |
862 values = { | 861 values = { |
863 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, | 862 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, |
864 'NAME': called_by_native.name, | 863 'NAME': called_by_native.name, |
865 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, | 864 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, |
866 'STATIC': 'Static' if called_by_native.static else '', | 865 'STATIC': 'Static' if called_by_native.static else '', |
867 'JNI_SIGNATURE': JniSignature(called_by_native.params, | 866 'JNI_SIGNATURE': JniSignature(called_by_native.params, |
868 called_by_native.return_type, | 867 called_by_native.return_type, |
869 True) | 868 True) |
870 } | 869 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 if options.output_files: | 962 if options.output_files: |
964 output_files = input_files[len(input_files) / 2:] | 963 output_files = input_files[len(input_files) / 2:] |
965 input_files = input_files[:len(input_files) / 2] | 964 input_files = input_files[:len(input_files) / 2] |
966 CheckFilenames(input_files, output_files) | 965 CheckFilenames(input_files, output_files) |
967 GenerateJNIHeaders(input_files, output_files, options.javap_class, | 966 GenerateJNIHeaders(input_files, output_files, options.javap_class, |
968 options.namespace) | 967 options.namespace) |
969 | 968 |
970 | 969 |
971 if __name__ == '__main__': | 970 if __name__ == '__main__': |
972 sys.exit(main(sys.argv)) | 971 sys.exit(main(sys.argv)) |
OLD | NEW |