3 # Copyright (c) 2013 Intel Corporation. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6 # pylint: disable=F0401
8 import distutils.dir_util
13 from common_function import RemoveUnusedFilesInReleaseMode
14 from xml.dom.minidom import Document
16 LIBRARY_PROJECT_NAME = 'xwalk_core_library'
17 XWALK_CORE_SHELL_APK = 'xwalk_core_shell_apk'
19 def AddGeneratorOptions(option_parser):
20 option_parser.add_option('-s', dest='source',
21 help='Source directory of project root.',
23 option_parser.add_option('-t', dest='target',
24 help='Product out target directory.',
28 def CleanLibraryProject(out_dir):
29 out_project_path = os.path.join(out_dir, LIBRARY_PROJECT_NAME)
30 if os.path.exists(out_project_path):
31 for item in os.listdir(out_project_path):
32 sub_path = os.path.join(out_project_path, item)
33 if os.path.isdir(sub_path):
34 shutil.rmtree(sub_path)
35 elif os.path.isfile(sub_path):
39 def CopyProjectFiles(project_source, out_dir):
40 """cp xwalk/build/android/xwalkcore_library_template/<file>
41 out/Release/xwalk_core_library/<file>
44 print 'Copying library project files...'
45 template_dir = os.path.join(project_source, 'xwalk', 'build', 'android',
46 'xwalkcore_library_template')
48 # AndroidManifest.xml from template.
49 'AndroidManifest.xml',
50 # Eclipse project properties from template.
54 # Ant properties file.
57 for f in files_to_copy:
58 source_file = os.path.join(template_dir, f)
59 target_file = os.path.join(out_dir, LIBRARY_PROJECT_NAME, f)
61 shutil.copy2(source_file, target_file)
64 def CopyJavaSources(project_source, out_dir):
65 """cp <path>/java/src/<package>
66 out/Release/xwalk_core_library/src/<package>
69 print 'Copying Java sources...'
70 target_source_dir = os.path.join(
71 out_dir, LIBRARY_PROJECT_NAME, 'src')
72 if not os.path.exists(target_source_dir):
73 os.makedirs(target_source_dir)
75 # FIXME(wang16): There is an assumption here the package names listed
76 # here are all beginned with "org". If the assumption is broken in
77 # future, the logic needs to be adjusted accordingly.
79 # Chromium java sources.
80 'base/android/java/src/org/chromium/base',
81 'content/public/android/java/src/org/chromium/content',
82 'content/public/android/java/src/org/chromium/content_public',
83 'media/base/android/java/src/org/chromium/media',
84 'net/android/java/src/org/chromium/net',
85 'ui/android/java/src/org/chromium/ui',
86 'components/navigation_interception/android/java/'
87 'src/org/chromium/components/navigation_interception',
88 'components/web_contents_delegate_android/android/java/'
89 'src/org/chromium/components/web_contents_delegate_android',
92 'content/public/android/java/resource_map/org/chromium/content/R.java',
93 'ui/android/java/resource_map/org/chromium/ui/R.java',
96 'xwalk/runtime/android/core/src/org/xwalk/core',
97 'xwalk/extensions/android/java/src/org/xwalk/core/extensions',
100 for source in java_srcs_to_copy:
101 # find the src/org in the path
102 slash_org_pos = source.find(r'/org/')
103 if slash_org_pos < 0:
104 raise Exception('Invalid java source path: %s' % source)
105 source_path = os.path.join(project_source, source)
106 package_path = source[slash_org_pos+1:]
107 target_path = os.path.join(target_source_dir, package_path)
108 if os.path.isfile(source_path):
109 if not os.path.isdir(os.path.dirname(target_path)):
110 os.makedirs(os.path.dirname(target_path))
111 shutil.copyfile(source_path, target_path)
113 shutil.copytree(source_path, target_path)
116 def CopyGeneratedSources(out_dir):
117 """cp out/Release/gen/templates/<path>
118 out/Release/xwalk_core_library/src/<path>
119 cp out/Release/xwalk_core_shell_apk/
120 native_libraries_java/NativeLibraries.java
121 out/Release/xwalk_core_library/src/org/
122 chromium/base/library_loader/NativeLibraries.java
125 print 'Copying generated source files...'
126 generated_srcs_to_copy = [
127 'org/chromium/base/ApplicationState.java',
128 'org/chromium/base/MemoryPressureLevelList.java',
129 'org/chromium/base/library_loader/NativeLibraries.java',
130 'org/chromium/content/browser/GestureEventType.java',
131 'org/chromium/content/browser/input/PopupItemType.java',
132 'org/chromium/content/browser/PageTransitionTypes.java',
133 'org/chromium/content/browser/SpeechRecognitionError.java',
134 'org/chromium/content/common/ResultCodes.java',
135 'org/chromium/content/common/ScreenOrientationValues.java',
136 'org/chromium/content/common/TopControlsState.java',
137 'org/chromium/media/ImageFormat.java',
138 'org/chromium/net/CertificateMimeType.java',
139 'org/chromium/net/CertVerifyStatusAndroid.java',
140 'org/chromium/net/NetError.java',
141 'org/chromium/net/PrivateKeyType.java',
142 'org/chromium/ui/gfx/BitmapFormat.java',
143 'org/chromium/ui/WindowOpenDisposition.java'
146 for source in generated_srcs_to_copy:
147 source_file = os.path.join(out_dir, 'gen', 'templates', source)
148 target_file = os.path.join(
149 out_dir, LIBRARY_PROJECT_NAME, 'src', source)
150 shutil.copyfile(source_file, target_file)
152 source_file = os.path.join(out_dir, XWALK_CORE_SHELL_APK,
153 'native_libraries_java',
154 'NativeLibraries.java')
155 target_file = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'src', 'org',
156 'chromium', 'base', 'library_loader',
157 'NativeLibraries.java')
158 shutil.copyfile(source_file, target_file)
160 def CopyJSBindingFiles(project_source, out_dir):
161 print 'Copying js binding files...'
162 jsapi_dir = os.path.join(out_dir,
163 LIBRARY_PROJECT_NAME,
166 if not os.path.exists(jsapi_dir):
167 os.makedirs(jsapi_dir)
170 'xwalk/experimental/launch_screen/launch_screen_api.js',
171 'xwalk/experimental/presentation/presentation_api.js',
172 'xwalk/runtime/extension/screen_orientation_api.js',
173 'xwalk/sysapps/device_capabilities/device_capabilities_api.js'
176 # Copy JS binding file to assets/jsapi folder.
177 for jsfile in jsfiles_to_copy:
178 source_file = os.path.join(project_source, jsfile)
179 target_file = os.path.join(jsapi_dir, os.path.basename(source_file))
180 shutil.copyfile(source_file, target_file)
183 def CopyBinaries(out_dir):
184 """cp out/Release/<pak> out/Release/xwalk_core_library/res/raw/<pak>
185 cp out/Release/lib.java/<lib> out/Release/xwalk_core_library/libs/<lib>
186 cp out/Release/xwalk_core_shell_apk/libs/*
187 out/Release/xwalk_core_library/libs
190 print 'Copying binaries...'
192 res_raw_dir = os.path.join(
193 out_dir, LIBRARY_PROJECT_NAME, 'res', 'raw')
194 res_value_dir = os.path.join(
195 out_dir, LIBRARY_PROJECT_NAME, 'res', 'values')
196 if not os.path.exists(res_raw_dir):
197 os.mkdir(res_raw_dir)
198 if not os.path.exists(res_value_dir):
199 os.mkdir(res_value_dir)
206 pak_list_xml = Document()
207 resources_node = pak_list_xml.createElement('resources')
208 string_array_node = pak_list_xml.createElement('string-array')
209 string_array_node.setAttribute('name', 'xwalk_resources_list')
210 pak_list_xml.appendChild(resources_node)
211 resources_node.appendChild(string_array_node)
212 for pak in paks_to_copy:
213 source_file = os.path.join(out_dir, pak)
214 target_file = os.path.join(res_raw_dir, pak)
215 shutil.copyfile(source_file, target_file)
216 item_node = pak_list_xml.createElement('item')
217 item_node.appendChild(pak_list_xml.createTextNode(pak))
218 string_array_node.appendChild(item_node)
219 pak_list_file = open(os.path.join(res_value_dir,
220 'xwalk_resources_list.xml'), 'w')
221 pak_list_xml.writexml(pak_list_file, newl='\n', encoding='utf-8')
222 pak_list_file.close()
224 # Copy jar files to libs.
225 libs_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'libs')
226 if not os.path.exists(libs_dir):
232 'jsr_305_javalib.jar',
235 for lib in libs_to_copy:
236 source_file = os.path.join(out_dir, 'lib.java', lib)
237 target_file = os.path.join(libs_dir, lib)
238 shutil.copyfile(source_file, target_file)
240 # Copy native libraries.
241 source_dir = os.path.join(out_dir, XWALK_CORE_SHELL_APK, 'libs')
242 target_dir = libs_dir
243 distutils.dir_util.copy_tree(source_dir, target_dir)
246 def CopyDirAndPrefixDuplicates(input_dir, output_dir, prefix):
247 """ Copy the files into the output directory. If one file in input_dir folder
248 doesn't exist, copy it directly. If a file exists, copy it and rename the
249 file so that the resources won't be overrided. So all of them could be
250 packaged into the xwalk core library.
252 for root, _, files in os.walk(input_dir):
254 src_file = os.path.join(root, f)
255 relative_path = os.path.relpath(src_file, input_dir)
256 target_file = os.path.join(output_dir, relative_path)
257 target_dir_name = os.path.dirname(target_file)
258 if not os.path.exists(target_dir_name):
259 os.makedirs(target_dir_name)
260 # If the file exists, copy it and rename it with another name to
261 # avoid overwriting the existing one.
262 if os.path.exists(target_file):
263 target_base_name = os.path.basename(target_file)
264 target_base_name = prefix + '_' + target_base_name
265 target_file = os.path.join(target_dir_name, target_base_name)
266 shutil.copyfile(src_file, target_file)
269 def CopyResources(project_source, out_dir):
270 print 'Copying resources...'
271 res_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'res')
272 if os.path.exists(res_dir):
273 shutil.rmtree(res_dir)
275 # All resources should be in specific folders in res_directory.
276 # Since there might be some resource files with same names from
277 # different folders like ui_java, content_java and others,
278 # it's necessary to rename some files to avoid overridding.
280 # (package, prefix) turple.
281 ('ui/android/java/res', 'ui'),
282 ('content/public/android/java/res', 'content'),
283 ('xwalk/runtime/android/java/res', 'xwalk_core'),
286 # For each res, there are two generated res folder in out directory,
287 # they are res_grit and res_v14_compatibility.
288 for res, prefix in res_to_copy:
289 res_path_src = os.path.join(project_source, res)
290 res_path_grit = os.path.join(out_dir,
291 'gen', '%s_java' % prefix, 'res_grit')
292 res_path_v14 = os.path.join(out_dir,
293 'gen', '%s_java' % prefix, 'res_v14_compatibility')
295 for res_path in [res_path_src, res_path_grit, res_path_v14]:
296 CopyDirAndPrefixDuplicates(res_path, res_dir, prefix)
299 def PostCopyLibraryProject(out_dir):
300 print 'Post Copy Library Project...'
302 'org/chromium/content/common/common.aidl',
303 'org/chromium/net/IRemoteAndroidKeyStoreInterface.aidl',
305 for aidl in aidls_to_remove:
306 aidl_file = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'src', aidl)
307 if os.path.exists(aidl_file):
312 print 'Generating XWalkCore Library Project...'
313 option_parser = optparse.OptionParser()
314 AddGeneratorOptions(option_parser)
315 options, _ = option_parser.parse_args(argv)
317 if not os.path.exists(options.source):
318 print 'Source project does not exist, please provide correct directory.'
320 out_dir = options.target
322 # Clean directory for project first.
323 CleanLibraryProject(out_dir)
325 out_project_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME)
326 if not os.path.exists(out_project_dir):
327 os.mkdir(out_project_dir)
329 # Copy Eclipse project files of library project.
330 CopyProjectFiles(options.source, out_dir)
331 # Copy Java sources of chromium and xwalk.
332 CopyJavaSources(options.source, out_dir)
333 CopyGeneratedSources(out_dir)
334 # Copy binaries and resuorces.
335 CopyResources(options.source, out_dir)
336 CopyBinaries(out_dir)
337 # Copy JS API binding files.
338 CopyJSBindingFiles(options.source, out_dir)
339 # Post copy library project.
340 PostCopyLibraryProject(out_dir)
341 # Remove unused files.
342 mode = os.path.basename(os.path.normpath(out_dir))
343 RemoveUnusedFilesInReleaseMode(mode,
344 os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'libs'))
345 print 'Your Android library project has been created at %s' % (
348 if __name__ == '__main__':
349 sys.exit(main(sys.argv))