Fix interface removal in tree pruner
Bug: b/259204069
Change-Id: I2133c3fcb970e6d368c618044dc06bfe5ff31e9e
diff --git a/src/library_desugar/java/java/adapter/AndroidVersionTest.java b/src/library_desugar/java/java/adapter/AndroidVersionTest.java
index 6425791..065761e 100644
--- a/src/library_desugar/java/java/adapter/AndroidVersionTest.java
+++ b/src/library_desugar/java/java/adapter/AndroidVersionTest.java
@@ -6,6 +6,7 @@
public class AndroidVersionTest {
+ public static final boolean is24OrAbove = setUp("java.util.StringJoiner");
public static final boolean is26OrAbove = setUp("java.nio.file.FileSystems");
public static final boolean isHeadfull = setUp("android.os.Build");
diff --git a/src/library_desugar/java/java/nio/channels/DesugarChannels.java b/src/library_desugar/java/java/nio/channels/DesugarChannels.java
index 6380268..4ca851d 100644
--- a/src/library_desugar/java/java/nio/channels/DesugarChannels.java
+++ b/src/library_desugar/java/java/nio/channels/DesugarChannels.java
@@ -39,10 +39,10 @@
if (raw == null) {
return null;
}
- if (raw instanceof SeekableByteChannel) {
+ if (AndroidVersionTest.is24OrAbove) {
return raw;
}
- return new WrappedFileChannel(raw);
+ return WrappedFileChannel.wrap(raw);
}
/**
@@ -63,12 +63,15 @@
final FileChannel delegate;
- private WrappedFileChannel(FileChannel delegate) {
- this.delegate = delegate;
+ public static FileChannel wrap(FileChannel channel) {
+ if (channel instanceof WrappedFileChannel) {
+ return channel;
+ }
+ return new WrappedFileChannel(channel);
}
- FileChannel convert(FileChannel raw) {
- return new WrappedFileChannel(raw);
+ private WrappedFileChannel(FileChannel delegate) {
+ this.delegate = delegate;
}
@Override
@@ -98,7 +101,7 @@
@Override
public FileChannel position(long newPosition) throws IOException {
- return convert(delegate.position(newPosition));
+ return WrappedFileChannel.wrap(delegate.position(newPosition));
}
@Override
@@ -108,7 +111,7 @@
@Override
public FileChannel truncate(long size) throws IOException {
- return convert(delegate.truncate(size));
+ return WrappedFileChannel.wrap(delegate.truncate(size));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/TreePruner.java b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
index 7170817..57726f6 100644
--- a/src/main/java/com/android/tools/r8/shaking/TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
@@ -156,6 +156,11 @@
if (clazz == null) {
return;
}
+ if (clazz.isLibraryClass()) {
+ // TODO(b/259204069): Mitigation of invalid interface removal.
+ // It would be nice to integrate this with the api database.
+ return;
+ }
for (DexType itf : clazz.interfaces) {
if (interfaces.remove(itf) && interfaces.isEmpty()) {
return;
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileChannelTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileChannelTest.java
index c39147d..6c5c149 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileChannelTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileChannelTest.java
@@ -18,8 +18,10 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.OpenOption;
@@ -38,6 +40,10 @@
private static final String EXPECTED_RESULT =
StringUtils.lines(
+ "true",
+ "true",
+ "true",
+ "true",
"Hello World! ",
"Hello World! ",
"Bye bye. ",
@@ -89,11 +95,28 @@
public static class TestClass {
public static void main(String[] args) throws IOException {
+ instanceTest();
fisTest();
fosTest();
fileChannelOpen();
}
+ /**
+ * These check look obvious but they are not on low Api level due to the interface injection.
+ */
+ @SuppressWarnings("all")
+ private static void instanceTest() throws IOException {
+ Path tmp = Files.createTempFile("tmp", ".txt");
+ System.out.println(
+ new FileInputStream(tmp.toFile()).getChannel() instanceof SeekableByteChannel);
+ System.out.println(
+ new FileOutputStream(tmp.toFile()).getChannel() instanceof SeekableByteChannel);
+ System.out.println(
+ new RandomAccessFile(tmp.toFile(), "rw").getChannel() instanceof SeekableByteChannel);
+ System.out.println(
+ Files.newByteChannel(tmp, StandardOpenOption.READ) instanceof SeekableByteChannel);
+ }
+
private static void fosTest() throws IOException {
String toWrite = "The monkey eats...";
Path tmp = Files.createTempFile("fos", ".txt");