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/ActivityState.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/TopControlsState.java',
136 'org/chromium/media/ImageFormat.java',
137 'org/chromium/net/CertificateMimeType.java',
138 'org/chromium/net/CertVerifyStatusAndroid.java',
139 'org/chromium/net/NetError.java',
140 'org/chromium/net/PrivateKeyType.java',
141 'org/chromium/ui/WindowOpenDisposition.java'
144 for source in generated_srcs_to_copy:
145 source_file = os.path.join(out_dir, 'gen', 'templates', source)
146 target_file = os.path.join(
147 out_dir, LIBRARY_PROJECT_NAME, 'src', source)
148 shutil.copyfile(source_file, target_file)
150 source_file = os.path.join(out_dir, XWALK_CORE_SHELL_APK,
151 'native_libraries_java',
152 'NativeLibraries.java')
153 target_file = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'src', 'org',
154 'chromium', 'base', 'library_loader',
155 'NativeLibraries.java')
156 shutil.copyfile(source_file, target_file)
158 def CopyJSBindingFiles(project_source, out_dir):
159 print 'Copying js binding files...'
160 jsapi_dir = os.path.join(out_dir,
161 LIBRARY_PROJECT_NAME,
164 if not os.path.exists(jsapi_dir):
165 os.makedirs(jsapi_dir)
168 'xwalk/experimental/launch_screen/launch_screen_api.js',
169 'xwalk/experimental/presentation/presentation_api.js',
170 'xwalk/runtime/extension/screen_orientation_api.js',
171 'xwalk/sysapps/device_capabilities/device_capabilities_api.js'
174 # Copy JS binding file to assets/jsapi folder.
175 for jsfile in jsfiles_to_copy:
176 source_file = os.path.join(project_source, jsfile)
177 target_file = os.path.join(jsapi_dir, os.path.basename(source_file))
178 shutil.copyfile(source_file, target_file)
181 def CopyBinaries(out_dir):
182 """cp out/Release/<pak> out/Release/xwalk_core_library/res/raw/<pak>
183 cp out/Release/lib.java/<lib> out/Release/xwalk_core_library/libs/<lib>
184 cp out/Release/xwalk_core_shell_apk/libs/*
185 out/Release/xwalk_core_library/libs
188 print 'Copying binaries...'
190 res_raw_dir = os.path.join(
191 out_dir, LIBRARY_PROJECT_NAME, 'res', 'raw')
192 res_value_dir = os.path.join(
193 out_dir, LIBRARY_PROJECT_NAME, 'res', 'values')
194 if not os.path.exists(res_raw_dir):
195 os.mkdir(res_raw_dir)
196 if not os.path.exists(res_value_dir):
197 os.mkdir(res_value_dir)
203 pak_list_xml = Document()
204 resources_node = pak_list_xml.createElement('resources')
205 string_array_node = pak_list_xml.createElement('string-array')
206 string_array_node.setAttribute('name', 'xwalk_resources_list')
207 pak_list_xml.appendChild(resources_node)
208 resources_node.appendChild(string_array_node)
209 for pak in paks_to_copy:
210 source_file = os.path.join(out_dir, pak)
211 target_file = os.path.join(res_raw_dir, pak)
212 shutil.copyfile(source_file, target_file)
213 item_node = pak_list_xml.createElement('item')
214 item_node.appendChild(pak_list_xml.createTextNode(pak))
215 string_array_node.appendChild(item_node)
216 pak_list_file = open(os.path.join(res_value_dir,
217 'xwalk_resources_list.xml'), 'w')
218 pak_list_xml.writexml(pak_list_file, newl='\n', encoding='utf-8')
219 pak_list_file.close()
221 # Copy jar files to libs.
222 libs_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'libs')
223 if not os.path.exists(libs_dir):
229 'jsr_305_javalib.jar',
232 for lib in libs_to_copy:
233 source_file = os.path.join(out_dir, 'lib.java', lib)
234 target_file = os.path.join(libs_dir, lib)
235 shutil.copyfile(source_file, target_file)
237 # Copy native libraries.
238 source_dir = os.path.join(out_dir, XWALK_CORE_SHELL_APK, 'libs')
239 target_dir = libs_dir
240 distutils.dir_util.copy_tree(source_dir, target_dir)
243 def CopyDirAndPrefixDuplicates(input_dir, output_dir, prefix):
244 """ Copy the files into the output directory. If one file in input_dir folder
245 doesn't exist, copy it directly. If a file exists, copy it and rename the
246 file so that the resources won't be overrided. So all of them could be
247 packaged into the xwalk core library.
249 for root, _, files in os.walk(input_dir):
251 src_file = os.path.join(root, f)
252 relative_path = os.path.relpath(src_file, input_dir)
253 target_file = os.path.join(output_dir, relative_path)
254 target_dir_name = os.path.dirname(target_file)
255 if not os.path.exists(target_dir_name):
256 os.makedirs(target_dir_name)
257 # If the file exists, copy it and rename it with another name to
258 # avoid overwriting the existing one.
259 if os.path.exists(target_file):
260 target_base_name = os.path.basename(target_file)
261 target_base_name = prefix + '_' + target_base_name
262 target_file = os.path.join(target_dir_name, target_base_name)
263 shutil.copyfile(src_file, target_file)
266 def CopyResources(project_source, out_dir):
267 print 'Copying resources...'
268 res_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'res')
269 if os.path.exists(res_dir):
270 shutil.rmtree(res_dir)
272 # All resources should be in specific folders in res_directory.
273 # Since there might be some resource files with same names from
274 # different folders like ui_java, content_java and others,
275 # it's necessary to rename some files to avoid overridding.
277 # (package, prefix) turple.
278 ('ui/android/java/res', 'ui'),
279 ('content/public/android/java/res', 'content'),
280 ('xwalk/runtime/android/java/res', 'xwalk_core'),
283 # For each res, there are two generated res folder in out directory,
284 # they are res_grit and res_v14_compatibility.
285 for res, prefix in res_to_copy:
286 res_path_src = os.path.join(project_source, res)
287 res_path_grit = os.path.join(out_dir,
288 'gen', '%s_java' % prefix, 'res_grit')
289 res_path_v14 = os.path.join(out_dir,
290 'gen', '%s_java' % prefix, 'res_v14_compatibility')
292 for res_path in [res_path_src, res_path_grit, res_path_v14]:
293 CopyDirAndPrefixDuplicates(res_path, res_dir, prefix)
296 def PostCopyLibraryProject(out_dir):
297 print 'Post Copy Library Project...'
299 'org/chromium/content/common/common.aidl',
300 'org/chromium/net/IRemoteAndroidKeyStoreInterface.aidl',
302 for aidl in aidls_to_remove:
303 aidl_file = os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'src', aidl)
304 if os.path.exists(aidl_file):
309 print 'Generating XWalkCore Library Project...'
310 option_parser = optparse.OptionParser()
311 AddGeneratorOptions(option_parser)
312 options, _ = option_parser.parse_args(argv)
314 if not os.path.exists(options.source):
315 print 'Source project does not exist, please provide correct directory.'
317 out_dir = options.target
319 # Clean directory for project first.
320 CleanLibraryProject(out_dir)
322 out_project_dir = os.path.join(out_dir, LIBRARY_PROJECT_NAME)
323 if not os.path.exists(out_project_dir):
324 os.mkdir(out_project_dir)
326 # Copy Eclipse project files of library project.
327 CopyProjectFiles(options.source, out_dir)
328 # Copy Java sources of chromium and xwalk.
329 CopyJavaSources(options.source, out_dir)
330 CopyGeneratedSources(out_dir)
331 # Copy binaries and resuorces.
332 CopyResources(options.source, out_dir)
333 CopyBinaries(out_dir)
334 # Copy JS API binding files.
335 CopyJSBindingFiles(options.source, out_dir)
336 # Post copy library project.
337 PostCopyLibraryProject(out_dir)
338 # Remove unused files.
339 mode = os.path.basename(os.path.normpath(out_dir))
340 RemoveUnusedFilesInReleaseMode(mode,
341 os.path.join(out_dir, LIBRARY_PROJECT_NAME, 'libs'))
342 print 'Your Android library project has been created at %s' % (
345 if __name__ == '__main__':
346 sys.exit(main(sys.argv))