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
14 from common_function import RemoveUnusedFilesInReleaseMode
15 from xml.dom.minidom import Document
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.',
26 option_parser.add_option('--src-package', action='store_true',
28 help='Use java sources instead of java libs.')
31 def CleanLibraryProject(out_project_dir):
32 if os.path.exists(out_project_dir):
33 for item in os.listdir(out_project_dir):
34 sub_path = os.path.join(out_project_dir, item)
35 if os.path.isdir(sub_path):
36 shutil.rmtree(sub_path)
37 elif os.path.isfile(sub_path):
41 def CopyProjectFiles(project_source, out_project_dir):
42 """cp xwalk/build/android/xwalkcore_library_template/<file>
43 out/Release/xwalk_core_library/<file>
46 print 'Copying library project files...'
47 template_dir = os.path.join(project_source, 'xwalk', 'build', 'android',
48 'xwalkcore_library_template')
50 # AndroidManifest.xml from template.
51 'AndroidManifest.xml',
52 # Eclipse project properties from template.
56 # Ant properties file.
59 for f in files_to_copy:
60 source_file = os.path.join(template_dir, f)
61 target_file = os.path.join(out_project_dir, f)
63 shutil.copy2(source_file, target_file)
66 def CopyJSBindingFiles(project_source, out_project_dir):
67 print 'Copying js binding files...'
68 jsapi_dir = os.path.join(out_project_dir, 'res', 'raw')
69 if not os.path.exists(jsapi_dir):
70 os.makedirs(jsapi_dir)
73 'xwalk/experimental/launch_screen/launch_screen_api.js',
74 'xwalk/experimental/presentation/presentation_api.js',
75 'xwalk/runtime/android/core_internal/src/org/xwalk/core/'
76 + 'internal/extension/api/contacts/contacts_api.js',
77 'xwalk/runtime/android/core_internal/src/org/xwalk/core/'
78 + 'internal/extension/api/device_capabilities/device_capabilities_api.js',
79 'xwalk/runtime/android/core_internal/src/org/xwalk/core/'
80 + 'internal/extension/api/messaging/messaging_api.js'
83 # Copy JS binding file to assets/jsapi folder.
84 for jsfile in jsfiles_to_copy:
85 source_file = os.path.join(project_source, jsfile)
86 target_file = os.path.join(jsapi_dir, os.path.basename(source_file))
87 shutil.copyfile(source_file, target_file)
90 def CopyBinaries(out_dir, out_project_dir, src_package):
91 """cp out/Release/<pak> out/Release/xwalk_core_library/res/raw/<pak>
92 cp out/Release/lib.java/<lib> out/Release/xwalk_core_library/libs/<lib>
93 cp out/Release/xwalk_core_shell_apk/libs/*
94 out/Release/xwalk_core_library/libs
97 print 'Copying binaries...'
99 res_raw_dir = os.path.join(out_project_dir, 'res', 'raw')
100 res_value_dir = os.path.join(out_project_dir, 'res', 'values')
101 if not os.path.exists(res_raw_dir):
102 os.mkdir(res_raw_dir)
103 if not os.path.exists(res_value_dir):
104 os.mkdir(res_value_dir)
111 pak_list_xml = Document()
112 resources_node = pak_list_xml.createElement('resources')
113 string_array_node = pak_list_xml.createElement('string-array')
114 string_array_node.setAttribute('name', 'xwalk_resources_list')
115 pak_list_xml.appendChild(resources_node)
116 resources_node.appendChild(string_array_node)
117 for pak in paks_to_copy:
118 source_file = os.path.join(out_dir, pak)
119 target_file = os.path.join(res_raw_dir, pak)
120 shutil.copyfile(source_file, target_file)
121 item_node = pak_list_xml.createElement('item')
122 item_node.appendChild(pak_list_xml.createTextNode(pak))
123 string_array_node.appendChild(item_node)
124 pak_list_file = open(os.path.join(res_value_dir,
125 'xwalk_resources_list.xml'), 'w')
126 pak_list_xml.writexml(pak_list_file, newl='\n', encoding='utf-8')
127 pak_list_file.close()
129 libs_dir = os.path.join(out_project_dir, 'libs')
130 if not os.path.exists(libs_dir):
133 # Copy jar files to libs.
137 'jsr_305_javalib.jar',
141 'xwalk_core_library_java_app_part.jar',
142 'xwalk_core_library_java_library_part.jar',
145 for lib in libs_to_copy:
146 source_file = os.path.join(out_dir, 'lib.java', lib)
147 target_file = os.path.join(libs_dir, lib)
148 shutil.copyfile(source_file, target_file)
150 # Copy native libraries.
151 source_dir = os.path.join(out_dir, XWALK_CORE_SHELL_APK, 'libs')
152 target_dir = libs_dir
153 distutils.dir_util.copy_tree(source_dir, target_dir)
156 def CopyDirAndPrefixDuplicates(input_dir, output_dir, prefix):
157 """ Copy the files into the output directory. If one file in input_dir folder
158 doesn't exist, copy it directly. If a file exists, copy it and rename the
159 file so that the resources won't be overrided. So all of them could be
160 packaged into the xwalk core library.
162 for root, _, files in os.walk(input_dir):
164 src_file = os.path.join(root, f)
165 relative_path = os.path.relpath(src_file, input_dir)
166 target_file = os.path.join(output_dir, relative_path)
167 target_dir_name = os.path.dirname(target_file)
168 if not os.path.exists(target_dir_name):
169 os.makedirs(target_dir_name)
170 # If the file exists, copy it and rename it with another name to
171 # avoid overwriting the existing one.
172 if os.path.exists(target_file):
173 target_base_name = os.path.basename(target_file)
174 target_base_name = prefix + '_' + target_base_name
175 target_file = os.path.join(target_dir_name, target_base_name)
176 shutil.copyfile(src_file, target_file)
179 def MoveImagesToNonMdpiFolders(res_root):
180 """Move images from drawable-*-mdpi-* folders to drawable-* folders.
182 Why? http://crbug.com/289843
184 Copied from build/android/gyp/package_resources.py.
186 for src_dir_name in os.listdir(res_root):
187 src_components = src_dir_name.split('-')
188 if src_components[0] != 'drawable' or 'mdpi' not in src_components:
190 src_dir = os.path.join(res_root, src_dir_name)
191 if not os.path.isdir(src_dir):
193 dst_components = [c for c in src_components if c != 'mdpi']
194 assert dst_components != src_components
195 dst_dir_name = '-'.join(dst_components)
196 dst_dir = os.path.join(res_root, dst_dir_name)
197 if not os.path.isdir(dst_dir):
199 for src_file_name in os.listdir(src_dir):
200 if not src_file_name.endswith('.png'):
202 src_file = os.path.join(src_dir, src_file_name)
203 dst_file = os.path.join(dst_dir, src_file_name)
204 assert not os.path.lexists(dst_file)
205 shutil.move(src_file, dst_file)
208 def ReplaceCrunchedImage(project_source, filename, filepath):
209 """Replace crunched images with source images.
212 'content/public/android/java/res',
213 'ui/android/java/res'
216 pathname = os.path.basename(filepath)
217 #replace crunched 9-patch image resources.
218 for search in search_dir:
219 absdir = os.path.join(project_source, search)
220 for dirname, _, files in os.walk(absdir):
221 if filename in files:
222 relativedir = os.path.basename(dirname)
223 if (pathname == 'drawable' and relativedir == 'drawable-mdpi') or \
224 relativedir == pathname:
225 source_file = os.path.abspath(os.path.join(dirname, filename))
226 target_file = os.path.join(filepath, filename)
227 shutil.copyfile(source_file, target_file)
231 def CopyResources(project_source, out_dir, out_project_dir):
232 print 'Copying resources...'
233 res_dir = os.path.join(out_project_dir, 'res')
234 temp_dir = os.path.join(out_project_dir, 'temp')
235 if os.path.exists(res_dir):
236 shutil.rmtree(res_dir)
237 if os.path.exists(temp_dir):
238 shutil.rmtree(temp_dir)
240 # All resources should be in specific folders in res_directory.
241 # Since there might be some resource files with same names from
242 # different folders like ui_java, content_java and others,
243 # it's necessary to rename some files to avoid overridding.
247 'content_strings_grd.zip',
249 'ui_strings_grd.zip',
250 'xwalk_core_internal_java.zip',
251 'xwalk_core_strings.zip'
254 for res_zip in res_to_copy:
255 zip_file = os.path.join(out_dir, 'res.java', res_zip)
256 zip_name = os.path.splitext(res_zip)[0]
257 if not os.path.isfile(zip_file):
258 raise Exception('Resource zip not found: ' + zip_file)
259 subdir = os.path.join(temp_dir, zip_name)
260 if os.path.isdir(subdir):
261 raise Exception('Resource zip name conflict: ' + zip_name)
263 with zipfile.ZipFile(zip_file) as z:
264 z.extractall(path=subdir)
265 CopyDirAndPrefixDuplicates(subdir, res_dir, zip_name)
266 MoveImagesToNonMdpiFolders(res_dir)
268 if os.path.isdir(temp_dir):
269 shutil.rmtree(temp_dir)
271 #search 9-patch, then replace it with uncrunch image.
272 for dirname, _, files in os.walk(res_dir):
273 for filename in files:
274 if filename.endswith('.9.png'):
275 ReplaceCrunchedImage(project_source, filename, dirname)
279 print 'Generating XWalkCore Library Project...'
280 option_parser = optparse.OptionParser()
281 AddGeneratorOptions(option_parser)
282 options, _ = option_parser.parse_args(argv)
284 if not os.path.exists(options.source):
285 print 'Source project does not exist, please provide correct directory.'
287 out_dir = options.target
288 if options.src_package:
289 out_project_dir = os.path.join(out_dir, 'xwalk_core_library_src')
291 out_project_dir = os.path.join(out_dir, 'xwalk_core_library')
293 # Clean directory for project first.
294 CleanLibraryProject(out_project_dir)
296 if not os.path.exists(out_project_dir):
297 os.mkdir(out_project_dir)
299 # Copy Eclipse project files of library project.
300 CopyProjectFiles(options.source, out_project_dir)
301 # Copy binaries and resuorces.
302 CopyResources(options.source, out_dir, out_project_dir)
303 CopyBinaries(out_dir, out_project_dir, options.src_package)
304 # Copy JS API binding files.
305 CopyJSBindingFiles(options.source, out_project_dir)
306 # Remove unused files.
307 mode = os.path.basename(os.path.normpath(out_dir))
308 RemoveUnusedFilesInReleaseMode(mode,
309 os.path.join(out_project_dir, 'libs'))
310 # Create empty src directory
311 src_dir = os.path.join(out_project_dir, 'src')
312 if not os.path.isdir(src_dir):
314 readme = os.path.join(src_dir, 'README.md')
315 open(readme, 'w').write(
316 "# Source folder for xwalk_core_library\n"
317 "## Why it's empty\n"
318 "xwalk_core_library doesn't contain java sources.\n"
319 "## Why put me here\n"
320 "To make archives keep the folder, "
321 "the src directory is needed to build an apk by ant.")
322 print 'Your Android library project has been created at %s' % (
325 if __name__ == '__main__':
326 sys.exit(main(sys.argv))