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

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

Issue 11339013: Android: passes a list of qualified JNI parameters as a param to the generator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase from new tree Created 8 years, 1 month 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 | Annotate | Revision Log
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 # TODO (qinmin): Need to refactor this file as base should not know about 6 # TODO (qinmin): Need to refactor this file as base should not know about
7 # higher level concepts. Currently this file has knowledge about higher level 7 # higher level concepts. Currently this file has knowledge about higher level
8 # java classes. 8 # java classes.
9 9
10 """Extracts native methods from a Java file and generates the JNI bindings. 10 """Extracts native methods from a Java file and generates the JNI bindings.
11 If you change this, please run and update the tests.""" 11 If you change this, please run and update the tests."""
12 12
13 import collections 13 import collections
14 import optparse 14 import optparse
15 import os 15 import os
16 import re 16 import re
17 import string 17 import string
18 from string import Template 18 from string import Template
19 import subprocess 19 import subprocess
20 import sys 20 import sys
21 import textwrap 21 import textwrap
22 import zipfile 22 import zipfile
23 23
24 UNKNOWN_JAVA_TYPE_PREFIX = 'UNKNOWN_JAVA_TYPE: ' 24 UNKNOWN_JAVA_TYPE_PREFIX = 'UNKNOWN_JAVA_TYPE: '
25 25 EXTERNAL_PARAM_LIST = []
26 26
27 class ParseError(Exception): 27 class ParseError(Exception):
28 """Exception thrown when we can't parse the input file.""" 28 """Exception thrown when we can't parse the input file."""
29 29
30 def __init__(self, description, *context_lines): 30 def __init__(self, description, *context_lines):
31 Exception.__init__(self) 31 Exception.__init__(self)
32 self.description = description 32 self.description = description
33 self.context_lines = context_lines 33 self.context_lines = context_lines
34 34
35 def __str__(self): 35 def __str__(self):
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 'Ljava/util/ArrayList', 133 'Ljava/util/ArrayList',
134 'Ljava/util/HashMap', 134 'Ljava/util/HashMap',
135 'Ljava/util/List', 135 'Ljava/util/List',
136 'Landroid/content/Context', 136 'Landroid/content/Context',
137 'Landroid/graphics/Bitmap', 137 'Landroid/graphics/Bitmap',
138 'Landroid/graphics/Canvas', 138 'Landroid/graphics/Canvas',
139 'Landroid/graphics/Rect', 139 'Landroid/graphics/Rect',
140 'Landroid/graphics/RectF', 140 'Landroid/graphics/RectF',
141 'Landroid/graphics/Matrix', 141 'Landroid/graphics/Matrix',
142 'Landroid/graphics/Point', 142 'Landroid/graphics/Point',
143 'Landroid/graphics/SurfaceTexture',
143 'Landroid/graphics/SurfaceTexture$OnFrameAvailableListener', 144 'Landroid/graphics/SurfaceTexture$OnFrameAvailableListener',
144 'Landroid/media/MediaPlayer', 145 'Landroid/media/MediaPlayer',
145 'Landroid/os/Message', 146 'Landroid/os/Message',
146 'Landroid/view/KeyEvent', 147 'Landroid/view/KeyEvent',
147 'Landroid/view/Surface', 148 'Landroid/view/Surface',
148 'Landroid/view/View', 149 'Landroid/view/View',
149 'Landroid/webkit/ValueCallback', 150 'Landroid/webkit/ValueCallback',
150 'Ljava/io/InputStream', 151 'Ljava/io/InputStream',
151 'Ljava/nio/ByteBuffer', 152 'Ljava/nio/ByteBuffer',
152 'Ljava/util/Vector', 153 'Ljava/util/Vector',
153 ] 154 ]
154 app_param_list = [
155 'Landroid/graphics/SurfaceTexture',
156 'Lcom/google/android/apps/chrome/ChromeContextMenuInfo',
157 'Lcom/google/android/apps/chrome/ChromeWindow',
158 'Lcom/google/android/apps/chrome/GoogleLocationSettingsHelperImpl',
159 'Lcom/google/android/apps/chrome/OmniboxSuggestion',
160 'Lcom/google/android/apps/chrome/PageInfoViewer',
161 'Lcom/google/android/apps/chrome/Tab',
162 'Lcom/google/android/apps/chrome/infobar/AutoLogin',
163 'Lcom/google/android/apps/chrome/infobar/InfoBarContainer',
164 'Lcom/google/android/apps/chrome/infobar/InfoBarContainer$NativeInfoBar',
165 ('Lcom/google/android/apps/chrome/preferences/ChromeNativePreferences$'
166 'PasswordListObserver'),
167 'Lorg/chromium/android_webview/AwContents',
168 'Lorg/chromium/android_webview/AwContentsClient',
169 'Lorg/chromium/android_webview/AwHttpAuthHandler',
170 'Lorg/chromium/android_webview/AwContentsIoThreadClient',
171 'Lorg/chromium/android_webview/AwWebContentsDelegate',
172 'Lorg/chromium/android_webview/InterceptedRequestData',
173 'Lorg/chromium/android_webview/JsPromptResultReceiver',
174 'Lorg/chromium/android_webview/JsResultHandler',
175 'Lorg/chromium/android_webview/JsResultReceiver',
176 'Lorg/chromium/base/SystemMessageHandler',
177 'Lorg/chromium/chrome/browser/autofill/AutofillExternalDelegate',
178 'Lorg/chromium/chrome/browser/autofill/AutofillSuggestion',
179 'Lorg/chromium/chrome/browser/ChromeBrowserProvider$BookmarkNode',
180 'Lorg/chromium/chrome/browser/ChromeHttpAuthHandler',
181 'Lorg/chromium/chrome/browser/ChromeWebContentsDelegateAndroid',
182 'Lorg/chromium/chrome/browser/FindMatchRectsDetails',
183 'Lorg/chromium/chrome/browser/FindNotificationDetails',
184 'Lorg/chromium/chrome/browser/GoogleLocationSettingsHelper',
185 'Lorg/chromium/chrome/browser/GoogleLocationSettingsHelperStub',
186 'Lorg/chromium/chrome/browser/JavascriptAppModalDialog',
187 'Lorg/chromium/chrome/browser/ProcessUtils',
188 ('Lorg/chromium/chrome/browser/component/navigation_interception/'
189 'InterceptNavigationDelegate'),
190 ('Lorg/chromium/chrome/browser/component/web_contents_delegate_android/'
191 'WebContentsDelegateAndroid'),
192 'Lorg/chromium/chrome/browser/database/SQLiteCursor',
193 'Lorg/chromium/content/app/SandboxedProcessService',
194 'Lorg/chromium/content/browser/ContainerViewDelegate',
195 'Lorg/chromium/content/browser/ContentVideoView',
196 'Lorg/chromium/content/browser/ContentViewCore',
197 'Lorg/chromium/content/browser/DeviceOrientation',
198 'Lorg/chromium/content/browser/JavaInputStream',
199 'Lorg/chromium/content/browser/LocationProvider',
200 'Lorg/chromium/content/browser/SandboxedProcessArgs',
201 'Lorg/chromium/content/browser/SandboxedProcessConnection',
202 'Lorg/chromium/content/browser/TouchPoint',
203 'Lorg/chromium/content/browser/WaitableNativeEvent',
204 'Lorg/chromium/content/browser/WebContentsObserverAndroid',
205 'Lorg/chromium/content/common/DeviceInfo',
206 'Lorg/chromium/content/common/SurfaceTextureListener',
207 'Lorg/chromium/media/MediaPlayerListener',
208 'Lorg/chromium/net/NetworkChangeNotifier',
209 'Lorg/chromium/net/ProxyChangeListener',
210 'Lorg/chromium/ui/gfx/NativeWindow',
211 'Lorg/chromium/ui/SelectFileDialog',
212 ]
213 if param == 'byte[][]': 155 if param == 'byte[][]':
214 return '[[B' 156 return '[[B'
215 prefix = '' 157 prefix = ''
216 # Array? 158 # Array?
217 if param[-2:] == '[]': 159 if param[-2:] == '[]':
218 prefix = '[' 160 prefix = '['
219 param = param[:-2] 161 param = param[:-2]
220 # Generic? 162 # Generic?
221 if '<' in param: 163 if '<' in param:
222 param = param[:param.index('<')] 164 param = param[:param.index('<')]
223 if param in pod_param_map: 165 if param in pod_param_map:
224 return prefix + pod_param_map[param] 166 return prefix + pod_param_map[param]
225 if '/' in param: 167 if '/' in param:
226 # Coming from javap, use the fully qualified param directly. 168 # Coming from javap, use the fully qualified param directly.
227 return 'L' + param + ';' 169 return 'L' + param + ';'
228 for qualified_name in object_param_list + app_param_list: 170 for qualified_name in object_param_list + EXTERNAL_PARAM_LIST:
Nico 2012/10/30 19:47:36 CAPS_NAMES are usually constants, which this isn't
bulach 2012/10/31 10:17:02 good points, thanks nico! I refactored this a bit
229 if (qualified_name.endswith('/' + param) or 171 if (qualified_name.endswith('/' + param) or
230 qualified_name.endswith('$' + param.replace('.', '$')) or 172 qualified_name.endswith('$' + param.replace('.', '$')) or
231 qualified_name == 'L' + param): 173 qualified_name == 'L' + param):
232 return prefix + qualified_name + ';' 174 return prefix + qualified_name + ';'
233 else: 175 else:
234 return UNKNOWN_JAVA_TYPE_PREFIX + prefix + param + ';' 176 return UNKNOWN_JAVA_TYPE_PREFIX + prefix + param + ';'
235 177
236 178
237 def JniSignature(params, returns, wrap): 179 def JniSignature(params, returns, wrap):
238 """Returns the JNI signature for the given datatypes.""" 180 """Returns the JNI signature for the given datatypes."""
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 self.fully_qualified_class = fully_qualified_class 501 self.fully_qualified_class = fully_qualified_class
560 self.class_name = self.fully_qualified_class.split('/')[-1] 502 self.class_name = self.fully_qualified_class.split('/')[-1]
561 self.natives = natives 503 self.natives = natives
562 self.called_by_natives = called_by_natives 504 self.called_by_natives = called_by_natives
563 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' 505 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI'
564 unknown_datatypes = GetUnknownDatatypes(self.natives + 506 unknown_datatypes = GetUnknownDatatypes(self.natives +
565 self.called_by_natives) 507 self.called_by_natives)
566 if unknown_datatypes: 508 if unknown_datatypes:
567 msg = ('There are a few unknown datatypes in %s' % 509 msg = ('There are a few unknown datatypes in %s' %
568 self.fully_qualified_class) 510 self.fully_qualified_class)
569 msg += '\nPlease, edit %s' % sys.argv[0] 511 msg += '\nPlease, edit %s' % sys.argv[0]
Yaron 2012/10/30 19:42:36 Actually, with this change, this will no longer be
bulach 2012/10/31 10:17:02 Done.
570 msg += '\nand add the java type to JavaParamToJni()\n' 512 msg += '\nand add the java type to JavaParamToJni()\n'
571 for unknown_datatype in unknown_datatypes: 513 for unknown_datatype in unknown_datatypes:
572 msg += '\n%s in methods:\n' % unknown_datatype 514 msg += '\n%s in methods:\n' % unknown_datatype
573 msg += '\n '.join(unknown_datatypes[unknown_datatype]) 515 msg += '\n '.join(unknown_datatypes[unknown_datatype])
574 raise SyntaxError(msg) 516 raise SyntaxError(msg)
575 517
576 def GetContent(self): 518 def GetContent(self):
577 """Returns the content of the JNI binding file.""" 519 """Returns the content of the JNI binding file."""
578 template = Template("""\ 520 template = Template("""\
579 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 521 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 sys.exit(1) 946 sys.exit(1)
1005 if output_file: 947 if output_file:
1006 if not os.path.exists(os.path.dirname(os.path.abspath(output_file))): 948 if not os.path.exists(os.path.dirname(os.path.abspath(output_file))):
1007 os.makedirs(os.path.dirname(os.path.abspath(output_file))) 949 os.makedirs(os.path.dirname(os.path.abspath(output_file)))
1008 with file(output_file, 'w') as f: 950 with file(output_file, 'w') as f:
1009 f.write(content) 951 f.write(content)
1010 else: 952 else:
1011 print output 953 print output
1012 954
1013 955
956 def ReadExtraAppParamList(external_param_files):
957 if not external_param_files:
958 return
959 for external_param_file in set(external_param_files):
960 with file(external_param_file, 'r') as f:
961 contents = f.read()
962 global EXTERNAL_PARAM_LIST
963 EXTERNAL_PARAM_LIST += [x.strip() for x in contents.splitlines()
964 if x and not x.startswith('#')]
965
966
1014 def main(argv): 967 def main(argv):
1015 usage = """usage: %prog [OPTIONS] 968 usage = """usage: %prog [OPTIONS]
1016 This script will parse the given java source code extracting the native 969 This script will parse the given java source code extracting the native
1017 declarations and print the header file to stdout (or a file). 970 declarations and print the header file to stdout (or a file).
1018 See SampleForTests.java for more details. 971 See SampleForTests.java for more details.
1019 """ 972 """
1020 option_parser = optparse.OptionParser(usage=usage) 973 option_parser = optparse.OptionParser(usage=usage)
1021 option_parser.add_option('-j', dest='jar_file', 974 option_parser.add_option('-j', dest='jar_file',
1022 help='Extract the list of input files from' 975 help='Extract the list of input files from'
1023 ' a specified jar file.' 976 ' a specified jar file.'
1024 ' Uses javap to extract the methods from a' 977 ' Uses javap to extract the methods from a'
1025 ' pre-compiled class. --input should point' 978 ' pre-compiled class. --input should point'
1026 ' to pre-compiled Java .class files.') 979 ' to pre-compiled Java .class files.')
1027 option_parser.add_option('-n', dest='namespace', 980 option_parser.add_option('-n', dest='namespace',
1028 help='Uses as a namespace in the generated header,' 981 help='Uses as a namespace in the generated header,'
1029 ' instead of the javap class name.') 982 ' instead of the javap class name.')
1030 option_parser.add_option('--input_file', 983 option_parser.add_option('--input_file',
1031 help='Single input file name. The output file name ' 984 help='Single input file name. The output file name '
1032 'will be derived from it. Must be used with ' 985 'will be derived from it. Must be used with '
1033 '--output_dir.') 986 '--output_dir.')
1034 option_parser.add_option('--output_dir', 987 option_parser.add_option('--output_dir',
1035 help='The output directory. Must be used with ' 988 help='The output directory. Must be used with '
1036 '--input') 989 '--input')
990 option_parser.add_option('--external_param_list',
991 help='A file name containing a list with extra '
992 'fully-qualified param names. Can be used multiple '
993 'times.',
994 action='append')
1037 options, args = option_parser.parse_args(argv) 995 options, args = option_parser.parse_args(argv)
996 ReadExtraAppParamList(options.external_param_list)
1038 if options.jar_file: 997 if options.jar_file:
1039 input_file = ExtractJarInputFile(options.jar_file, options.input_file, 998 input_file = ExtractJarInputFile(options.jar_file, options.input_file,
1040 options.output_dir) 999 options.output_dir)
1041 else: 1000 else:
1042 input_file = options.input_file 1001 input_file = options.input_file
1043 output_file = None 1002 output_file = None
1044 if options.output_dir: 1003 if options.output_dir:
1045 root_name = os.path.splitext(os.path.basename(input_file))[0] 1004 root_name = os.path.splitext(os.path.basename(input_file))[0]
1046 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1005 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1047 GenerateJNIHeader(input_file, output_file, options.namespace) 1006 GenerateJNIHeader(input_file, output_file, options.namespace)
1048 1007
1049 1008
1050 if __name__ == '__main__': 1009 if __name__ == '__main__':
1051 sys.exit(main(sys.argv)) 1010 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698