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 = JNIFromJavaSource.InMainDex(contents) | |
| 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 10 matching lines...) Expand all Loading... | |
| 698 def GetContent(self): | 698 def GetContent(self): |
| 699 return self.content | 699 return self.content |
| 700 | 700 |
| 701 @staticmethod | 701 @staticmethod |
| 702 def CreateFromFile(java_file_name, options): | 702 def CreateFromFile(java_file_name, options): |
| 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 @staticmethod | |
| 709 def InMainDex(contents): | |
|
agrieve
2016/12/07 20:46:19
nit: odd name. I'd probably just inline the functi
estevenson
2016/12/07 23:00:04
Done.
| |
| 710 return '@MainDex' in contents | |
| 711 | |
| 708 | 712 |
| 709 class InlHeaderFileGenerator(object): | 713 class InlHeaderFileGenerator(object): |
| 710 """Generates an inline header file for JNI integration.""" | 714 """Generates an inline header file for JNI integration.""" |
| 711 | 715 |
| 712 def __init__(self, namespace, fully_qualified_class, natives, | 716 def __init__(self, namespace, fully_qualified_class, natives, |
| 713 called_by_natives, constant_fields, options): | 717 called_by_natives, constant_fields, options, maindex=False): |
| 714 self.namespace = namespace | 718 self.namespace = namespace |
| 715 self.fully_qualified_class = fully_qualified_class | 719 self.fully_qualified_class = fully_qualified_class |
| 716 self.class_name = self.fully_qualified_class.split('/')[-1] | 720 self.class_name = self.fully_qualified_class.split('/')[-1] |
| 717 self.natives = natives | 721 self.natives = natives |
| 718 self.called_by_natives = called_by_natives | 722 self.called_by_natives = called_by_natives |
| 719 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' | 723 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' |
| 720 self.constant_fields = constant_fields | 724 self.constant_fields = constant_fields |
| 725 self.maindex = maindex | |
| 721 self.options = options | 726 self.options = options |
| 722 | 727 |
| 723 | 728 |
| 724 def GetContent(self): | 729 def GetContent(self): |
| 725 """Returns the content of the JNI binding file.""" | 730 """Returns the content of the JNI binding file.""" |
| 726 template = Template("""\ | 731 template = Template("""\ |
| 727 // Copyright 2014 The Chromium Authors. All rights reserved. | 732 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 728 // Use of this source code is governed by a BSD-style license that can be | 733 // Use of this source code is governed by a BSD-style license that can be |
| 729 // found in the LICENSE file. | 734 // found in the LICENSE file. |
| 730 | 735 |
| 731 | 736 |
| 732 // This file is autogenerated by | 737 // This file is autogenerated by |
| 733 // ${SCRIPT_NAME} | 738 // ${SCRIPT_NAME} |
| 734 // For | 739 // For |
| 735 // ${FULLY_QUALIFIED_CLASS} | 740 // ${FULLY_QUALIFIED_CLASS} |
| 736 | 741 |
| 737 #ifndef ${HEADER_GUARD} | 742 #ifndef ${HEADER_GUARD} |
| 738 #define ${HEADER_GUARD} | 743 #define ${HEADER_GUARD} |
| 739 | 744 |
| 740 #include <jni.h> | 745 #include <jni.h> |
| 741 | 746 |
| 742 ${INCLUDES} | 747 ${INCLUDES} |
| 743 | 748 |
| 744 #include "base/android/jni_int_wrapper.h" | 749 #include "base/android/jni_int_wrapper.h" |
| 750 #include "base/android/jni_utils.h" | |
| 745 | 751 |
| 746 // Step 1: forward declarations. | 752 // Step 1: forward declarations. |
| 747 namespace { | 753 namespace { |
| 748 $CLASS_PATH_DEFINITIONS | 754 $CLASS_PATH_DEFINITIONS |
| 749 | 755 |
| 750 } // namespace | 756 } // namespace |
| 751 | 757 |
| 752 $OPEN_NAMESPACE | 758 $OPEN_NAMESPACE |
| 753 | 759 |
| 754 $CONSTANT_FIELDS | 760 $CONSTANT_FIELDS |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 ${NATIVES} | 863 ${NATIVES} |
| 858 return true; | 864 return true; |
| 859 } | 865 } |
| 860 """) | 866 """) |
| 861 signature = 'static bool RegisterNativesImpl(JNIEnv* env)' | 867 signature = 'static bool RegisterNativesImpl(JNIEnv* env)' |
| 862 early_exit = '' | 868 early_exit = '' |
| 863 if self.options.native_exports_optional: | 869 if self.options.native_exports_optional: |
| 864 early_exit = """\ | 870 early_exit = """\ |
| 865 if (base::android::IsManualJniRegistrationDisabled()) return true; | 871 if (base::android::IsManualJniRegistrationDisabled()) return true; |
| 866 """ | 872 """ |
| 873 if not self.maindex: | |
| 874 early_exit += """\ | |
| 875 if (base::android::IsMultidexEnabled(env) && | |
| 876 base::android::GetLibraryProcessType(env) != | |
| 877 base::android::PROCESS_BROWSER) { | |
| 878 return true; | |
| 879 } | |
| 880 """ | |
| 867 | 881 |
| 868 values = {'REGISTER_NATIVES_SIGNATURE': signature, | 882 values = {'REGISTER_NATIVES_SIGNATURE': signature, |
| 869 'EARLY_EXIT': early_exit, | 883 'EARLY_EXIT': early_exit, |
| 870 'NATIVES': natives, | 884 'NATIVES': natives, |
| 871 } | 885 } |
| 872 | 886 |
| 873 return template.substitute(values) | 887 return template.substitute(values) |
| 874 | 888 |
| 875 def GetRegisterNativesImplString(self): | 889 def GetRegisterNativesImplString(self): |
| 876 """Returns the shared implementation for RegisterNatives.""" | 890 """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] | 1407 root_name = os.path.splitext(os.path.basename(input_file))[0] |
| 1394 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' | 1408 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' |
| 1395 GenerateJNIHeader(input_file, output_file, options) | 1409 GenerateJNIHeader(input_file, output_file, options) |
| 1396 | 1410 |
| 1397 if options.depfile: | 1411 if options.depfile: |
| 1398 build_utils.WriteDepfile(options.depfile, output_file) | 1412 build_utils.WriteDepfile(options.depfile, output_file) |
| 1399 | 1413 |
| 1400 | 1414 |
| 1401 if __name__ == '__main__': | 1415 if __name__ == '__main__': |
| 1402 sys.exit(main(sys.argv)) | 1416 sys.exit(main(sys.argv)) |
| OLD | NEW |