Chromium Code Reviews| 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 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 match = re.match(re_constant_field, content) | 625 match = re.match(re_constant_field, content) | 
| 626 if not match: | 626 if not match: | 
| 627 continue | 627 continue | 
| 628 value = re.match(re_constant_field_value, contents[lineno + 2]) | 628 value = re.match(re_constant_field_value, contents[lineno + 2]) | 
| 629 if not value: | 629 if not value: | 
| 630 value = re.match(re_constant_field_value, contents[lineno + 3]) | 630 value = re.match(re_constant_field_value, contents[lineno + 3]) | 
| 631 if value: | 631 if value: | 
| 632 self.constant_fields.append( | 632 self.constant_fields.append( | 
| 633 ConstantField(name=match.group('name'), | 633 ConstantField(name=match.group('name'), | 
| 634 value=value.group('value'))) | 634 value=value.group('value'))) | 
| 635 | |
| 636 self.inl_header_file_generator = InlHeaderFileGenerator( | 635 self.inl_header_file_generator = InlHeaderFileGenerator( | 
| 637 self.namespace, self.fully_qualified_class, [], | 636 self.namespace, self.fully_qualified_class, [], self.called_by_natives, | 
| 638 self.called_by_natives, self.constant_fields, options) | 637 self.constant_fields, options) | 
| 639 | 638 | 
| 640 def GetContent(self): | 639 def GetContent(self): | 
| 641 return self.inl_header_file_generator.GetContent() | 640 return self.inl_header_file_generator.GetContent() | 
| 642 | 641 | 
| 643 @staticmethod | 642 @staticmethod | 
| 644 def CreateFromClass(class_file, options): | 643 def CreateFromClass(class_file, options): | 
| 645 class_name = os.path.splitext(os.path.basename(class_file))[0] | 644 class_name = os.path.splitext(os.path.basename(class_file))[0] | 
| 646 p = subprocess.Popen(args=[options.javap, '-c', '-verbose', | 645 p = subprocess.Popen(args=[options.javap, '-c', '-verbose', | 
| 647 '-s', class_name], | 646 '-s', class_name], | 
| 648 cwd=os.path.dirname(class_file), | 647 cwd=os.path.dirname(class_file), | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 662 r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', | 661 r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', | 
| 663 re.DOTALL | re.MULTILINE) | 662 re.DOTALL | re.MULTILINE) | 
| 664 | 663 | 
| 665 def __init__(self, contents, fully_qualified_class, options): | 664 def __init__(self, contents, fully_qualified_class, options): | 
| 666 contents = self._RemoveComments(contents) | 665 contents = self._RemoveComments(contents) | 
| 667 JniParams.SetFullyQualifiedClass(fully_qualified_class) | 666 JniParams.SetFullyQualifiedClass(fully_qualified_class) | 
| 668 JniParams.ExtractImportsAndInnerClasses(contents) | 667 JniParams.ExtractImportsAndInnerClasses(contents) | 
| 669 jni_namespace = ExtractJNINamespace(contents) or options.namespace | 668 jni_namespace = ExtractJNINamespace(contents) or options.namespace | 
| 670 natives = ExtractNatives(contents, options.ptr_type) | 669 natives = ExtractNatives(contents, options.ptr_type) | 
| 671 called_by_natives = ExtractCalledByNatives(contents) | 670 called_by_natives = ExtractCalledByNatives(contents) | 
| 671 maindex = '@MainDex' in contents | |
| 
 
Torne
2016/12/14 11:40:24
The other Extract* functions are doing more than j
 
 | |
