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

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

Issue 2501193003: Selectively perform JNI registration in render processes on Android. (Closed)
Patch Set: Add @MainDex where it's missing Created 4 years 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 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698