| OLD | NEW | 
|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python | 
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 """ Merges a 64-bit and a 32-bit APK into a single APK | 6 """ Merges a 64-bit and a 32-bit APK into a single APK | 
| 7 | 7 | 
| 8 This script is used to merge two APKs which have only 32-bit or 64-bit | 8 This script is used to merge two APKs which have only 32-bit or 64-bit | 
| 9 binaries respectively into a APK that has both 32-bit and 64-bit binaries | 9 binaries respectively into a APK that has both 32-bit and 64-bit binaries | 
| 10 for 64-bit Android platform. | 10 for 64-bit Android platform. | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 112         '  unexpected files: %s' % pprint.pformat(unexpected_file_set)) | 112         '  unexpected files: %s' % pprint.pformat(unexpected_file_set)) | 
| 113   if missing_file_set: | 113   if missing_file_set: | 
| 114     errors.append('  missing files: %s' % pprint.pformat(missing_file_set)) | 114     errors.append('  missing files: %s' % pprint.pformat(missing_file_set)) | 
| 115   if duplicate_file_set: | 115   if duplicate_file_set: | 
| 116     errors.append('  duplicate files: %s' % pprint.pformat(duplicate_file_set)) | 116     errors.append('  duplicate files: %s' % pprint.pformat(duplicate_file_set)) | 
| 117 | 117 | 
| 118   if errors: | 118   if errors: | 
| 119     raise ApkMergeFailure( | 119     raise ApkMergeFailure( | 
| 120         "Files don't match expectations:\n%s" % '\n'.join(errors)) | 120         "Files don't match expectations:\n%s" % '\n'.join(errors)) | 
| 121 | 121 | 
| 122 def AddDiffFiles(diff_files, tmp_dir_32, tmp_apk, expected_files, | 122 | 
|  | 123 def AddDiffFiles(diff_files, tmp_dir_32, out_zip, expected_files, | 
| 123                  component_build, uncompress_shared_libraries): | 124                  component_build, uncompress_shared_libraries): | 
| 124   """ Insert files only present in 32-bit APK into 64-bit APK (tmp_apk). """ | 125   """ Insert files only present in 32-bit APK into 64-bit APK (tmp_apk). """ | 
| 125   old_dir = os.getcwd() | 126   for diff_file in diff_files: | 
| 126   # Move into 32-bit directory to make sure the files we insert have correct | 127     if component_build and diff_file.endswith('.so'): | 
| 127   # relative paths. | 128       compress = not uncompress_shared_libraries | 
| 128   os.chdir(tmp_dir_32) | 129     else: | 
| 129   try: | 130       compress = expected_files[os.path.basename(diff_file)] | 
| 130     for diff_file in diff_files: | 131     build_utils.AddToZipHermetic(out_zip, | 
| 131       if component_build and diff_file.endswith('.so'): | 132                                  diff_file, | 
| 132         extra_flags = [] | 133                                  os.path.join(tmp_dir_32, diff_file), | 
| 133         if uncompress_shared_libraries: | 134                                  compress=compress) | 
| 134           extra_flags = ['-0'] |  | 
| 135       else: |  | 
| 136         extra_flags = expected_files[os.path.basename(diff_file)] |  | 
| 137       build_utils.CheckOutput( |  | 
| 138           [ |  | 
| 139               'zip', '-r', '-X', '--no-dir-entries', tmp_apk, diff_file |  | 
| 140           ] + extra_flags) |  | 
| 141   except build_utils.CalledProcessError as e: |  | 
| 142     raise ApkMergeFailure( |  | 
| 143         'Failed to add file %s to APK: %s' % (diff_file, e.output)) |  | 
| 144   finally: |  | 
| 145     # Move out of 32-bit directory when done |  | 
| 146     os.chdir(old_dir) |  | 
| 147 |  | 
| 148 |  | 
| 149 def RemoveMetafiles(tmp_apk): |  | 
| 150   """ Remove all meta info to avoid certificate clashes """ |  | 
| 151   try: |  | 
| 152     build_utils.CheckOutput(['zip', '-d', tmp_apk, 'META-INF/*']) |  | 
| 153   except build_utils.CalledProcessError as e: |  | 
| 154     raise ApkMergeFailure('Failed to delete Meta folder: ' + e.output) |  | 
| 155 | 135 | 
| 156 | 136 | 
| 157 def SignAndAlignApk(tmp_apk, signed_tmp_apk, new_apk, zipalign_path, | 137 def SignAndAlignApk(tmp_apk, signed_tmp_apk, new_apk, zipalign_path, | 
| 158                     keystore_path, key_name, key_password, | 138                     keystore_path, key_name, key_password, | 
| 159                     page_align_shared_libraries): | 139                     page_align_shared_libraries): | 
| 160   try: | 140   try: | 
| 161     finalize_apk.JarSigner( | 141     finalize_apk.JarSigner( | 
| 162         keystore_path, | 142         keystore_path, | 
| 163         key_name, | 143         key_name, | 
| 164         key_password, | 144         key_password, | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 187         ret = 'mips64' | 167         ret = 'mips64' | 
| 188       elif abi == 'x86': | 168       elif abi == 'x86': | 
| 189         ret = 'x86_64' | 169         ret = 'x86_64' | 
| 190       else: | 170       else: | 
| 191         raise ApkMergeFailure('Unsupported abi ' + abi) | 171         raise ApkMergeFailure('Unsupported abi ' + abi) | 
| 192   if ret == '': | 172   if ret == '': | 
| 193     raise ApkMergeFailure('Failed to find secondary abi') | 173     raise ApkMergeFailure('Failed to find secondary abi') | 
| 194   return ret | 174   return ret | 
| 195 | 175 | 
| 196 def MergeApk(args, tmp_apk, tmp_dir_32, tmp_dir_64): | 176 def MergeApk(args, tmp_apk, tmp_dir_32, tmp_dir_64): | 
| 197   # Expected files to copy from 32- to 64-bit APK together with an extra flag | 177   # Expected files to copy from 32- to 64-bit APK together with whether to | 
| 198   # setting the compression level of the file | 178   # compress within the .apk. | 
| 199   expected_files = {'snapshot_blob_32.bin': ['-0']} | 179   expected_files = {'snapshot_blob_32.bin': False} | 
| 200   if args.shared_library: | 180   if args.shared_library: | 
| 201     expected_files[args.shared_library] = [] | 181     expected_files[args.shared_library] = not args.uncompress_shared_libraries | 
| 202 |  | 
| 203   if args.debug: | 182   if args.debug: | 
| 204     expected_files['gdbserver'] = [] | 183     expected_files['gdbserver'] = True | 
| 205   if args.uncompress_shared_libraries and args.shared_library: |  | 
| 206     expected_files[args.shared_library] += ['-0'] |  | 
| 207 |  | 
| 208   shutil.copyfile(args.apk_64bit, tmp_apk) |  | 
| 209 | 184 | 
| 210   # need to unpack APKs to compare their contents | 185   # need to unpack APKs to compare their contents | 
| 211   UnpackApk(args.apk_64bit, tmp_dir_64) | 186   UnpackApk(args.apk_64bit, tmp_dir_64) | 
| 212   UnpackApk(args.apk_32bit, tmp_dir_32) | 187   UnpackApk(args.apk_32bit, tmp_dir_32) | 
| 213 | 188 | 
| 214   ignores = ['META-INF', 'AndroidManifest.xml'] | 189   ignores = ['META-INF', 'AndroidManifest.xml'] | 
| 215   if args.ignore_classes_dex: | 190   if args.ignore_classes_dex: | 
| 216     ignores += ['classes.dex', 'classes2.dex'] | 191     ignores += ['classes.dex', 'classes2.dex'] | 
| 217   if args.debug: | 192   if args.debug: | 
| 218     # see http://crbug.com/648720 | 193     # see http://crbug.com/648720 | 
| 219     ignores += ['webview_licenses.notice'] | 194     ignores += ['webview_licenses.notice'] | 
| 220 | 195 | 
| 221   dcmp = filecmp.dircmp( | 196   dcmp = filecmp.dircmp( | 
| 222       tmp_dir_64, | 197       tmp_dir_64, | 
| 223       tmp_dir_32, | 198       tmp_dir_32, | 
| 224       ignore=ignores) | 199       ignore=ignores) | 
| 225 | 200 | 
| 226   diff_files = GetDiffFiles(dcmp, tmp_dir_32) | 201   diff_files = GetDiffFiles(dcmp, tmp_dir_32) | 
| 227 | 202 | 
| 228   # Check that diff_files match exactly those files we want to insert into | 203   # Check that diff_files match exactly those files we want to insert into | 
| 229   # the 64-bit APK. | 204   # the 64-bit APK. | 
| 230   CheckFilesExpected(diff_files, expected_files, args.component_build) | 205   CheckFilesExpected(diff_files, expected_files, args.component_build) | 
| 231 | 206 | 
| 232   RemoveMetafiles(tmp_apk) | 207   with zipfile.ZipFile(tmp_apk, 'w') as out_zip: | 
| 233 | 208     build_utils.MergeZips(out_zip, [args.apk_64bit], | 
| 234   AddDiffFiles(diff_files, tmp_dir_32, tmp_apk, expected_files, | 209                           exclude_patterns=['META-INF/*']) | 
| 235                args.component_build, args.uncompress_shared_libraries) | 210     AddDiffFiles(diff_files, tmp_dir_32, out_zip, expected_files, | 
|  | 211                  args.component_build, args.uncompress_shared_libraries) | 
| 236 | 212 | 
| 237 | 213 | 
| 238 def main(): | 214 def main(): | 
| 239   parser = argparse.ArgumentParser( | 215   parser = argparse.ArgumentParser( | 
| 240       description='Merge a 32-bit APK into a 64-bit APK') | 216       description='Merge a 32-bit APK into a 64-bit APK') | 
| 241   # Using type=os.path.abspath converts file paths to absolute paths so that | 217   # Using type=os.path.abspath converts file paths to absolute paths so that | 
| 242   # we can change working directory without affecting these paths | 218   # we can change working directory without affecting these paths | 
| 243   parser.add_argument('--apk_32bit', required=True, type=os.path.abspath) | 219   parser.add_argument('--apk_32bit', required=True, type=os.path.abspath) | 
| 244   parser.add_argument('--apk_64bit', required=True, type=os.path.abspath) | 220   parser.add_argument('--apk_64bit', required=True, type=os.path.abspath) | 
| 245   parser.add_argument('--out_apk', required=True, type=os.path.abspath) | 221   parser.add_argument('--out_apk', required=True, type=os.path.abspath) | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 280   except ApkMergeFailure as e: | 256   except ApkMergeFailure as e: | 
| 281     print e | 257     print e | 
| 282     return 1 | 258     return 1 | 
| 283   finally: | 259   finally: | 
| 284     shutil.rmtree(tmp_dir) | 260     shutil.rmtree(tmp_dir) | 
| 285   return 0 | 261   return 0 | 
| 286 | 262 | 
| 287 | 263 | 
| 288 if __name__ == '__main__': | 264 if __name__ == '__main__': | 
| 289   sys.exit(main()) | 265   sys.exit(main()) | 
| OLD | NEW | 
|---|