| 672 if len(natives) == 0 and len(called_by_natives) == 0: | 672 if len(natives) == 0 and len(called_by_natives) == 0: | 
| 673 raise SyntaxError('Unable to find any JNI methods for %s.' % | 673 raise SyntaxError('Unable to find any JNI methods for %s.' % | 
| 674 fully_qualified_class) | 674 fully_qualified_class) | 
| 675 inl_header_file_generator = InlHeaderFileGenerator( | 675 inl_header_file_generator = InlHeaderFileGenerator( | 
| 676 jni_namespace, fully_qualified_class, natives, called_by_natives, | 676 jni_namespace, fully_qualified_class, natives, called_by_natives, [], | 
| 677 [], options) | 677 options, maindex) | 
| 678 self.content = inl_header_file_generator.GetContent() | 678 self.content = inl_header_file_generator.GetContent() | 
| 679 | 679 | 
| 680 @classmethod | 680 @classmethod | 
| 681 def _RemoveComments(cls, contents): | 681 def _RemoveComments(cls, contents): | 
| 682 # We need to support both inline and block comments, and we need to handle | 682 # We need to support both inline and block comments, and we need to handle | 
| 683 # strings that contain '//' or '/*'. | 683 # strings that contain '//' or '/*'. | 
| 684 # TODO(bulach): This is a bit hacky. It would be cleaner to use a real Java | 684 # TODO(bulach): This is a bit hacky. It would be cleaner to use a real Java | 
| 685 # parser. Maybe we could ditch JNIFromJavaSource and just always use | 685 # parser. Maybe we could ditch JNIFromJavaSource and just always use | 
| 686 # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT. | 686 # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT. | 
| 687 # http://code.google.com/p/chromium/issues/detail?id=138941 | 687 # http://code.google.com/p/chromium/issues/detail?id=138941 | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 703 contents = file(java_file_name).read() | 703 contents = file(java_file_name).read() | 
| 704 fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name, | 704 fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name, | 
| 705 contents) | 705 contents) | 
| 706 return JNIFromJavaSource(contents, fully_qualified_class, options) | 706 return JNIFromJavaSource(contents, fully_qualified_class, options) | 
| 707 | 707 | 
| 708 | 708 | 
| 709 class InlHeaderFileGenerator(object): | 709 class InlHeaderFileGenerator(object): | 
| 710 """Generates an inline header file for JNI integration.""" | 710 """Generates an inline header file for JNI integration.""" | 
| 711 | 711 | 
| 712 def __init__(self, namespace, fully_qualified_class, natives, | 712 def __init__(self, namespace, fully_qualified_class, natives, | 
| 713 called_by_natives, constant_fields, options): | 713 called_by_natives, constant_fields, options, maindex=False): | 
| 714 self.namespace = namespace | 714 self.namespace = namespace | 
| 715 self.fully_qualified_class = fully_qualified_class | 715 self.fully_qualified_class = fully_qualified_class | 
| 716 self.class_name = self.fully_qualified_class.split('/')[-1] | 716 self.class_name = self.fully_qualified_class.split('/')[-1] | 
| 717 self.natives = natives | 717 self.natives = natives | 
| 718 self.called_by_natives = called_by_natives | 718 self.called_by_natives = called_by_natives | 
| 719 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' | 719 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' | 
| 720 self.constant_fields = constant_fields | 720 self.constant_fields = constant_fields | 
| 721 self.maindex = maindex | |
| 721 self.options = options | 722 self.options = options | 
| 722 | 723 | 
| 723 | 724 | 
| 724 def GetContent(self): | 725 def GetContent(self): | 
| 725 """Returns the content of the JNI binding file.""" | 726 """Returns the content of the JNI binding file.""" | 
| 726 template = Template("""\ | 727 template = Template("""\ | 
| 727 // Copyright 2014 The Chromium Authors. All rights reserved. | 728 // Copyright 2014 The Chromium Authors. All rights reserved. | 
| 728 // Use of this source code is governed by a BSD-style license that can be | 729 // Use of this source code is governed by a BSD-style license that can be | 
| 729 // found in the LICENSE file. | 730 // found in the LICENSE file. | 
| 730 | 731 | 
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 ${NATIVES} | 858 ${NATIVES} | 
| 858 return true; | 859 return true; | 
| 859 } | 860 } | 
| 860 """) | 861 """) | 
| 861 signature = 'static bool RegisterNativesImpl(JNIEnv* env)' | 862 signature = 'static bool RegisterNativesImpl(JNIEnv* env)' | 
| 862 early_exit = '' | 863 early_exit = '' | 
| 863 if self.options.native_exports_optional: | 864 if self.options.native_exports_optional: | 
| 864 early_exit = """\ | 865 early_exit = """\ | 
| 865 if (base::android::IsManualJniRegistrationDisabled()) return true; | 866 if (base::android::IsManualJniRegistrationDisabled()) return true; | 
| 866 """ | 867 """ | 
| 868 if not self.maindex: | |
| 869 early_exit += """\ | |
| 870 base::android::LibraryProcessType proc_type = | |
| 
 
Torne
2016/12/14 11:40:24
Can you put this in jni_generator_helper.h as an i
 
 | |
| 871 base::android::GetLibraryProcessType(env); | |
| 
 
Torne
2016/12/14 11:40:24
GetLibraryProcessType is a JNI call; if we're goin
 
 | |
| 872 if (proc_type != base::android::PROCESS_BROWSER && | |
| 873 proc_type != base::android::PROCESS_UNINITIALIZED) { | |
| 
 
Torne
2016/12/14 11:40:25
Is there really a case where the process type is u
 
 | |
| 874 return true; | |
| 875 } | |
| 876 """ | |
| 867 | 877 | 
| 868 values = {'REGISTER_NATIVES_SIGNATURE': signature, | 878 values = {'REGISTER_NATIVES_SIGNATURE': signature, | 
| 869 'EARLY_EXIT': early_exit, | 879 'EARLY_EXIT': early_exit, | 
| 870 'NATIVES': natives, | 880 'NATIVES': natives, | 
| 871 } | 881 } | 
| 872 | 882 | 
| 873 return template.substitute(values) | 883 return template.substitute(values) | 
| 874 | 884 | 
| 875 def GetRegisterNativesImplString(self): | 885 def GetRegisterNativesImplString(self): | 
| 876 """Returns the shared implementation for RegisterNatives.""" | 886 """Returns the shared implementation for RegisterNatives.""" | 
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1393 root_name = os.path.splitext(os.path.basename(input_file))[0] | 1403 root_name = os.path.splitext(os.path.basename(input_file))[0] | 
| 1394 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' | 1404 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' | 
| 1395 GenerateJNIHeader(input_file, output_file, options) | 1405 GenerateJNIHeader(input_file, output_file, options) | 
| 1396 | 1406 | 
| 1397 if options.depfile: | 1407 if options.depfile: | 
| 1398 build_utils.WriteDepfile(options.depfile, output_file) | 1408 build_utils.WriteDepfile(options.depfile, output_file) | 
| 1399 | 1409 | 
| 1400 | 1410 | 
| 1401 if __name__ == '__main__': | 1411 if __name__ == '__main__': | 
| 1402 sys.exit(main(sys.argv)) | 1412 sys.exit(main(sys.argv)) | 
| OLD | NEW |