Add a relayout.py script to relayout an existing APK using a profile
Change-Id: Idd2518909b129d4d1af3b750873441422d897f69
diff --git a/tools/startup/relayout.py b/tools/startup/relayout.py
new file mode 100755
index 0000000..6220336
--- /dev/null
+++ b/tools/startup/relayout.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+# Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import argparse
+import os
+import subprocess
+import sys
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+import apk_masseur
+import toolhelper
+import utils
+
+def parse_options(argv):
+ result = argparse.ArgumentParser(
+ description='Relayout a given APK using a startup profile.')
+ result.add_argument('--apk',
+ help='Path to the .apk',
+ required=True)
+ result.add_argument('--out',
+ help='Destination of resulting apk',
+ required=True)
+ result.add_argument('--profile',
+ help='Path to the startup profile',
+ required=True)
+ options, args = result.parse_known_args(argv)
+ return options, args
+
+def get_min_api(apk):
+ aapt = os.path.join(utils.getAndroidBuildTools(), 'aapt')
+ cmd = [aapt, 'dump', 'badging', apk]
+ stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+ for line in stdout.splitlines():
+ if line.startswith('sdkVersion:\''):
+ return int(line[len('sdkVersion:\''): -1])
+ raise ValueError('Unexpected stdout: %s' % stdout)
+
+def main(argv):
+ (options, args) = parse_options(argv)
+ with utils.TempDir() as temp:
+ dex = os.path.join(temp, 'dex.zip')
+ d8_args = [
+ '--min-api', str(get_min_api(options.apk)),
+ '--output', dex,
+ '--no-desugaring',
+ '--release',
+ options.apk]
+ extra_args = ['-Dcom.android.tools.r8.startup.profile=%s' % options.profile]
+ toolhelper.run(
+ 'd8',
+ d8_args,
+ extra_args=extra_args,
+ main='com.android.tools.r8.D8')
+ apk_masseur.masseur(options.apk, dex=dex, out=options.out)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))