| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:io'; |
| |
| import 'package:args/args.dart'; |
| |
| const String kBuildToolsVersion = '22.0.1'; |
| const String kAndroidPlatformVersion = '22'; |
| |
| const String kKeystoreKeyName = "chromiumdebugkey"; |
| const String kKeystorePassword = "chromium"; |
| |
| class AssetBuilder { |
| final Directory outDir; |
| |
| Directory _assetDir; |
| |
| AssetBuilder(this.outDir) { |
| _assetDir = new Directory('${outDir.path}/assets'); |
| _assetDir.createSync(recursive: true); |
| } |
| |
| void add(File asset, String assetName) { |
| asset.copySync('${_assetDir.path}/$assetName'); |
| } |
| |
| Directory get directory => _assetDir; |
| } |
| |
| class ApkBuilder { |
| final String androidSDK; |
| |
| File _androidJar; |
| File _aapt; |
| File _zipalign; |
| String _jarsigner; |
| |
| ApkBuilder(this.androidSDK) { |
| _androidJar = new File('$androidSDK/platforms/android-$kAndroidPlatformVersion/android.jar'); |
| |
| String buildTools = '$androidSDK/build-tools/$kBuildToolsVersion'; |
| _aapt = new File('$buildTools/aapt'); |
| _zipalign = new File('$buildTools/zipalign'); |
| _jarsigner = 'jarsigner'; |
| } |
| |
| void package(File androidManifest, Directory assets, File outputApk) { |
| _run(_aapt.path, [ |
| 'package', |
| '-M', androidManifest.path, |
| '-A', assets.path, |
| '-I', _androidJar.path, |
| '-F', outputApk.path, |
| ]); |
| } |
| |
| void add(Directory base, String resource, File outputApk) { |
| _run(_aapt.path, [ |
| 'add', '-f', outputApk.absolute.path, resource, |
| ], workingDirectory: base.path); |
| } |
| |
| void sign(File keystore, String keystorePassword, String keyName, File outputApk) { |
| _run(_jarsigner, [ |
| '-keystore', keystore.path, |
| '-storepass', keystorePassword, |
| outputApk.path, |
| keyName, |
| ]); |
| } |
| |
| void align(File unalignedApk, File outputApk) { |
| _run(_zipalign.path, ['4', unalignedApk.path, outputApk.path]); |
| } |
| |
| void _run(String command, List<String> args, { String workingDirectory }) { |
| ProcessResult result = Process.runSync( |
| command, args, workingDirectory: workingDirectory); |
| if (result.exitCode == 0) |
| return; |
| stdout.write(result.stdout); |
| stderr.write(result.stderr); |
| } |
| } |
| |
| main(List<String> argv) async { |
| ArgParser parser = new ArgParser(); |
| parser.addFlag('help', abbr: 'h', negatable: false); |
| parser.addOption('android-sdk'); |
| parser.addOption('skyx'); |
| |
| ArgResults args = parser.parse(argv); |
| |
| if (args['help']) { |
| print('usage: pub run sky_tools:build_sky_apk <options>'); |
| print(''); |
| print(parser.usage); |
| return; |
| } |
| |
| Directory artifacts = new Directory('artifacts'); |
| File keystore = new File('${artifacts.path}/chromium-debug.keystore'); |
| File androidManifest = new File('${artifacts.path}/AndroidManifest.xml'); |
| File icuData = new File('${artifacts.path}/assets/icudtl.dat'); |
| File appSkyx = new File(args['skyx']); |
| |
| Directory outDir = new Directory('out'); |
| outDir.createSync(recursive: true); |
| |
| AssetBuilder assetBuilder = new AssetBuilder(outDir); |
| assetBuilder.add(icuData, 'icudtl.dat'); |
| assetBuilder.add(appSkyx, 'app.skyx'); |
| |
| ApkBuilder builder = new ApkBuilder(args['android-sdk']); |
| |
| File unalignedApk = new File('${outDir.path}/Example.apk.unaligned'); |
| File finalApk = new File('${outDir.path}/Example.apk'); |
| |
| builder.package(androidManifest, assetBuilder.directory, unalignedApk); |
| builder.add(artifacts, 'classes.dex', unalignedApk); |
| builder.add(artifacts, 'lib/armeabi-v7a/libsky_shell.so', unalignedApk); |
| builder.sign(keystore, kKeystorePassword, kKeystoreKeyName, unalignedApk); |
| builder.align(unalignedApk, finalApk); |
| } |