OLD | NEW |
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 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 kmethods = self.GetKMethodsString(clazz) | 882 kmethods = self.GetKMethodsString(clazz) |
883 if kmethods: | 883 if kmethods: |
884 values = {'JAVA_CLASS': clazz, | 884 values = {'JAVA_CLASS': clazz, |
885 'KMETHODS': kmethods} | 885 'KMETHODS': kmethods} |
886 ret += [template.substitute(values)] | 886 ret += [template.substitute(values)] |
887 if not ret: return '' | 887 if not ret: return '' |
888 return '\n' + '\n'.join(ret) | 888 return '\n' + '\n'.join(ret) |
889 | 889 |
890 def GetJNINativeMethodsString(self): | 890 def GetJNINativeMethodsString(self): |
891 """Returns the implementation of the array of native methods.""" | 891 """Returns the implementation of the array of native methods.""" |
892 if self.options.native_exports: | 892 if self.options.native_exports and not self.options.native_exports_optional: |
893 return '' | 893 return '' |
894 template = Template("""\ | 894 template = Template("""\ |
895 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { | 895 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { |
896 ${KMETHODS} | 896 ${KMETHODS} |
897 }; | 897 }; |
898 """) | 898 """) |
899 return self.SubstituteNativeMethods(template) | 899 return self.SubstituteNativeMethods(template) |
900 | 900 |
901 def GetRegisterCalledByNativesImplString(self): | 901 def GetRegisterCalledByNativesImplString(self): |
902 """Returns the code for registering the called by native methods.""" | 902 """Returns the code for registering the called by native methods.""" |
(...skipping 12 matching lines...) Expand all Loading... |
915 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, | 915 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, |
916 'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native), | 916 'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native), |
917 } | 917 } |
918 ret += [template.substitute(values)] | 918 ret += [template.substitute(values)] |
919 return '\n'.join(ret) | 919 return '\n'.join(ret) |
920 | 920 |
921 def GetRegisterNativesString(self): | 921 def GetRegisterNativesString(self): |
922 """Returns the code for RegisterNatives.""" | 922 """Returns the code for RegisterNatives.""" |
923 template = Template("""\ | 923 template = Template("""\ |
924 ${REGISTER_NATIVES_SIGNATURE} { | 924 ${REGISTER_NATIVES_SIGNATURE} { |
925 ${CLASSES} | 925 ${EARLY_EXIT}${CLASSES} |
926 ${NATIVES} | 926 ${NATIVES} |
927 ${CALLED_BY_NATIVES} | 927 ${CALLED_BY_NATIVES} |
928 return true; | 928 return true; |
929 } | 929 } |
930 """) | 930 """) |
931 signature = 'static bool RegisterNativesImpl(JNIEnv* env' | 931 signature = 'static bool RegisterNativesImpl(JNIEnv* env' |
932 if self.init_native: | 932 if self.init_native: |
933 signature += ', jclass clazz)' | 933 signature += ', jclass clazz)' |
934 else: | 934 else: |
935 signature += ')' | 935 signature += ')' |
936 | 936 |
| 937 early_exit = '' |
| 938 if self.options.native_exports_optional: |
| 939 early_exit = """\ |
| 940 if (base::android::IsManualJniRegistrationDisabled()) return true; |
| 941 """ |
| 942 |
937 natives = self.GetRegisterNativesImplString() | 943 natives = self.GetRegisterNativesImplString() |
938 called_by_natives = self.GetRegisterCalledByNativesImplString() | 944 called_by_natives = self.GetRegisterCalledByNativesImplString() |
939 values = {'REGISTER_NATIVES_SIGNATURE': signature, | 945 values = {'REGISTER_NATIVES_SIGNATURE': signature, |
| 946 'EARLY_EXIT': early_exit, |
940 'CLASSES': self.GetFindClasses(), | 947 'CLASSES': self.GetFindClasses(), |
941 'NATIVES': natives, | 948 'NATIVES': natives, |
942 'CALLED_BY_NATIVES': called_by_natives, | 949 'CALLED_BY_NATIVES': called_by_natives, |
943 } | 950 } |
944 return template.substitute(values) | 951 return template.substitute(values) |
945 | 952 |
946 def GetRegisterNativesImplString(self): | 953 def GetRegisterNativesImplString(self): |
947 """Returns the shared implementation for RegisterNatives.""" | 954 """Returns the shared implementation for RegisterNatives.""" |
948 if self.options.native_exports: | 955 if self.options.native_exports and not self.options.native_exports_optional: |
949 return '' | 956 return '' |
950 | 957 |
951 template = Template("""\ | 958 template = Template("""\ |
952 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); | 959 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); |
953 | 960 |
954 if (env->RegisterNatives(${JAVA_CLASS}_clazz(env), | 961 if (env->RegisterNatives(${JAVA_CLASS}_clazz(env), |
955 kMethods${JAVA_CLASS}, | 962 kMethods${JAVA_CLASS}, |
956 kMethods${JAVA_CLASS}Size) < 0) { | 963 kMethods${JAVA_CLASS}Size) < 0) { |
957 jni_generator::HandleRegistrationError( | 964 jni_generator::HandleRegistrationError( |
958 env, ${JAVA_CLASS}_clazz(env), __FILE__); | 965 env, ${JAVA_CLASS}_clazz(env), __FILE__); |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 action='store_true', dest='eager_called_by_natives', | 1513 action='store_true', dest='eager_called_by_natives', |
1507 help='When true, the called-by-native methods will ' | 1514 help='When true, the called-by-native methods will ' |
1508 'be initialized in a non-atomic way.') | 1515 'be initialized in a non-atomic way.') |
1509 option_parser.add_option('--cpp', default='cpp', | 1516 option_parser.add_option('--cpp', default='cpp', |
1510 help='The path to cpp command.') | 1517 help='The path to cpp command.') |
1511 option_parser.add_option('--javap', default='javap', | 1518 option_parser.add_option('--javap', default='javap', |
1512 help='The path to javap command.') | 1519 help='The path to javap command.') |
1513 option_parser.add_option('--native_exports', action='store_true', | 1520 option_parser.add_option('--native_exports', action='store_true', |
1514 help='Native method registration through .so ' | 1521 help='Native method registration through .so ' |
1515 'exports.') | 1522 'exports.') |
| 1523 option_parser.add_option('--native_exports_optional', action='store_true', |
| 1524 help='Support both explicit and native method' |
| 1525 'registration.') |
1516 options, args = option_parser.parse_args(argv) | 1526 options, args = option_parser.parse_args(argv) |
| 1527 if options.native_exports_optional: |
| 1528 options.native_exports = True |
1517 if options.jar_file: | 1529 if options.jar_file: |
1518 input_file = ExtractJarInputFile(options.jar_file, options.input_file, | 1530 input_file = ExtractJarInputFile(options.jar_file, options.input_file, |
1519 options.output_dir) | 1531 options.output_dir) |
1520 elif options.input_file: | 1532 elif options.input_file: |
1521 input_file = options.input_file | 1533 input_file = options.input_file |
1522 else: | 1534 else: |
1523 option_parser.print_help() | 1535 option_parser.print_help() |
1524 print '\nError: Must specify --jar_file or --input_file.' | 1536 print '\nError: Must specify --jar_file or --input_file.' |
1525 return 1 | 1537 return 1 |
1526 output_file = None | 1538 output_file = None |
1527 if options.output_dir: | 1539 if options.output_dir: |
1528 root_name = os.path.splitext(os.path.basename(input_file))[0] | 1540 root_name = os.path.splitext(os.path.basename(input_file))[0] |
1529 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' | 1541 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' |
1530 if options.jarjar: | 1542 if options.jarjar: |
1531 with open(options.jarjar) as f: | 1543 with open(options.jarjar) as f: |
1532 JniParams.SetJarJarMappings(f.read()) | 1544 JniParams.SetJarJarMappings(f.read()) |
1533 GenerateJNIHeader(input_file, output_file, options) | 1545 GenerateJNIHeader(input_file, output_file, options) |
1534 | 1546 |
1535 if options.depfile: | 1547 if options.depfile: |
1536 build_utils.WriteDepfile( | 1548 build_utils.WriteDepfile( |
1537 options.depfile, | 1549 options.depfile, |
1538 build_utils.GetPythonDependencies()) | 1550 build_utils.GetPythonDependencies()) |
1539 | 1551 |
1540 | 1552 |
1541 if __name__ == '__main__': | 1553 if __name__ == '__main__': |
1542 sys.exit(main(sys.argv)) | 1554 sys.exit(main(sys.argv)) |
OLD | NEW |