aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java47
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java14
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java23
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java4
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java4
5 files changed, 45 insertions, 47 deletions
diff --git a/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java b/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java
index e03348cdaa..7e1d8741ca 100644
--- a/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java
+++ b/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java
@@ -23,11 +23,12 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.attribute.FileTime;
+import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -123,7 +124,6 @@ public class RClassGeneratorActionTest {
.toArray(new String[0]));
assertThat(Files.exists(jarPath)).isTrue();
- assertThat(Files.getLastModifiedTime(jarPath)).isEqualTo(FileTime.fromMillis(0));
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
List<? extends ZipEntry> zipEntries = Collections.list(zip.entries());
@@ -144,6 +144,7 @@ public class RClassGeneratorActionTest {
"com/google/app/R$string.class",
"com/google/app/R.class",
"META-INF/MANIFEST.MF");
+ ZipMtimeAsserter.assertEntries(zipEntries);
}
}
@@ -175,7 +176,6 @@ public class RClassGeneratorActionTest {
.toArray(new String[0]));
assertThat(Files.exists(jarPath)).isTrue();
- assertThat(Files.getLastModifiedTime(jarPath)).isEqualTo(FileTime.fromMillis(0));
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
List<? extends ZipEntry> zipEntries = Collections.list(zip.entries());
@@ -190,6 +190,7 @@ public class RClassGeneratorActionTest {
"com/google/bar/R$drawable.class",
"com/google/bar/R.class",
"META-INF/MANIFEST.MF");
+ ZipMtimeAsserter.assertEntries(zipEntries);
}
}
@@ -219,7 +220,6 @@ public class RClassGeneratorActionTest {
).toArray(new String[0]));
assertThat(Files.exists(jarPath)).isTrue();
- assertThat(Files.getLastModifiedTime(jarPath)).isEqualTo(FileTime.fromMillis(0));
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
List<? extends ZipEntry> zipEntries = Collections.list(zip.entries());
@@ -233,6 +233,7 @@ public class RClassGeneratorActionTest {
"com/google/app/R$string.class",
"com/google/app/R.class",
"META-INF/MANIFEST.MF");
+ ZipMtimeAsserter.assertEntries(zipEntries);
}
}
@@ -244,12 +245,12 @@ public class RClassGeneratorActionTest {
).toArray(new String[0]));
assertThat(Files.exists(jarPath)).isTrue();
- assertThat(Files.getLastModifiedTime(jarPath)).isEqualTo(FileTime.fromMillis(0));
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
List<? extends ZipEntry> zipEntries = Collections.list(zip.entries());
Iterable<String> entries = getZipFilenames(zipEntries);
assertThat(entries).containsExactly("META-INF/MANIFEST.MF");
+ ZipMtimeAsserter.assertEntries(zipEntries);
}
}
@@ -285,7 +286,6 @@ public class RClassGeneratorActionTest {
.toArray(new String[0]));
assertThat(Files.exists(jarPath)).isTrue();
- assertThat(Files.getLastModifiedTime(jarPath)).isEqualTo(FileTime.fromMillis(0));
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
List<? extends ZipEntry> zipEntries = Collections.list(zip.entries());
@@ -299,6 +299,7 @@ public class RClassGeneratorActionTest {
"com/custom/er/R$string.class",
"com/custom/er/R.class",
"META-INF/MANIFEST.MF");
+ ZipMtimeAsserter.assertEntries(zipEntries);
}
}
@@ -323,12 +324,12 @@ public class RClassGeneratorActionTest {
.toArray(new String[0]));
assertThat(Files.exists(jarPath)).isTrue();
- assertThat(Files.getLastModifiedTime(jarPath)).isEqualTo(FileTime.fromMillis(0));
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
List<? extends ZipEntry> zipEntries = Collections.list(zip.entries());
Iterable<String> entries = getZipFilenames(zipEntries);
assertThat(entries).containsExactly("META-INF/MANIFEST.MF");
+ ZipMtimeAsserter.assertEntries(zipEntries);
}
}
@@ -349,4 +350,36 @@ public class RClassGeneratorActionTest {
}
});
}
+
+ private static final class ZipMtimeAsserter {
+ private static final long ZIP_EPOCH = Instant.parse("1980-01-01T00:00:00Z").getEpochSecond();
+ private static final long ZIP_EPOCH_PLUS_ONE_DAY =
+ Instant.parse("1980-01-02T00:00:00Z").getEpochSecond();
+
+ public static void assertEntry(ZipEntry e) {
+ // getLastModifiedTime().toMillis() returns milliseconds, Instant.getEpochSecond() returns
+ // seconds.
+ long mtime = e.getLastModifiedTime().toMillis() / 1000;
+ // The ZIP epoch is the same as the MS-DOS epoch, 1980-01-01T00:00:00Z.
+ // AndroidResourceOutputs.ZipBuilder sets this to most of its entries, except for .class files
+ // for which the ZipBuilder increments the timestamp by 2 seconds.
+ // We don't care about the details of this logic and asserting exact timestamps would couple
+ // the test to the code too tightly, so here we only assert that the timestamp is on
+ // 1980-01-01, ignoring the exact time.
+ // AndroidResourceOutputs.ZipBuilde sets the ZIP epoch (same as the MS-DOS epoch,
+ // 1980-01-01T00:00:00Z) as the timestamp for all of its entries (except .class files, for
+ // which it sets a timestamp 2 seconds later than the DOS epoch).
+ // We don't care about the exact timestamps though, only that they are stable, so let's just
+ // assert that they are all on the day of 1980-01-01.
+ if (mtime < ZIP_EPOCH || mtime > ZIP_EPOCH_PLUS_ONE_DAY) {
+ Assert.fail(String.format("e=(%s) mtime=(%s)", e.getName(), e.getLastModifiedTime()));
+ }
+ }
+
+ public static void assertEntries(Iterable<? extends ZipEntry> entries) throws Exception {
+ for (ZipEntry e : entries) {
+ assertEntry(e);
+ }
+ }
+ }
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java
index a4e9344c91..b277e010e2 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java
@@ -30,8 +30,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.List;
@@ -56,7 +56,7 @@ public class AndroidResourceOutputs {
// The earliest date representable in a zip file, 1-1-1980 (the DOS epoch).
private static final long ZIP_EPOCH =
- new GregorianCalendar(1980, 01, 01, 0, 0).getTimeInMillis();
+ new GregorianCalendar(1980, Calendar.JANUARY, 01, 0, 0).getTimeInMillis();
private final ZipOutputStream zip;
@@ -299,8 +299,6 @@ public class AndroidResourceOutputs {
try {
Files.createDirectories(manifestOut.getParent());
Files.copy(provider.getManifest(), manifestOut);
- // Set to the epoch for caching purposes.
- Files.setLastModifiedTime(manifestOut, FileTime.fromMillis(0L));
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -332,8 +330,6 @@ public class AndroidResourceOutputs {
// outputs. This state occurs when there are no resource directories.
Files.createFile(rOutput);
}
- // Set to the epoch for caching purposes.
- Files.setLastModifiedTime(rOutput, FileTime.fromMillis(0L));
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -349,8 +345,6 @@ public class AndroidResourceOutputs {
visitor.writeEntries();
visitor.writeManifestContent();
}
- // Set to the epoch for caching purposes.
- Files.setLastModifiedTime(classJar, FileTime.fromMillis(0L));
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -366,8 +360,6 @@ public class AndroidResourceOutputs {
Files.walkFileTree(root, visitor);
visitor.writeEntries();
}
- // Set to the epoch for caching purposes.
- Files.setLastModifiedTime(archive, FileTime.fromMillis(0L));
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -383,8 +375,6 @@ public class AndroidResourceOutputs {
Files.walkFileTree(generatedSourcesRoot, visitor);
visitor.writeEntries();
}
- // Set to the epoch for caching purposes.
- Files.setLastModifiedTime(srcJar, FileTime.fromMillis(0L));
} catch (IOException e) {
throw new RuntimeException(e);
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java
index 2ff8330046..a72d1d243a 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java
@@ -57,7 +57,6 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -343,24 +342,11 @@ public class AndroidResourceProcessor {
dependencyData, customPackageForR, androidManifest, sourceOut);
}
// Reset the output date stamps.
- if (proguardOut != null) {
- Files.setLastModifiedTime(proguardOut, FileTime.fromMillis(0L));
- }
- if (mainDexProguardOut != null) {
- Files.setLastModifiedTime(mainDexProguardOut, FileTime.fromMillis(0L));
- }
if (packageOut != null) {
- Files.setLastModifiedTime(packageOut, FileTime.fromMillis(0L));
if (!splits.isEmpty()) {
- Iterable<Path> splitFilenames = findAndRenameSplitPackages(packageOut, splits);
- for (Path splitFilename : splitFilenames) {
- Files.setLastModifiedTime(splitFilename, FileTime.fromMillis(0L));
- }
+ renameSplitPackages(packageOut, splits);
}
}
- if (publicResourcesOut != null && Files.exists(publicResourcesOut)) {
- Files.setLastModifiedTime(publicResourcesOut, FileTime.fromMillis(0L));
- }
return new MergedAndroidData(resourceDir, assetsDir, androidManifest);
}
@@ -623,8 +609,8 @@ public class AndroidResourceProcessor {
}
}
- /** Finds aapt's split outputs and renames them according to the input flags. */
- private Iterable<Path> findAndRenameSplitPackages(Path packageOut, Iterable<String> splits)
+ /** Renames aapt's split outputs according to the input flags. */
+ private void renameSplitPackages(Path packageOut, Iterable<String> splits)
throws UnrecognizedSplitsException, IOException {
String prefix = packageOut.getFileName().toString() + "_";
// The regex java string literal below is received as [\\{}\[\]*?] by the regex engine,
@@ -641,16 +627,13 @@ public class AndroidResourceProcessor {
}
Map<String, String> outputs =
SplitConfigurationFilter.mapFilenamesToSplitFlags(filenameSuffixes.build(), splits);
- ImmutableList.Builder<Path> outputPaths = new ImmutableList.Builder<>();
for (Map.Entry<String, String> splitMapping : outputs.entrySet()) {
Path resultPath = packageOut.resolveSibling(prefix + splitMapping.getValue());
- outputPaths.add(resultPath);
if (!splitMapping.getKey().equals(splitMapping.getValue())) {
Path sourcePath = packageOut.resolveSibling(prefix + splitMapping.getKey());
Files.move(sourcePath, resultPath);
}
}
- return outputPaths.build();
}
/** A logger that will print messages to a target OutputStream. */
diff --git a/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java b/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java
index a7301f1030..3fb09d2dff 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java
@@ -34,7 +34,6 @@ import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.FileTime;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
@@ -217,9 +216,6 @@ public class ManifestMergerAction {
if (!mergedManifest.equals(options.manifestOutput)) {
Files.copy(options.manifest, options.manifestOutput, StandardCopyOption.REPLACE_EXISTING);
}
-
- // Set to the epoch for caching purposes.
- Files.setLastModifiedTime(options.manifestOutput, FileTime.fromMillis(0L));
} catch (AndroidManifestProcessor.ManifestProcessingException e) {
System.exit(1);
} catch (Exception e) {
diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java b/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java
index eadc42532f..ceb41e6ff2 100644
--- a/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java
+++ b/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java
@@ -138,8 +138,6 @@ class DexBuilder {
executor.shutdown();
}
}
- // Use input's timestamp for output file so the output file is stable.
- Files.setLastModifiedTime(options.outputZip, Files.getLastModifiedTime(options.inputJar));
}
/**
@@ -225,8 +223,6 @@ class DexBuilder {
new Dexing(context, optionsParser.getOptions(DexingOptions.class)),
dexCache);
}
- // Use input's timestamp for output file so the output file is stable.
- Files.setLastModifiedTime(options.outputZip, Files.getLastModifiedTime(options.inputJar));
}
private static ZipOutputStream createZipOutputStream(Path path) throws IOException {