am c0f10644
: Merge "make SignApk do zip alignment"
* commit 'c0f10644bf877fae44e8aa5ebfff41f0e27af197': make SignApk do zip alignment
This commit is contained in:
commit
c793348298
1 changed files with 66 additions and 10 deletions
|
@ -461,24 +461,75 @@ class SignApk {
|
|||
* reduce variation in the output file and make incremental OTAs
|
||||
* more efficient.
|
||||
*/
|
||||
private static void copyFiles(Manifest manifest,
|
||||
JarFile in, JarOutputStream out, long timestamp) throws IOException {
|
||||
private static void copyFiles(Manifest manifest, JarFile in, JarOutputStream out,
|
||||
long timestamp, int alignment) throws IOException {
|
||||
byte[] buffer = new byte[4096];
|
||||
int num;
|
||||
|
||||
Map<String, Attributes> entries = manifest.getEntries();
|
||||
ArrayList<String> names = new ArrayList<String>(entries.keySet());
|
||||
Collections.sort(names);
|
||||
|
||||
boolean firstEntry = true;
|
||||
long offset = 0L;
|
||||
|
||||
// We do the copy in two passes -- first copying all the
|
||||
// entries that are STORED, then copying all the entries that
|
||||
// have any other compression flag (which in practice means
|
||||
// DEFLATED). This groups all the stored entries together at
|
||||
// the start of the file and makes it easier to do alignment
|
||||
// on them (since only stored entries are aligned).
|
||||
|
||||
for (String name : names) {
|
||||
JarEntry inEntry = in.getJarEntry(name);
|
||||
JarEntry outEntry = null;
|
||||
if (inEntry.getMethod() == JarEntry.STORED) {
|
||||
// Preserve the STORED method of the input entry.
|
||||
outEntry = new JarEntry(inEntry);
|
||||
} else {
|
||||
// Create a new entry so that the compressed len is recomputed.
|
||||
outEntry = new JarEntry(name);
|
||||
if (inEntry.getMethod() != JarEntry.STORED) continue;
|
||||
// Preserve the STORED method of the input entry.
|
||||
outEntry = new JarEntry(inEntry);
|
||||
outEntry.setTime(timestamp);
|
||||
|
||||
// 'offset' is the offset into the file at which we expect
|
||||
// the file data to begin. This is the value we need to
|
||||
// make a multiple of 'alignement'.
|
||||
offset += JarFile.LOCHDR + outEntry.getName().length();
|
||||
if (firstEntry) {
|
||||
// The first entry in a jar file has an extra field of
|
||||
// four bytes that you can't get rid of; any extra
|
||||
// data you specify in the JarEntry is appended to
|
||||
// these forced four bytes. This is JAR_MAGIC in
|
||||
// JarOutputStream; the bytes are 0xfeca0000.
|
||||
offset += 4;
|
||||
firstEntry = false;
|
||||
}
|
||||
if (alignment > 0 && (offset % alignment != 0)) {
|
||||
// Set the "extra data" of the entry to between 1 and
|
||||
// alignment-1 bytes, to make the file data begin at
|
||||
// an aligned offset.
|
||||
int needed = alignment - (int)(offset % alignment);
|
||||
outEntry.setExtra(new byte[needed]);
|
||||
offset += needed;
|
||||
}
|
||||
|
||||
out.putNextEntry(outEntry);
|
||||
|
||||
InputStream data = in.getInputStream(inEntry);
|
||||
while ((num = data.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, num);
|
||||
offset += num;
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
|
||||
// Copy all the non-STORED entries. We don't attempt to
|
||||
// maintain the 'offset' variable past this point; we don't do
|
||||
// alignment on these entries.
|
||||
|
||||
for (String name : names) {
|
||||
JarEntry inEntry = in.getJarEntry(name);
|
||||
JarEntry outEntry = null;
|
||||
if (inEntry.getMethod() == JarEntry.STORED) continue;
|
||||
// Create a new entry so that the compressed len is recomputed.
|
||||
outEntry = new JarEntry(name);
|
||||
outEntry.setTime(timestamp);
|
||||
out.putNextEntry(outEntry);
|
||||
|
||||
|
@ -589,7 +640,7 @@ class SignApk {
|
|||
long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
|
||||
|
||||
Manifest manifest = addDigestsToManifest(inputJar, hash);
|
||||
copyFiles(manifest, inputJar, outputJar, timestamp);
|
||||
copyFiles(manifest, inputJar, outputJar, timestamp, 0);
|
||||
addOtacert(outputJar, publicKeyFile, timestamp, manifest, hash);
|
||||
|
||||
signFile(manifest, inputJar,
|
||||
|
@ -778,6 +829,7 @@ class SignApk {
|
|||
|
||||
private static void usage() {
|
||||
System.err.println("Usage: signapk [-w] " +
|
||||
"[-a <alignment>] " +
|
||||
"[-providerClass <className>] " +
|
||||
"publickey.x509[.pem] privatekey.pk8 " +
|
||||
"[publickey2.x509[.pem] privatekey2.pk8 ...] " +
|
||||
|
@ -794,6 +846,7 @@ class SignApk {
|
|||
boolean signWholeFile = false;
|
||||
String providerClass = null;
|
||||
String providerArg = null;
|
||||
int alignment = 4;
|
||||
|
||||
int argstart = 0;
|
||||
while (argstart < args.length && args[argstart].startsWith("-")) {
|
||||
|
@ -806,6 +859,9 @@ class SignApk {
|
|||
}
|
||||
providerClass = args[++argstart];
|
||||
++argstart;
|
||||
} else if ("-a".equals(args[argstart])) {
|
||||
alignment = Integer.parseInt(args[++argstart]);
|
||||
++argstart;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
|
@ -872,7 +928,7 @@ class SignApk {
|
|||
outputJar.setLevel(9);
|
||||
|
||||
Manifest manifest = addDigestsToManifest(inputJar, hashes);
|
||||
copyFiles(manifest, inputJar, outputJar, timestamp);
|
||||
copyFiles(manifest, inputJar, outputJar, timestamp, alignment);
|
||||
signFile(manifest, inputJar, publicKey, privateKey, outputJar);
|
||||
outputJar.close();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue