Merge "Enable and demonstrate Java 9 language features in libcore."
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 0f8df96..21645d3 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -127,6 +127,7 @@
 
     java_resource_dirs: core_resource_dirs,
     java_resources: [":android_icu4j_resources"],
+    java_version: "1.9",
 
     required: [
         "tzdata",
@@ -192,6 +193,7 @@
 
     srcs: [":core_libart_java_files"],
     java_resources: [":android_icu4j_resources"],
+    java_version: "1.9",
 
     no_standard_libs: true,
     libs: ["core-all"],
@@ -245,6 +247,7 @@
     dex_preopt: {
         enabled: false,
     },
+    java_version: "1.9",
     notice: "ojluni/NOTICE",
     required: [
         "tzdata",
@@ -497,6 +500,7 @@
 droidstubs {
     name: "core-current-stubs-gen",
     srcs: [":core_api_files"],
+    java_version: "1.9",
     installable: false,
     no_framework_libs: true,
     args: " --exclude-annotations",
diff --git a/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
new file mode 100644
index 0000000..7e201d0
--- /dev/null
+++ b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Proof of concept / dummy code whose only purpose is to demonstrate that Java 9
+ * language features are supported in libcore.
+ */
+public class Java9LanguageFeatures {
+
+    public interface Person {
+        String name();
+
+        default boolean isPalindrome() {
+            return name().equals(reverse(name()));
+        }
+
+        default boolean isPalindromeIgnoreCase() {
+            return name().equalsIgnoreCase(reverse(name()));
+        }
+
+        // Language feature: private interface method
+        private String reverse(String s) {
+            return new StringBuilder(s).reverse().toString();
+        }
+    }
+
+    @SafeVarargs
+    public static<T> String toListString(T... values) {
+        return toString(values).toString();
+    }
+
+    // Language feature: @SafeVarargs on private methods
+    @SafeVarargs
+    private static<T> List<String> toString(T... values) {
+        List<String> result = new ArrayList<>();
+        for (T value : values) {
+            result.add(value.toString());
+        }
+        return result;
+    }
+
+    public <T> AtomicReference<T> createReference(T content) {
+        // Language feature: <> on anonymous class
+        return new AtomicReference<>(content) { };
+    }
+
+    public static byte[] copy(byte[] bytes) throws IOException {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        InputStream inputStream = new ByteArrayInputStream(bytes);
+        try (inputStream) { // Language feature: try on effectively-final variable
+            int value;
+            while ((value = inputStream.read()) != -1) {
+                byteArrayOutputStream.write(value);
+            }
+        }
+        return byteArrayOutputStream.toByteArray();
+    }
+
+
+}
diff --git a/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java b/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java
new file mode 100644
index 0000000..cc48ec0
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.libcore.internal;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
+import libcore.internal.Java9LanguageFeatures;
+
+public class Java9LanguageFeaturesTest extends TestCase {
+
+    public static class SimplePerson implements Java9LanguageFeatures.Person {
+        private final String name;
+        public SimplePerson(String name) { this.name = Objects.requireNonNull(name); }
+        @Override public String toString() { return "Person: " + name; }
+        @Override public String name() { return name; }
+    }
+
+    public void testPrivateInterfaceMethods() {
+        assertFalse(new SimplePerson("Anna").isPalindrome());
+        assertTrue(new SimplePerson("Anna").isPalindromeIgnoreCase());
+        assertTrue(new SimplePerson("anna").isPalindrome());
+        assertTrue(new SimplePerson("bob").isPalindrome());
+        assertFalse(new SimplePerson("larry").isPalindrome());
+        assertFalse(new SimplePerson("larry").isPalindromeIgnoreCase());
+    }
+
+    public void testTryOnEffectivelyFinalVariables() throws IOException {
+        byte[] data = "Hello, world!".getBytes();
+        byte[] dataCopy = Java9LanguageFeatures.copy(data);
+        assertTrue(Arrays.equals(data, dataCopy));
+        assertTrue(data != dataCopy);
+    }
+
+    public void testDiamondOnAnonymousClasses() {
+        AtomicReference<String> ref = new Java9LanguageFeatures().createReference("Hello, world");
+        assertSame("Hello, world", ref.get());
+    }
+
+    public void testSafeVarargsOnPrivateMethod() {
+        assertEquals("[23, and, 42]", Java9LanguageFeatures.toListString(23, "and", 42L));
+    }
+
+}
diff --git a/mmodules/libart_oj/Android.bp b/mmodules/libart_oj/Android.bp
index 950e9b1..e3d7ded 100644
--- a/mmodules/libart_oj/Android.bp
+++ b/mmodules/libart_oj/Android.bp
@@ -38,6 +38,7 @@
     no_standard_libs: true,
     libs: ["core.intra.stubs"],
     system_modules: "core-intra-stubs-system-modules",
+    java_version: "1.9",
     openjdk9: {
         javacflags: ["--patch-module=java.base=."],
     },
diff --git a/mmodules/simple/Android.bp b/mmodules/simple/Android.bp
index 94e8164..ddfed99 100644
--- a/mmodules/simple/Android.bp
+++ b/mmodules/simple/Android.bp
@@ -41,6 +41,7 @@
     name: "core-simple",
     hostdex: true,
     defaults: ["core-simple-defaults"],
+    java_version: "1.9",
 }
 
 // A guaranteed unstripped version of core-simple.
@@ -52,6 +53,7 @@
     dex_preopt: {
         enabled: false,
     },
+    java_version: "1.9",
 }
 
 // A rule that checks we can build core-simple using only the source for
@@ -93,6 +95,7 @@
     no_framework_libs: true,
 
     installable: false,
+    java_version: "1.9",
     args: "--show-annotation libcore.mmodule.IntraCoreMModuleApi",
 }
 
@@ -111,4 +114,5 @@
     openjdk9: {
         javacflags: ["--patch-module=java.base=."],
     },
+    java_version: "1.9",
 }
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 0b5244c..df04980 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -263,6 +263,7 @@
         "luni/src/main/java/libcore/icu/NativeConverter.java",
         "luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java",
         "luni/src/main/java/libcore/icu/TimeZoneNames.java",
+        "luni/src/main/java/libcore/internal/Java9LanguageFeatures.java",
         "luni/src/main/java/libcore/internal/StringPool.java",
         "luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java",
         "luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java",