build_sky_apk.dart 3.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 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";

15 16
class AssetBuilder {
  final Directory outDir;
17

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
  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);
  }
86 87 88 89 90 91 92 93 94 95
}

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);

Devon Carew's avatar
Devon Carew committed
96 97 98 99 100 101 102
  if (args['help']) {
    print('usage: pub run sky_tools:build_sky_apk <options>');
    print('');
    print(parser.usage);
    return;
  }

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
  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);
126
}