Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: base/android/jni_generator/jni_generator.py

Issue 147533004: Remove unneeded JNI registrations. (Closed) Base URL: https://git.chromium.org/chromium/src.git@master
Patch Set: Fix android webview build issues. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Extracts native methods from a Java file and generates the JNI bindings. 6 """Extracts native methods from a Java file and generates the JNI bindings.
7 If you change this, please run and update the tests.""" 7 If you change this, please run and update the tests."""
8 8
9 import collections 9 import collections
10 import errno 10 import errno
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 666
667 ${INCLUDES} 667 ${INCLUDES}
668 668
669 // Step 1: forward declarations. 669 // Step 1: forward declarations.
670 namespace { 670 namespace {
671 $CLASS_PATH_DEFINITIONS 671 $CLASS_PATH_DEFINITIONS
672 $METHOD_ID_DEFINITIONS 672 $METHOD_ID_DEFINITIONS
673 } // namespace 673 } // namespace
674 674
675 $OPEN_NAMESPACE 675 $OPEN_NAMESPACE
676 extern "C"{
676 $FORWARD_DECLARATIONS 677 $FORWARD_DECLARATIONS
677 678
678 $CONSTANT_FIELDS 679 $CONSTANT_FIELDS
679 680
680 // Step 2: method stubs. 681 // Step 2: method stubs.
681 $METHOD_STUBS 682 $METHOD_STUBS
683 };
682 684
683 // Step 3: RegisterNatives. 685 // Step 3: RegisterNatives.
684 $JNI_NATIVE_METHODS
685 $REGISTER_NATIVES 686 $REGISTER_NATIVES
686 $CLOSE_NAMESPACE 687 $CLOSE_NAMESPACE
687 $JNI_REGISTER_NATIVES
688 #endif // ${HEADER_GUARD} 688 #endif // ${HEADER_GUARD}
689 """) 689 """)
690 values = { 690 values = {
691 'SCRIPT_NAME': self.options.script_name, 691 'SCRIPT_NAME': self.options.script_name,
692 'FULLY_QUALIFIED_CLASS': self.fully_qualified_class, 692 'FULLY_QUALIFIED_CLASS': self.fully_qualified_class,
693 'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(), 693 'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(),
694 'METHOD_ID_DEFINITIONS': self.GetMethodIDDefinitionsString(), 694 'METHOD_ID_DEFINITIONS': self.GetMethodIDDefinitionsString(),
695 'FORWARD_DECLARATIONS': self.GetForwardDeclarationsString(), 695 'FORWARD_DECLARATIONS': self.GetForwardDeclarationsString(),
696 'CONSTANT_FIELDS': self.GetConstantFieldsString(), 696 'CONSTANT_FIELDS': self.GetConstantFieldsString(),
697 'METHOD_STUBS': self.GetMethodStubsString(), 697 'METHOD_STUBS': self.GetMethodStubsString(),
698 'OPEN_NAMESPACE': self.GetOpenNamespaceString(), 698 'OPEN_NAMESPACE': self.GetOpenNamespaceString(),
699 'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(),
700 'REGISTER_NATIVES': self.GetRegisterNativesString(), 699 'REGISTER_NATIVES': self.GetRegisterNativesString(),
701 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(), 700 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(),
702 'HEADER_GUARD': self.header_guard, 701 'HEADER_GUARD': self.header_guard,
703 'INCLUDES': self.GetIncludesString(), 702 'INCLUDES': self.GetIncludesString(),
704 'JNI_REGISTER_NATIVES': self.GetJNIRegisterNativesString()
705 } 703 }
706 return WrapOutput(template.substitute(values)) 704 return WrapOutput(template.substitute(values))
707 705
708 def GetClassPathDefinitionsString(self): 706 def GetClassPathDefinitionsString(self):
709 ret = [] 707 ret = []
710 ret += [self.GetClassPathDefinitions()] 708 ret += [self.GetClassPathDefinitions()]
711 return '\n'.join(ret) 709 return '\n'.join(ret)
712 710
713 def GetMethodIDDefinitionsString(self): 711 def GetMethodIDDefinitionsString(self):
714 """Returns the definition of method ids for the called by native methods.""" 712 """Returns the definition of method ids for the called by native methods."""
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 return '\n'.join('#include "%s"' % x for x in includes) 771 return '\n'.join('#include "%s"' % x for x in includes)
774 772
775 def GetKMethodsString(self, clazz): 773 def GetKMethodsString(self, clazz):
776 ret = [] 774 ret = []
777 for native in self.natives: 775 for native in self.natives:
778 if (native.java_class_name == clazz or 776 if (native.java_class_name == clazz or
779 (not native.java_class_name and clazz == self.class_name)): 777 (not native.java_class_name and clazz == self.class_name)):
780 ret += [self.GetKMethodArrayEntry(native)] 778 ret += [self.GetKMethodArrayEntry(native)]
781 return '\n'.join(ret) 779 return '\n'.join(ret)
782 780
783 def SubstituteNativeMethods(self, template):
784 """Substitutes JAVA_CLASS and KMETHODS in the provided template."""
785 ret = []
786 all_classes = self.GetUniqueClasses(self.natives)
787 all_classes[self.class_name] = self.fully_qualified_class
788 for clazz in all_classes:
789 kmethods = self.GetKMethodsString(clazz)
790 if kmethods:
791 values = {'JAVA_CLASS': clazz,
792 'KMETHODS': kmethods}
793 ret += [template.substitute(values)]
794 if not ret: return ''
795 return '\n' + '\n'.join(ret)
796
797 def GetJNINativeMethodsString(self):
798 """Returns the implementation of the array of native methods."""
799 template = Template("""\
800 static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
801 ${KMETHODS}
802 };
803 """)
804 return self.SubstituteNativeMethods(template)
805
806 def GetRegisterCalledByNativesImplString(self): 781 def GetRegisterCalledByNativesImplString(self):
807 """Returns the code for registering the called by native methods.""" 782 """Returns the code for registering the called by native methods."""
808 if not self.options.eager_called_by_natives: 783 if not self.options.eager_called_by_natives:
809 return '' 784 return ''
810 template = Template("""\ 785 template = Template("""\
811 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = ${GET_METHOD_ID_IMPL} 786 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = ${GET_METHOD_ID_IMPL}
812 if (g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} == NULL) { 787 if (g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} == NULL) {
813 return false; 788 return false;
814 } 789 }
815 """) 790 """)
816 ret = [] 791 ret = []
817 for called_by_native in self.called_by_natives: 792 for called_by_native in self.called_by_natives:
818 values = { 793 values = {
819 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, 794 'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
820 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 795 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
821 'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native), 796 'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native),
822 } 797 }
823 ret += [template.substitute(values)] 798 ret += [template.substitute(values)]
824 return '\n'.join(ret) 799 return '\n'.join(ret)
825 800
826 def GetRegisterNativesString(self): 801 def GetRegisterNativesString(self):
827 """Returns the code for RegisterNatives.""" 802 """Returns the code for RegisterNatives."""
803
804 if not self.called_by_natives and not self.options.eager_called_by_natives :
805 return ''
828 template = Template("""\ 806 template = Template("""\
829 ${REGISTER_NATIVES_SIGNATURE} { 807 ${REGISTER_NATIVES_SIGNATURE} {
830 ${CLASSES} 808 ${CLASSES}
831 ${NATIVES}
832 ${CALLED_BY_NATIVES} 809 ${CALLED_BY_NATIVES}
833 return true; 810 return true;
834 } 811 }
835 """) 812 """)
836 signature = 'static bool RegisterNativesImpl(JNIEnv* env' 813 signature = 'static bool RegisterNativesImpl(JNIEnv* env'
837 if self.init_native: 814 if self.init_native:
838 signature += ', jclass clazz)' 815 signature += ', jclass clazz)'
839 else: 816 else:
840 signature += ')' 817 signature += ')'
841 818
842 natives = self.GetRegisterNativesImplString()
843 called_by_natives = self.GetRegisterCalledByNativesImplString() 819 called_by_natives = self.GetRegisterCalledByNativesImplString()
844 values = {'REGISTER_NATIVES_SIGNATURE': signature, 820 values = {'REGISTER_NATIVES_SIGNATURE': signature,
845 'CLASSES': self.GetFindClasses(), 821 'CLASSES': self.GetFindClasses(),
846 'NATIVES': natives,
847 'CALLED_BY_NATIVES': called_by_natives, 822 'CALLED_BY_NATIVES': called_by_natives,
848 } 823 }
849 return template.substitute(values) 824 return template.substitute(values)
850 825
851 def GetRegisterNativesImplString(self):
852 """Returns the shared implementation for RegisterNatives."""
853 template = Template("""\
854 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
855
856 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz,
857 kMethods${JAVA_CLASS},
858 kMethods${JAVA_CLASS}Size) < 0) {
859 jni_generator::HandleRegistrationError(
860 env, g_${JAVA_CLASS}_clazz, __FILE__);
861 return false;
862 }
863 """)
864 return self.SubstituteNativeMethods(template)
865
866 def GetJNIRegisterNativesString(self): 826 def GetJNIRegisterNativesString(self):
867 """Returns the implementation for the JNI registration of native methods.""" 827 """Returns the implementation for the JNI registration of native methods."""
868 if not self.init_native: 828 if not self.init_native:
869 return '' 829 return ''
870 830
871 template = Template("""\ 831 template = Template("""\
872 extern "C" JNIEXPORT bool JNICALL 832 extern "C" JNIEXPORT bool JNICALL
873 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { 833 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
874 return ${NAMESPACE}RegisterNativesImpl(env, clazz); 834 return ${NAMESPACE}RegisterNativesImpl(env, clazz);
875 } 835 }
876 """) 836 """)
877 fully_qualified_class = self.fully_qualified_class.replace('/', '_') 837 fully_qualified_class = self.fully_qualified_class.replace('/', '_')
878 namespace = '' 838 namespace = ''
879 if self.namespace: 839 if self.namespace:
880 namespace = self.namespace + '::' 840 namespace = self.namespace + '::'
881 values = {'FULLY_QUALIFIED_CLASS': fully_qualified_class, 841 values = {'FULLY_QUALIFIED_CLASS': fully_qualified_class,
882 'INIT_NATIVE_NAME': 'native' + self.init_native.name, 842 'INIT_NATIVE_NAME': 'native' + self.init_native.name,
883 'NAMESPACE': namespace, 843 'NAMESPACE': namespace,
884 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString()
885 } 844 }
886 return template.substitute(values) 845 return template.substitute(values)
887 846
888 def GetOpenNamespaceString(self): 847 def GetOpenNamespaceString(self):
889 if self.namespace: 848 if self.namespace:
890 all_namespaces = ['namespace %s {' % ns 849 all_namespaces = ['namespace %s {' % ns
891 for ns in self.namespace.split('::')] 850 for ns in self.namespace.split('::')]
892 return '\n'.join(all_namespaces) 851 return '\n'.join(all_namespaces)
893 return '' 852 return ''
894 853
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 for param in native.params]) 885 for param in native.params])
927 886
928 def GetCalledByNativeParamsInDeclaration(self, called_by_native): 887 def GetCalledByNativeParamsInDeclaration(self, called_by_native):
929 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' + 888 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' +
930 param.name 889 param.name
931 for param in called_by_native.params]) 890 for param in called_by_native.params])
932 891
933 def GetForwardDeclaration(self, native): 892 def GetForwardDeclaration(self, native):
934 template = Template(""" 893 template = Template("""
935 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); 894 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
895 __attribute__((alias("${NAME}"), visibility("default"))) ${RETURN}
896 Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS});
936 """) 897 """)
898 java_name = JniParams.RemapClassName(self.fully_qualified_class).replace('_' , '_1').replace('/', '_')
899 if native.java_class_name:
900 java_name += "_00024" + native.java_class_name
901
937 values = {'RETURN': JavaDataTypeToC(native.return_type), 902 values = {'RETURN': JavaDataTypeToC(native.return_type),
938 'NAME': native.name, 903 'NAME': native.name,
904 'JAVA_NAME': java_name,
939 'PARAMS': self.GetParamsInDeclaration(native)} 905 'PARAMS': self.GetParamsInDeclaration(native)}
940 return template.substitute(values) 906 return template.substitute(values)
941 907
942 def GetNativeMethodStubString(self, native): 908 def GetNativeMethodStubString(self, native):
943 """Returns stubs for native methods.""" 909 """Returns stubs for native methods."""
944 template = Template("""\ 910 template = Template("""\
945 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { 911 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {
946 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 912 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
947 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 913 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
948 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 914 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
949 } 915 }
916 __attribute__((alias("${NAME}"), visibility("default")))
917 ${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env,
918 ${PARAMS_IN_DECLARATION});
950 """) 919 """)
951 params = [] 920 params = []
952 if not self.options.pure_native_methods: 921 if not self.options.pure_native_methods:
953 params = ['env', 'jcaller'] 922 params = ['env', 'jcaller']
954 params_in_call = ', '.join(params + [p.name for p in native.params[1:]]) 923 params_in_call = ', '.join(params + [p.name for p in native.params[1:]])
955 924
956 return_type = JavaDataTypeToC(native.return_type) 925 return_type = JavaDataTypeToC(native.return_type)
957 optional_error_return = JavaReturnValueToC(native.return_type) 926 optional_error_return = JavaReturnValueToC(native.return_type)
958 if optional_error_return: 927 if optional_error_return:
959 optional_error_return = ', ' + optional_error_return 928 optional_error_return = ', ' + optional_error_return
960 post_call = '' 929 post_call = ''
961 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 930 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
962 post_call = '.Release()' 931 post_call = '.Release()'
932 java_name = JniParams.RemapClassName(self.fully_qualified_class).replace('_' , '_1').replace('/', '_')
933 if native.java_class_name:
934 java_name += "_00024" + native.java_class_name
963 values = { 935 values = {
964 'RETURN': return_type, 936 'RETURN': return_type,
965 'OPTIONAL_ERROR_RETURN': optional_error_return, 937 'OPTIONAL_ERROR_RETURN': optional_error_return,
938 'JAVA_NAME': java_name,
966 'NAME': native.name, 939 'NAME': native.name,
967 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), 940 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
968 'PARAM0_NAME': native.params[0].name, 941 'PARAM0_NAME': native.params[0].name,
969 'P0_TYPE': native.p0_type, 942 'P0_TYPE': native.p0_type,
970 'PARAMS_IN_CALL': params_in_call, 943 'PARAMS_IN_CALL': params_in_call,
971 'POST_CALL': post_call 944 'POST_CALL': post_call
972 } 945 }
973 return template.substitute(values) 946 return template.substitute(values)
974 947
975 def GetCalledByNativeValues(self, called_by_native): 948 def GetCalledByNativeValues(self, called_by_native):
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 jni_class_path = self.fully_qualified_class 1064 jni_class_path = self.fully_qualified_class
1092 if entry.java_class_name: 1065 if entry.java_class_name:
1093 class_name = entry.java_class_name 1066 class_name = entry.java_class_name
1094 jni_class_path = self.fully_qualified_class + '$' + class_name 1067 jni_class_path = self.fully_qualified_class + '$' + class_name
1095 ret[class_name] = jni_class_path 1068 ret[class_name] = jni_class_path
1096 return ret 1069 return ret
1097 1070
1098 def GetClassPathDefinitions(self): 1071 def GetClassPathDefinitions(self):
1099 """Returns the ClassPath constants.""" 1072 """Returns the ClassPath constants."""
1100 ret = [] 1073 ret = []
1074 if not self.called_by_natives:
1075 return ''
1101 template = Template("""\ 1076 template = Template("""\
1102 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") 1077 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
1103 native_classes = self.GetUniqueClasses(self.natives) 1078 all_classes = self.GetUniqueClasses(self.called_by_natives)
1104 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
1105 all_classes = native_classes
1106 all_classes.update(called_by_native_classes)
1107 for clazz in all_classes: 1079 for clazz in all_classes:
1108 values = { 1080 values = {
1109 'JAVA_CLASS': clazz, 1081 'JAVA_CLASS': clazz,
1110 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), 1082 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]),
1111 } 1083 }
1112 ret += [template.substitute(values)] 1084 ret += [template.substitute(values)]
1113 ret += '' 1085 ret += ''
1114 for clazz in called_by_native_classes: 1086 for clazz in all_classes:
1115 template = Template("""\ 1087 template = Template("""\
1116 // Leaking this jclass as we cannot use LazyInstance from some threads. 1088 // Leaking this jclass as we cannot use LazyInstance from some threads.
1117 jclass g_${JAVA_CLASS}_clazz = NULL;""") 1089 jclass g_${JAVA_CLASS}_clazz = NULL;""")
1118 values = { 1090 values = {
1119 'JAVA_CLASS': clazz, 1091 'JAVA_CLASS': clazz,
1120 } 1092 }
1121 ret += [template.substitute(values)] 1093 ret += [template.substitute(values)]
1122 return '\n'.join(ret) 1094 return '\n'.join(ret)
1123 1095
1124 def GetFindClasses(self): 1096 def GetFindClasses(self):
1097 if not self.called_by_natives:
1098 return ''
1125 """Returns the imlementation of FindClass for all known classes.""" 1099 """Returns the imlementation of FindClass for all known classes."""
1126 if self.init_native: 1100 if self.init_native:
1127 template = Template("""\ 1101 template = Template("""\
1128 g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""") 1102 g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""")
1129 else: 1103 else:
1130 template = Template("""\ 1104 template = Template("""\
1131 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( 1105 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
1132 base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""") 1106 base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""")
1133 ret = [] 1107 ret = []
1134 for clazz in self.GetUniqueClasses(self.called_by_natives): 1108 for clazz in self.GetUniqueClasses(self.called_by_natives):
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 root_name = os.path.splitext(os.path.basename(input_file))[0] 1311 root_name = os.path.splitext(os.path.basename(input_file))[0]
1338 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1312 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1339 if options.jarjar: 1313 if options.jarjar:
1340 with open(options.jarjar) as f: 1314 with open(options.jarjar) as f:
1341 JniParams.SetJarJarMappings(f.read()) 1315 JniParams.SetJarJarMappings(f.read())
1342 GenerateJNIHeader(input_file, output_file, options) 1316 GenerateJNIHeader(input_file, output_file, options)
1343 1317
1344 1318
1345 if __name__ == '__main__': 1319 if __name__ == '__main__':
1346 sys.exit(main(sys.argv)) 1320 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698