Merge "Fix flaky FileInputStreamTest test."
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..72d7fb4
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,3 @@
+nfuller@google.com
+pszczepaniak@google.com
+android-libcore-team+review@google.com
diff --git a/expectations/virtualdeviceknownfailures.txt b/expectations/virtualdeviceknownfailures.txt
index 54d0d64..300bfde 100644
--- a/expectations/virtualdeviceknownfailures.txt
+++ b/expectations/virtualdeviceknownfailures.txt
@@ -12,5 +12,15 @@
description: "Virtual devices do not implement the SELinux policy (forbid hard link) asserted by this test",
name: "libcore.java.nio.file.Files2Test#test_createLink",
bug: 35670953
+},
+{
+ description: "multicast not supported in virtual device testing infra",
+ names: ["org.apache.harmony.tests.java.net.MulticastSocketTest#test_joinGroupLjava_net_InetAddress_IPv4",
+ "org.apache.harmony.tests.java.net.MulticastSocketTest#test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4_nullInterface",
+ "org.apache.harmony.tests.java.net.MulticastSocketTest#test_leaveGroupLjava_net_InetAddress_IPv4",
+ "org.apache.harmony.tests.java.net.MulticastSocketTest#test_sendLjava_net_DatagramPacketB_IPv4",
+ "org.apache.harmony.tests.java.net.MulticastSocketTest#test_setLoopbackModeSendReceive_IPv4"
+ ],
+ bug: 35922755
}
]
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index adad301..20a4a47 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -521,6 +521,9 @@
public static final int TCP_NODELAY = placeholder();
public static final int TCP_USER_TIMEOUT = placeholder();
/** @hide */ public static final int TIOCOUTQ = placeholder();
+ /** @hide */ public static final int UDP_ENCAP = placeholder();
+ /** @hide */ public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
+ /** @hide */ public static final int UDP_ENCAP_ESPINUDP = placeholder();
/** @hide */ public static final int UNIX_PATH_MAX = placeholder();
public static final int WCONTINUED = placeholder();
public static final int WEXITED = placeholder();
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 3ae4af6..a517475 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -47,6 +47,9 @@
#include <linux/if_addr.h>
#include <linux/rtnetlink.h>
+// Include linux socket constants for setting sockopts
+#include <linux/udp.h>
+
#include <net/if.h> // After <sys/socket.h> to work around a Mac header file bug.
#if defined(__BIONIC__)
@@ -577,6 +580,9 @@
initConstant(env, c, "TCP_USER_TIMEOUT", TCP_USER_TIMEOUT);
#endif
initConstant(env, c, "TIOCOUTQ", TIOCOUTQ);
+ initConstant(env, c, "UDP_ENCAP", UDP_ENCAP);
+ initConstant(env, c, "UDP_ENCAP_ESPINUDP_NON_IKE", UDP_ENCAP_ESPINUDP_NON_IKE);
+ initConstant(env, c, "UDP_ENCAP_ESPINUDP", UDP_ENCAP_ESPINUDP);
// UNIX_PATH_MAX is mentioned in some versions of unix(7), but not actually declared.
initConstant(env, c, "UNIX_PATH_MAX", sizeof(sockaddr_un::sun_path));
initConstant(env, c, "WCONTINUED", WCONTINUED);
diff --git a/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java b/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java
index d32fa20..0161c6a 100644
--- a/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java
+++ b/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java
@@ -27,6 +27,7 @@
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -35,18 +36,22 @@
public class LambdaImplementationTest extends TestCase {
- private static final String MSG = "Hello World";
+ private static final String STATIC_METHOD_RESPONSE = "StaticMethodResponse";
public void testNonCapturingLambda() throws Exception {
- Callable<String> r1 = () -> MSG;
+ Callable<String> r1 = () -> "Hello World";
assertGeneralLambdaClassCharacteristics(r1);
assertLambdaImplementsInterfaces(r1, Callable.class);
assertLambdaMethodCharacteristics(r1, Callable.class);
assertNonSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG);
+ assertCallableBehavior(r1, "Hello World");
- Callable<String> r2 = () -> MSG;
- assertMultipleInstanceCharacteristics(r1, r2);
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ callables.add(() -> "Hello World");
+ }
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
interface Condition<T> {
@@ -83,65 +88,96 @@
assertLambdaMethodCharacteristics(r1, Callable.class);
assertNonSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG);
+ assertCallableBehavior(r1, STATIC_METHOD_RESPONSE);
- Callable<String> r2 = LambdaImplementationTest::staticMethod;
- assertMultipleInstanceCharacteristics(r1, r2);
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ callables.add(LambdaImplementationTest::staticMethod);
+ }
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
public void testObjectMethodReferenceLambda() throws Exception {
- StringBuilder o = new StringBuilder(MSG);
+ String msg = "Hello";
+ StringBuilder o = new StringBuilder(msg);
Callable<String> r1 = o::toString;
assertGeneralLambdaClassCharacteristics(r1);
assertLambdaImplementsInterfaces(r1, Callable.class);
assertLambdaMethodCharacteristics(r1, Callable.class);
assertNonSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG);
+ assertCallableBehavior(r1, msg);
- Callable<String> r2 = o::toString;
- assertMultipleInstanceCharacteristics(r1, r2);
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ callables.add(o::toString);
+ }
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
public void testArgumentCapturingLambda() throws Exception {
- String msg = MSG;
+ checkArgumentCapturingLambda("Argument");
+ }
+
+ private void checkArgumentCapturingLambda(String msg) throws Exception {
Callable<String> r1 = () -> msg;
assertGeneralLambdaClassCharacteristics(r1);
assertLambdaImplementsInterfaces(r1, Callable.class);
assertLambdaMethodCharacteristics(r1, Callable.class);
assertNonSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG);
+ assertCallableBehavior(r1, msg);
- Callable<String> r2 = () -> msg;
- assertMultipleInstanceCharacteristics(r1, r2);
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ callables.add(() -> msg);
+ }
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
public void testSerializableLambda_withoutState() throws Exception {
- Callable<String> r1 = (Callable<String> & Serializable) () -> MSG;
+ Callable<String> r1 = (Callable<String> & Serializable) () -> "No State";
assertGeneralLambdaClassCharacteristics(r1);
assertLambdaImplementsInterfaces(r1, Callable.class, Serializable.class);
assertLambdaMethodCharacteristics(r1, Callable.class);
assertSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG);
+ assertCallableBehavior(r1, "No State");
- Callable<String> r2 = (Callable<String> & Serializable) () -> MSG;
- assertMultipleInstanceCharacteristics(r1, r2);
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ Callable<String> callable = (Callable<String> & Serializable) () -> "No State";
+ assertLambdaImplementsInterfaces(callable, Callable.class, Serializable.class);
+ callables.add(callable);
+ }
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
public void testSerializableLambda_withState() throws Exception {
- final int state = 123;
- Callable<String> r1 = (Callable<String> & Serializable) () -> MSG + state;
+ final long state = System.currentTimeMillis();
+ Callable<String> r1 = (Callable<String> & Serializable) () -> "State:" + state;
assertGeneralLambdaClassCharacteristics(r1);
assertLambdaImplementsInterfaces(r1, Callable.class, Serializable.class);
assertLambdaMethodCharacteristics(r1, Callable.class);
assertSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG + state);
+ assertCallableBehavior(r1, "State:" + state);
Callable<String> deserializedR1 = roundtripSerialization(r1);
assertEquals(r1.call(), deserializedR1.call());
+
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ Callable<String> callable = (Callable<String> & Serializable) () -> "State:" + state;
+ assertLambdaImplementsInterfaces(callable, Callable.class, Serializable.class);
+ callables.add(callable);
+ }
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
public void testBadSerializableLambda() throws Exception {
@@ -159,14 +195,25 @@
}
public void testMultipleInterfaceLambda() throws Exception {
- Callable<String> r1 = (Callable<String> & MarkerInterface) () -> MSG;
+ Callable<String> r1 = (Callable<String> & MarkerInterface) () -> "MultipleInterfaces";
assertTrue(r1 instanceof MarkerInterface);
assertGeneralLambdaClassCharacteristics(r1);
assertLambdaMethodCharacteristics(r1, Callable.class);
assertLambdaImplementsInterfaces(r1, Callable.class, MarkerInterface.class);
assertNonSerializableLambdaCharacteristics(r1);
- assertCallableBehavior(r1, MSG);
+ assertCallableBehavior(r1, "MultipleInterfaces");
+
+ List<Callable<String>> callables = new ArrayList<>();
+ for (int i = 0; i < 2; i++) {
+ Callable<String> callable =
+ (Callable<String> & MarkerInterface) () -> "MultipleInterfaces";
+ assertLambdaImplementsInterfaces(callable, Callable.class, MarkerInterface.class);
+ callables.add(callable);
+ }
+ assertLambdaImplementsInterfaces(r1, Callable.class, MarkerInterface.class);
+ assertMultipleDefinitionCharacteristics(r1, callables.get(0));
+ assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
}
private static void assertSerializableLambdaCharacteristics(Object r1) throws Exception {
@@ -248,8 +295,15 @@
}
}
- private static void assertMultipleInstanceCharacteristics(Object r1, Object r2)
- throws Exception {
+ /**
+ * Asserts that necessary conditions hold when there are two lambdas with separate but identical
+ * definitions.
+ */
+ private static void assertMultipleDefinitionCharacteristics(
+ Callable<String> r1, Callable<String> r2) throws Exception {
+
+ // Sanity check that the lambdas do the same thing.
+ assertEquals(r1.call(), r2.call());
// Unclear if any of this is *guaranteed* to be true.
@@ -258,10 +312,23 @@
assertNotSame(r1, r2);
assertTrue(!r1.equals(r2));
- // Confirm the classes differ.
- Class<?> lambda1Class = r1.getClass();
- Class<?> lambda2Class = r2.getClass();
- assertNotSame(lambda1Class, lambda2Class);
+ // Two lambdas from different definitions can share the same class or may not.
+ // See JLS 15.27.4.
+ }
+
+ /**
+ * Asserts that necessary conditions hold when there are two lambdas created from the same
+ * definition.
+ */
+ private static void assertMultipleInstanceCharacteristics(
+ Callable<String> r1, Callable<String> r2) throws Exception {
+
+ // Sanity check that the lambdas do the same thing.
+ assertEquals(r1.call(), r2.call());
+
+ // There doesn't appear to be anything else that is safe to assert here. Two lambdas
+ // created from the same definition can be the same, as can their class, but they can also
+ // be different. See JLS 15.27.4.
}
private static void assertGeneralLambdaClassCharacteristics(Object r1) throws Exception {
@@ -333,7 +400,7 @@
}
private static String staticMethod() {
- return MSG;
+ return STATIC_METHOD_RESPONSE;
}
private interface MarkerInterface {
diff --git a/ojluni/src/main/java/java/io/Console.java b/ojluni/src/main/java/java/io/Console.java
index 2b4e4e6..b25759c 100644
--- a/ojluni/src/main/java/java/io/Console.java
+++ b/ojluni/src/main/java/java/io/Console.java
@@ -514,11 +514,10 @@
}
}
- // Android-changed: Remove SharedSecrets setup and also the shutdown
- // hook that's a no-op (but causes trouble when it's turned on).
+ // Android-removed: SharedSecrets setup and also the shutdown hook.
+ // The hook is a no-op (but causes trouble when it's turned on).
- private static Console cons;
-
+ // Android-changed: Use @hide rather than sun.misc.SharedSecrets to expose console().
/** @hide */
public static Console console() {
if (istty()) {
@@ -528,15 +527,16 @@
}
return null;
}
-
+ private static Console cons;
private native static boolean istty();
-
private Console() {
+ // BEGIN Android-changed: Support custom in/out streams for testing.
this(new FileInputStream(FileDescriptor.in), new FileOutputStream(FileDescriptor.out));
}
// Constructor for tests
private Console(InputStream inStream, OutputStream outStream) {
+ // END Android-changed: Support custom in/out streams for testing.
readLock = new Object();
writeLock = new Object();
String csname = encoding();
diff --git a/ojluni/src/main/java/java/io/DeleteOnExitHook.java b/ojluni/src/main/java/java/io/DeleteOnExitHook.java
index 447f038..e988f9b 100644
--- a/ojluni/src/main/java/java/io/DeleteOnExitHook.java
+++ b/ojluni/src/main/java/java/io/DeleteOnExitHook.java
@@ -36,11 +36,13 @@
class DeleteOnExitHook {
private static LinkedHashSet<String> files = new LinkedHashSet<>();
static {
+ // BEGIN Android-changed: Use Runtime.addShutdownHook() rather than SharedSecrets.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
runHooks();
}
});
+ // END Android-changed: Use Runtime.addShutdownHook() rather than SharedSecrets.
}
private DeleteOnExitHook() {}
diff --git a/ojluni/src/main/java/java/io/InterruptedIOException.java b/ojluni/src/main/java/java/io/InterruptedIOException.java
index e4ed419..25569dd 100644
--- a/ojluni/src/main/java/java/io/InterruptedIOException.java
+++ b/ojluni/src/main/java/java/io/InterruptedIOException.java
@@ -74,7 +74,7 @@
public int bytesTransferred = 0;
/** @hide */
- // Android-added.
+ // Android-added: Additional constructor for internal use.
public InterruptedIOException(Throwable cause) {
super(cause);
}
@@ -84,7 +84,7 @@
*
* @hide internal use only
*/
- // Android-added.
+ // Android-added: Additional constructor for internal use.
public InterruptedIOException(String detailMessage, Throwable cause) {
super(detailMessage, cause);
}
diff --git a/ojluni/src/main/java/java/io/Serializable.java b/ojluni/src/main/java/java/io/Serializable.java
index 96ea33c..496aef7 100644
--- a/ojluni/src/main/java/java/io/Serializable.java
+++ b/ojluni/src/main/java/java/io/Serializable.java
@@ -25,6 +25,7 @@
package java.io;
+// Android-added: Notes about serialVersionUID, using serialization judiciously, JSON.
/**
* Serializability of a class is enabled by the class implementing the
* java.io.Serializable interface. Classes that do not implement this
diff --git a/ojluni/src/main/java/java/io/SerializablePermission.java b/ojluni/src/main/java/java/io/SerializablePermission.java
index e11f3ee..93bb4aa 100644
--- a/ojluni/src/main/java/java/io/SerializablePermission.java
+++ b/ojluni/src/main/java/java/io/SerializablePermission.java
@@ -27,8 +27,9 @@
import java.security.*;
+// Android-changed: Replaced with empty implementation and documented as legacy security code.
/**
- * Legacy security code; do not use.
+ * This legacy security is not supported on Android. Do not use.
*/
public final class SerializablePermission extends BasicPermission {
diff --git a/ojluni/src/main/java/java/lang/AbstractStringBuilder.java b/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
index c67a0a4..cc24e96 100644
--- a/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -153,7 +153,7 @@
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
- ? hugeCapacity(minCapacity)
+ ? hugeCapacity(minCapacity)
: newCapacity;
}
diff --git a/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java b/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
index 756c684..9c85456 100644
--- a/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
+++ b/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
@@ -66,16 +66,16 @@
super(s);
}
+ // Android-added: Additional constructor for internal use.
/**
- * Used internally for consistent high-quality error reporting.
* @hide
*/
public ArrayIndexOutOfBoundsException(int sourceLength, int index) {
super("length=" + sourceLength + "; index=" + index);
}
+ // Android-added: Additional constructor for internal use.
/**
- * Used internally for consistent high-quality error reporting.
* @hide
*/
public ArrayIndexOutOfBoundsException(int sourceLength, int offset,
diff --git a/ojluni/src/main/java/java/lang/Byte.java b/ojluni/src/main/java/java/lang/Byte.java
index ba2f588..d0031d0 100644
--- a/ojluni/src/main/java/java/lang/Byte.java
+++ b/ojluni/src/main/java/java/lang/Byte.java
@@ -518,7 +518,7 @@
/** use serialVersionUID from JDK 1.1. for interoperability */
private static final long serialVersionUID = -7183698231559129828L;
- // BEGIN Android-changed
+ // BEGIN Android-added: toHexString() for internal use.
/**
* @hide
*/
@@ -542,5 +542,5 @@
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
- // END Android-changed
+ // END Android-added: toHexString() for internal use.
}
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index a6301b5..0419ede 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -1081,7 +1081,9 @@
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
- throw new IllegalArgumentException();
+ // Android-changed: Improve exception message when the new priority
+ // is out of bounds.
+ throw new IllegalArgumentException("Priority out of range: " + newPriority);
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
diff --git a/ojluni/src/main/java/java/net/SocketTimeoutException.java b/ojluni/src/main/java/java/net/SocketTimeoutException.java
index 3b5b50a..2c61415 100644
--- a/ojluni/src/main/java/java/net/SocketTimeoutException.java
+++ b/ojluni/src/main/java/java/net/SocketTimeoutException.java
@@ -50,11 +50,13 @@
public SocketTimeoutException() {}
/** @hide */
+ // Android-added: Additional constructor for internal use.
public SocketTimeoutException(Throwable cause) {
super(cause);
}
/** @hide */
+ // Android-added: Additional constructor for internal use.
public SocketTimeoutException(String msg, Throwable cause) {
super(msg, cause);
}
diff --git a/ojluni/src/main/java/java/time/chrono/HijrahChronology.java b/ojluni/src/main/java/java/time/chrono/HijrahChronology.java
index 98b79c4..e7b3554 100644
--- a/ojluni/src/main/java/java/time/chrono/HijrahChronology.java
+++ b/ojluni/src/main/java/java/time/chrono/HijrahChronology.java
@@ -544,7 +544,7 @@
//-----------------------------------------------------------------------
@Override
public boolean isLeapYear(long prolepticYear) {
- checkCalendarInit();
+ checkCalendarInit();
if (prolepticYear < getMinimumYear() || prolepticYear > getMaximumYear()) {
return false;
}