[automerger skipped] Merge "Fix nit in LocaleDataTest#testInvalidLocale and StringTest#testFormat_invalidLocale" into qt-dev
am: de64a196b5 -s ours
am skip reason: change_id If2d1c88705ab6a8e3cc855f6a957ffc33641dc84 with SHA1 4545804aad is in history
Change-Id: I8b280bce7551e08d9b261deaa675360f0c46ca7c
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 2066c42..53d0a10 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -702,3 +702,14 @@
name: "timezone-host",
srcs: [":timezone_host_files"],
}
+
+// The source files that contain the UnsupportedAppUsage annotation and its dependencies.
+filegroup {
+ name: "unsupportedappusage_annotation_files",
+ srcs: [
+ "dalvik/src/main/java/dalvik/annotation/compat/UnsupportedAppUsage.java",
+ "dalvik/src/main/java/dalvik/system/VersionCodes.java",
+ "luni/src/main/java/libcore/api/CorePlatformApi.java",
+ "luni/src/main/java/libcore/api/IntraCoreApi.java",
+ ],
+}
\ No newline at end of file
diff --git a/expectations/Android.bp b/expectations/Android.bp
new file mode 100644
index 0000000..bf4a993
--- /dev/null
+++ b/expectations/Android.bp
@@ -0,0 +1,9 @@
+filegroup {
+ name: "libcore-expectations-knownfailures",
+ srcs: ["knownfailures.txt"],
+}
+
+filegroup {
+ name: "libcore-expectations-virtualdeviceknownfailures",
+ srcs: ["virtualdeviceknownfailures.txt"],
+}
diff --git a/luni/src/main/java/android/system/ErrnoException.java b/luni/src/main/java/android/system/ErrnoException.java
index 02a529f..a5edf47 100644
--- a/luni/src/main/java/android/system/ErrnoException.java
+++ b/luni/src/main/java/android/system/ErrnoException.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.net.SocketException;
import libcore.io.Libcore;
+import libcore.util.NonNull;
/**
* A checked exception thrown when {@link Os} methods fail. This exception contains the native
@@ -65,21 +66,26 @@
}
/**
- * @hide - internal use only.
+ * Throws an {@link IOException} with a message based on {@link #getMessage()} and with this
+ * instance as the cause.
+ *
+ * <p>This method always terminates by throwing the exception. Callers can write
+ * {@code throw e.rethrowAsIOException()} to make that clear to the compiler.
*/
- @libcore.api.CorePlatformApi
- public IOException rethrowAsIOException() throws IOException {
+ public @NonNull IOException rethrowAsIOException() throws IOException {
IOException newException = new IOException(getMessage());
newException.initCause(this);
throw newException;
}
/**
- * @hide - internal use only.
+ * Throws a {@link SocketException} with a message based on {@link #getMessage()} and with this
+ * instance as the cause.
+ *
+ * <p>This method always terminates by throwing the exception. Callers can write
+ * {@code throw e.rethrowAsIOException()} to make that clear to the compiler.
*/
- @libcore.api.CorePlatformApi
- @libcore.api.IntraCoreApi
- public SocketException rethrowAsSocketException() throws SocketException {
+ public @NonNull SocketException rethrowAsSocketException() throws SocketException {
throw new SocketException(getMessage(), this);
}
}
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index d56e182..bd95a93 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -121,14 +121,29 @@
return linger.isOn() && linger.l_linger > 0;
}
- @Override public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException {
- BlockGuard.getThreadPolicy().onNetwork();
+ private static boolean isUdpSocket(FileDescriptor fd) throws ErrnoException {
+ return Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) == IPPROTO_UDP;
+ }
+
+ @Override public void connect(FileDescriptor fd, InetAddress address, int port)
+ throws ErrnoException, SocketException {
+ boolean skipGuard = false;
+ try {
+ skipGuard = isUdpSocket(fd);
+ } catch (ErrnoException ignored) {
+ }
+ if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork();
super.connect(fd, address, port);
}
@Override public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException,
SocketException {
- BlockGuard.getThreadPolicy().onNetwork();
+ boolean skipGuard = false;
+ try {
+ skipGuard = isUdpSocket(fd);
+ } catch (ErrnoException ignored) {
+ }
+ if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork();
super.connect(fd, address);
}
diff --git a/luni/src/main/java/libcore/net/android.mime.types b/luni/src/main/java/libcore/net/android.mime.types
index dd3b21a..dff930a 100644
--- a/luni/src/main/java/libcore/net/android.mime.types
+++ b/luni/src/main/java/libcore/net/android.mime.types
@@ -69,6 +69,7 @@
video/m4v m4v
video/mp2p mpeg
video/mp2ts ts
+video/MP2T m2ts MTS
video/x-webex wrf
# Special cases where Android has a strong opinion about mappings, so we
diff --git a/luni/src/main/java/libcore/util/HexEncoding.java b/luni/src/main/java/libcore/util/HexEncoding.java
index eceec6b..6d00074 100644
--- a/luni/src/main/java/libcore/util/HexEncoding.java
+++ b/luni/src/main/java/libcore/util/HexEncoding.java
@@ -23,17 +23,43 @@
@libcore.api.CorePlatformApi
public class HexEncoding {
+ private static final char[] LOWER_CASE_DIGITS = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+
+ private static final char[] UPPER_CASE_DIGITS = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
/** Hidden constructor to prevent instantiation. */
private HexEncoding() {}
- private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+ /**
+ * Encodes the provided byte as a two-digit hexadecimal String value.
+ */
+ @libcore.api.CorePlatformApi
+ public static String encodeToString(byte b, boolean upperCase) {
+ char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
+ char[] buf = new char[2]; // We always want two digits.
+ buf[0] = digits[(b >> 4) & 0xf];
+ buf[1] = digits[b & 0xf];
+ return new String(buf, 0, 2);
+ }
/**
* Encodes the provided data as a sequence of hexadecimal characters.
*/
@libcore.api.CorePlatformApi
public static char[] encode(byte[] data) {
- return encode(data, 0, data.length);
+ return encode(data, 0, data.length, true /* upperCase */);
+ }
+
+ /**
+ * Encodes the provided data as a sequence of hexadecimal characters.
+ */
+ @libcore.api.CorePlatformApi
+ public static char[] encode(byte[] data, boolean upperCase) {
+ return encode(data, 0, data.length, upperCase);
}
/**
@@ -41,12 +67,20 @@
*/
@libcore.api.CorePlatformApi
public static char[] encode(byte[] data, int offset, int len) {
+ return encode(data, offset, len, true /* upperCase */);
+ }
+
+ /**
+ * Encodes the provided data as a sequence of hexadecimal characters.
+ */
+ private static char[] encode(byte[] data, int offset, int len, boolean upperCase) {
+ char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
char[] result = new char[len * 2];
for (int i = 0; i < len; i++) {
byte b = data[offset + i];
int resultIndex = 2 * i;
- result[resultIndex] = (HEX_DIGITS[(b >>> 4) & 0x0f]);
- result[resultIndex + 1] = (HEX_DIGITS[b & 0x0f]);
+ result[resultIndex] = (digits[(b >> 4) & 0x0f]);
+ result[resultIndex + 1] = (digits[b & 0x0f]);
}
return result;
@@ -57,7 +91,15 @@
*/
@libcore.api.CorePlatformApi
public static String encodeToString(byte[] data) {
- return new String(encode(data));
+ return encodeToString(data, true /* upperCase */);
+ }
+
+ /**
+ * Encodes the provided data as a sequence of hexadecimal characters.
+ */
+ @libcore.api.CorePlatformApi
+ public static String encodeToString(byte[] data, boolean upperCase) {
+ return new String(encode(data, upperCase));
}
/**
@@ -78,7 +120,9 @@
*
* Throws an {@code IllegalArgumentException} if the input is malformed.
*/
- public static byte[] decode(String encoded, boolean allowSingleChar) throws IllegalArgumentException {
+ @libcore.api.CorePlatformApi
+ public static byte[] decode(String encoded, boolean allowSingleChar)
+ throws IllegalArgumentException {
return decode(encoded.toCharArray(), allowSingleChar);
}
@@ -101,25 +145,28 @@
* Throws an {@code IllegalArgumentException} if the input is malformed.
*/
@libcore.api.CorePlatformApi
- public static byte[] decode(char[] encoded, boolean allowSingleChar) throws IllegalArgumentException {
- int resultLengthBytes = (encoded.length + 1) / 2;
+ public static byte[] decode(char[] encoded, boolean allowSingleChar)
+ throws IllegalArgumentException {
+ int encodedLength = encoded.length;
+ int resultLengthBytes = (encodedLength + 1) / 2;
byte[] result = new byte[resultLengthBytes];
int resultOffset = 0;
int i = 0;
if (allowSingleChar) {
- if ((encoded.length % 2) != 0) {
- // Odd number of digits -- the first digit is the lower 4 bits of the first result byte.
+ if ((encodedLength % 2) != 0) {
+ // Odd number of digits -- the first digit is the lower 4 bits of the first result
+ // byte.
result[resultOffset++] = (byte) toDigit(encoded, i);
i++;
}
} else {
- if ((encoded.length % 2) != 0) {
- throw new IllegalArgumentException("Invalid input length: " + encoded.length);
+ if ((encodedLength % 2) != 0) {
+ throw new IllegalArgumentException("Invalid input length: " + encodedLength);
}
}
- for (int len = encoded.length; i < len; i += 2) {
+ for (; i < encodedLength; i += 2) {
result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1));
}
@@ -139,7 +186,6 @@
return 10 + (pseudoCodePoint - 'A');
}
- throw new IllegalArgumentException("Illegal char: " + str[offset] +
- " at offset " + offset);
+ throw new IllegalArgumentException("Illegal char: " + str[offset] + " at offset " + offset);
}
}
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
index 7536885..dd5e698 100644
--- a/luni/src/test/java/libcore/android/system/OsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -56,6 +56,7 @@
import junit.framework.TestCase;
import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
import static android.system.OsConstants.*;
@@ -81,7 +82,7 @@
int flags = Os.fcntlVoid(fis.getFD(), F_GETFD);
assertTrue((flags & FD_CLOEXEC) != 0);
} finally {
- IoUtils.closeQuietly(fis);
+ TestIoUtils.closeQuietly(fis);
f.delete();
}
}
@@ -1133,7 +1134,7 @@
}
public void test_readlink() throws Exception {
- File path = new File(IoUtils.createTemporaryDirectory("test_readlink"), "symlink");
+ File path = new File(TestIoUtils.createTemporaryDirectory("test_readlink"), "symlink");
// ext2 and ext4 have PAGE_SIZE limits on symlink targets.
// If file encryption is enabled, there's extra overhead to store the
@@ -1251,7 +1252,7 @@
android.system.Os.sendfile(outFd, inFd, offset, maxBytes);
assertEquals(expectedEndOffset, offset == null ? null : offset.value);
}
- return IoUtils.readFileAsString(out.getPath());
+ return TestIoUtils.readFileAsString(out.getPath());
} finally {
out.delete();
}
@@ -1307,7 +1308,7 @@
assertEquals(5, offOut.value);
}
- assertEquals("oobar", IoUtils.readFileAsString(out.getPath()));
+ assertEquals("oobar", TestIoUtils.readFileAsString(out.getPath()));
Os.close(pipe[0]);
Os.close(pipe[1]);
diff --git a/luni/src/test/java/libcore/java/net/AuditInputStream.java b/luni/src/test/java/libcore/java/net/AuditInputStream.java
new file mode 100644
index 0000000..2a76cac
--- /dev/null
+++ b/luni/src/test/java/libcore/java/net/AuditInputStream.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.java.net;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
+
+/**
+ * An {@link InputStream} that reads from a delegate and also writes an audit log of all data
+ * that was read to the given {@code audit} {@link OutputStream}.
+ */
+class AuditInputStream extends FilterInputStream {
+ private final OutputStream audit;
+
+ protected AuditInputStream(InputStream in, OutputStream audit) {
+ super(in);
+ this.audit = Objects.requireNonNull(audit);
+ }
+
+ @Override
+ public int read() throws IOException {
+ int result = super.read();
+ audit.write(result);
+ return result;
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ int result = super.read(b);
+ if (result > 0) {
+ audit.write(b, 0, result);
+ }
+ return result;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ int result = super.read(b, off, len);
+ if (result > 0) {
+ audit.write(b, off, result);
+ }
+ return result;
+ }
+}
diff --git a/luni/src/test/java/libcore/java/net/InetAddressTest.java b/luni/src/test/java/libcore/java/net/InetAddressTest.java
index 307cd1d..88f03d4 100644
--- a/luni/src/test/java/libcore/java/net/InetAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetAddressTest.java
@@ -36,6 +36,7 @@
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import libcore.libcore.util.SerializationTester;
+import libcore.net.InetAddressUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -312,8 +313,12 @@
public void test_getByName_invalid(String invalid) throws Exception {
try {
InetAddress.getByName(invalid);
- fail("Invalid IP address incorrectly recognized as valid: "
- + invalid);
+ String msg = "Invalid IP address incorrectly recognized as valid: \"" + invalid + "\"";
+ if (InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(invalid) == null) {
+ msg += " (it was probably unexpectedly resolved by this network's DNS)";
+ }
+ msg += ".";
+ fail(msg);
} catch (UnknownHostException expected) {
}
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 1574caf..c29ba09 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -19,6 +19,7 @@
import com.google.mockwebserver.Dispatcher;
import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.QueueDispatcher;
import com.google.mockwebserver.RecordedRequest;
import com.google.mockwebserver.SocketPolicy;
@@ -57,6 +58,7 @@
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.nio.channels.SocketChannel;
+import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -88,6 +90,7 @@
import javax.net.ssl.X509TrustManager;
import libcore.java.security.TestKeyStore;
import libcore.javax.net.ssl.TestSSLContext;
+import libcore.testing.io.TestIoUtils;
import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_END;
import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
@@ -342,7 +345,7 @@
server.enqueue(new MockResponse().setResponseCode(404).setBody("A"));
server.play();
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("A", readAscii(connection.getErrorStream(), Integer.MAX_VALUE));
+ assertEquals("A", readAscii(connection.getErrorStream()));
}
// Check that if we don't read to the end of a response, the next request on the
@@ -408,10 +411,10 @@
server.play();
URLConnection connection1 = server.getUrl("/").openConnection();
- assertEquals("ABC", readAscii(connection1.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("ABC", readAscii(connection1.getInputStream()));
assertEquals(0, server.takeRequest().getSequenceNumber());
URLConnection connection2 = server.getUrl("/").openConnection();
- assertEquals("DEF", readAscii(connection2.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("DEF", readAscii(connection2.getInputStream()));
assertEquals(1, server.takeRequest().getSequenceNumber());
}
@@ -593,7 +596,7 @@
connection = (HttpsURLConnection) server.getUrl("/").openConnection();
try {
- readAscii(connection.getInputStream(), Integer.MAX_VALUE);
+ readAscii(connection.getInputStream());
fail("without an SSL socket factory, the connection should fail");
} catch (SSLException expected) {
}
@@ -1127,6 +1130,105 @@
}
}
+ public void testDisconnectFromBackgroundThread_blockedRead_beforeHeader()
+ throws IOException {
+ QueueDispatcher dispatcher = new QueueDispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
+ Thread.sleep(6000);
+ return super.dispatch(request);
+ }
+ };
+ server.setDispatcher(dispatcher);
+ server.enqueue(new MockResponse().setHeader("Key", "Value").setBody("Response body"));
+ checkDisconnectFromBackgroundThread_blockedRead(2000, null /* disconnectMillis */);
+ }
+
+ public void testDisconnectFromBackgroundThread_blockedRead_beforeBody()
+ throws IOException {
+ server.enqueue(new MockResponse().setHeader("Key", "Value")
+ .setBody("Response body").setBodyDelayTimeMs(6000));
+ checkDisconnectFromBackgroundThread_blockedRead(2000, "" /* disconnectMillis */);
+ }
+
+ /**
+ *
+ * @throws IOException
+ */
+ public void testDisconnectFromBackgroundThread_blockedRead_duringBody()
+ throws IOException {
+ server.enqueue(new MockResponse().setHeader("Key", "Value")
+ .setBody("Response body").throttleBody(3, 1333, TimeUnit.MILLISECONDS));
+ // After 2 sec, we should have read about 6 bytes (we sleep 1333msec after every 3 bytes).
+ checkDisconnectFromBackgroundThread_blockedRead(2000, "Respon");
+ }
+
+ /**
+ * Checks that {@link HttpURLConnection#disconnect() disconnecting} a blocked read
+ * from a background thread unblocks the reading thread quickly and that the headers/body
+ * read so far are as given.
+ *
+ * The disconnect happens after approximately {@code disconnectMillis} msec (between half
+ * and double that is tolerated), so the server must already be set up such that reading
+ * the headers and the entire request takes comfortably more than that, eg.
+ * {@code 3 * disconnectMillis}.
+ *
+ * @param disconnectMillis number of milliseconds until the connection should be
+ * {@link HttpURLConnection#disconnect() disconnected} by a background thread.
+ * @param expectedResponseContent The part of the body that is expected to have been read by
+ * the time the connection is disconnected, or null if not even the headers
+ * are expected to have been read at the time.
+ * @throws IOException if one occurs unexpectedly while establishing the connection.
+ */
+ private void checkDisconnectFromBackgroundThread_blockedRead(
+ long disconnectMillis, String expectedResponseContent) throws IOException {
+ server.play();
+ HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
+
+ Thread disconnectThread = new Thread("Disconnect after " + disconnectMillis + "msec") {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(disconnectMillis);
+ } catch (InterruptedException e) {
+ // Even if an AssertionFailedError on this background thread doesn't
+ // cause the test to fail directly, we'd still prematurely disconnect()
+ // and that would (if significant) be detected further down by the
+ // assertion on the number of elapsed milliseconds observed by the
+ // main thread.
+ fail("Unexpectedly interrupted: " + e);
+ }
+ connection.disconnect();
+ }
+ };
+
+ ByteArrayOutputStream auditStream = new ByteArrayOutputStream();
+ AuditInputStream inputStream = null;
+ boolean headerRead = false;
+ long start = System.currentTimeMillis();
+ disconnectThread.start();
+ try {
+ inputStream = new AuditInputStream(connection.getInputStream(), auditStream);
+ connection.getHeaderFields();
+ headerRead = true;
+ readAscii(inputStream);
+ fail("Didn't expect to successfully read all of the data");
+ } catch (IOException expected) {
+ } finally {
+ TestIoUtils.closeQuietly(inputStream);
+ }
+ long elapsed = System.currentTimeMillis() - start;
+
+ assertTrue("Expected approx. " + disconnectMillis + " msec elapsed, got " + elapsed,
+ disconnectMillis / 2 <= elapsed && elapsed <= 2 * disconnectMillis);
+ String readBody = new String(auditStream.toByteArray(), StandardCharsets.UTF_8);
+
+ String actualResponse = headerRead ? readBody : null;
+ assertEquals("Headers read: " + headerRead + "; read response body: " + readBody,
+ expectedResponseContent, actualResponse);
+ }
+
+
// http://b/33763156
public void testDisconnectDuringConnect_getInputStream() throws IOException {
checkDisconnectDuringConnect(HttpURLConnection::getInputStream);
@@ -1223,7 +1325,7 @@
* exhausted before {@code count} characters can be read, the remaining
* characters are returned and the stream is closed.
*/
- private String readAscii(InputStream in, int count) throws IOException {
+ private static String readAscii(InputStream in, int count) throws IOException {
StringBuilder result = new StringBuilder();
for (int i = 0; i < count; i++) {
int value = in.read();
@@ -1236,6 +1338,10 @@
return result.toString();
}
+ private static String readAscii(InputStream in) throws IOException {
+ return readAscii(in, Integer.MAX_VALUE);
+ }
+
public void testMarkAndResetWithContentLengthHeader() throws IOException {
testMarkAndReset(TransferKind.FIXED_LENGTH);
}
@@ -1264,7 +1370,7 @@
fail();
} catch (IOException expected) {
}
- assertEquals("FGHIJKLMNOPQRSTUVWXYZ", readAscii(in, Integer.MAX_VALUE));
+ assertEquals("FGHIJKLMNOPQRSTUVWXYZ", readAscii(in));
assertContent("ABCDEFGHIJKLMNOPQRSTUVWXYZ", server.getUrl("/").openConnection());
}
@@ -1301,7 +1407,7 @@
URLConnection connection = server.getUrl("/").openConnection();
try {
- readAscii(connection.getInputStream(), Integer.MAX_VALUE);
+ readAscii(connection.getInputStream());
fail();
} catch (IOException e) {
}
@@ -1317,7 +1423,7 @@
URLConnection connection = server.getUrl("/").openConnection();
try {
- readAscii(connection.getInputStream(), Integer.MAX_VALUE);
+ readAscii(connection.getInputStream());
fail();
} catch (IOException e) {
}
@@ -1335,7 +1441,7 @@
server.play();
URLConnection connection = server.getUrl("/").openConnection();
- assertEquals("ABCABCABC", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("ABCABCABC", readAscii(connection.getInputStream()));
assertNull(connection.getContentEncoding());
assertEquals(-1, connection.getContentLength());
@@ -1354,7 +1460,7 @@
URLConnection connection = server.getUrl("/").openConnection();
connection.addRequestProperty("Accept-Encoding", "gzip");
InputStream gunzippedIn = new GZIPInputStream(connection.getInputStream());
- assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", readAscii(gunzippedIn, Integer.MAX_VALUE));
+ assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", readAscii(gunzippedIn));
assertEquals(bodyBytes.length, connection.getContentLength());
RecordedRequest request = server.takeRequest();
@@ -1378,7 +1484,7 @@
URLConnection connection = server.getUrl("/").openConnection();
connection.addRequestProperty("Accept-Encoding", "custom");
- assertEquals("ABCDE", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("ABCDE", readAscii(connection.getInputStream()));
RecordedRequest request = server.takeRequest();
assertContains(request.getHeaders(), "Accept-Encoding: custom");
@@ -1403,11 +1509,11 @@
URLConnection connection = server.getUrl("/").openConnection();
connection.addRequestProperty("Accept-Encoding", "gzip");
InputStream gunzippedIn = new GZIPInputStream(connection.getInputStream());
- assertEquals("one (gzipped)", readAscii(gunzippedIn, Integer.MAX_VALUE));
+ assertEquals("one (gzipped)", readAscii(gunzippedIn));
assertEquals(0, server.takeRequest().getSequenceNumber());
connection = server.getUrl("/").openConnection();
- assertEquals("two (identity)", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("two (identity)", readAscii(connection.getInputStream()));
assertEquals(1, server.takeRequest().getSequenceNumber());
}
@@ -1428,7 +1534,7 @@
assertContent("", connection1);
HttpURLConnection connection2 = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("A", readAscii(connection2.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("A", readAscii(connection2.getInputStream()));
assertEquals(0, server.takeRequest().getSequenceNumber());
assertEquals(1, server.takeRequest().getSequenceNumber());
@@ -1564,7 +1670,7 @@
server.enqueue(new MockResponse().setBody("A"));
server.play();
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("A", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("A", readAscii(connection.getInputStream()));
try {
connection.setFixedLengthStreamingMode(1);
fail();
@@ -1576,7 +1682,7 @@
server.enqueue(new MockResponse().setBody("A"));
server.play();
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("A", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("A", readAscii(connection.getInputStream()));
try {
connection.setChunkedStreamingMode(1);
fail();
@@ -1636,7 +1742,7 @@
OutputStream outputStream = connection.getOutputStream();
outputStream.write(requestBody);
outputStream.close();
- assertEquals("Success!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Success!", readAscii(connection.getInputStream()));
RecordedRequest request = server.takeRequest();
assertEquals("POST / HTTP/1.1", request.getRequestLine());
@@ -1672,7 +1778,7 @@
OutputStream outputStream = connection.getOutputStream();
outputStream.write(requestBody);
outputStream.close();
- assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Successful auth!", readAscii(connection.getInputStream()));
// no authorization header for the first request...
RecordedRequest request = server.takeRequest();
@@ -1704,7 +1810,7 @@
SimpleAuthenticator authenticator = new SimpleAuthenticator();
Authenticator.setDefault(authenticator);
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Successful auth!", readAscii(connection.getInputStream()));
assertEquals(Authenticator.RequestorType.SERVER, authenticator.requestorType);
assertEquals(server.getPort(), authenticator.requestingPort);
assertEquals(InetAddress.getByName(server.getHostName()), authenticator.requestingSite);
@@ -1742,7 +1848,7 @@
SimpleAuthenticator authenticator = new SimpleAuthenticator();
Authenticator.setDefault(authenticator);
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Successful auth!", readAscii(connection.getInputStream()));
assertEquals(Authenticator.RequestorType.SERVER, authenticator.requestorType);
assertEquals(server.getPort(), authenticator.requestingPort);
assertEquals(InetAddress.getByName(server.getHostName()), authenticator.requestingSite);
@@ -1765,7 +1871,7 @@
authenticator.expectedPrompt = "b";
Authenticator.setDefault(authenticator);
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Successful auth!", readAscii(connection.getInputStream()));
assertContainsNoneMatching(server.takeRequest().getHeaders(), "Authorization: .*");
assertContains(server.takeRequest().getHeaders(),
@@ -1787,7 +1893,7 @@
authenticator.expectedPrompt = "b";
Authenticator.setDefault(authenticator);
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Successful auth!", readAscii(connection.getInputStream()));
assertContainsNoneMatching(server.takeRequest().getHeaders(), "Authorization: .*");
assertContains(server.takeRequest().getHeaders(),
@@ -1817,8 +1923,7 @@
server.play();
URLConnection connection = server.getUrl("/").openConnection();
- assertEquals("This is the new location!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This is the new location!", readAscii(connection.getInputStream()));
RecordedRequest first = server.takeRequest();
assertEquals("GET / HTTP/1.1", first.getRequestLine());
@@ -1841,8 +1946,7 @@
HttpsURLConnection connection = (HttpsURLConnection) server.getUrl("/").openConnection();
connection.setSSLSocketFactory(testSSLContext.clientContext.getSocketFactory());
- assertEquals("This is the new location!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This is the new location!", readAscii(connection.getInputStream()));
RecordedRequest first = server.takeRequest();
assertEquals("GET / HTTP/1.1", first.getRequestLine());
@@ -1862,8 +1966,7 @@
HttpsURLConnection connection = (HttpsURLConnection) server.getUrl("/").openConnection();
connection.setSSLSocketFactory(testSSLContext.clientContext.getSocketFactory());
- assertEquals("This page has moved!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This page has moved!", readAscii(connection.getInputStream()));
}
public void testNotRedirectedFromHttpToHttps() throws IOException, InterruptedException {
@@ -1874,8 +1977,7 @@
server.play();
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("This page has moved!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This page has moved!", readAscii(connection.getInputStream()));
}
public void testRedirectToAnotherOriginServer() throws Exception {
@@ -1891,13 +1993,11 @@
server.play();
URLConnection connection = server.getUrl("/").openConnection();
- assertEquals("This is the 2nd server!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This is the 2nd server!", readAscii(connection.getInputStream()));
assertEquals(server2.getUrl("/"), connection.getURL());
// make sure the first server was careful to recycle the connection
- assertEquals("This is the first server again!",
- readAscii(server.getUrl("/").openStream(), Integer.MAX_VALUE));
+ assertEquals("This is the first server again!", readAscii(server.getUrl("/").openStream()));
RecordedRequest first = server.takeRequest();
assertContains(first.getHeaders(), "Host: " + hostName + ":" + server.getPort());
@@ -1963,7 +2063,7 @@
try {
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
- assertEquals("Target", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Target", readAscii(connection.getInputStream()));
// Inspect the redirect request to see what request was actually made.
RecordedRequest actualRequest = server2.takeRequest();
@@ -2051,7 +2151,7 @@
OutputStream outputStream = connection.getOutputStream();
outputStream.write(requestBody);
outputStream.close();
- assertEquals("Page 2", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("Page 2", readAscii(connection.getInputStream()));
assertTrue(connection.getDoOutput());
RecordedRequest page1 = server.takeRequest();
@@ -2072,8 +2172,7 @@
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/foo").openConnection();
// Fails on the RI, which gets "Proxy Response"
- assertEquals("This page has moved!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This page has moved!", readAscii(connection.getInputStream()));
RecordedRequest page1 = server.takeRequest();
assertEquals("GET /foo HTTP/1.1", page1.getRequestLine());
@@ -2099,9 +2198,9 @@
server.play();
URL url = server.getUrl("/");
- assertEquals("ABC", readAscii(url.openStream(), Integer.MAX_VALUE));
- assertEquals("DEF", readAscii(url.openStream(), Integer.MAX_VALUE));
- assertEquals("GHI", readAscii(url.openStream(), Integer.MAX_VALUE));
+ assertEquals("ABC", readAscii(url.openStream()));
+ assertEquals("DEF", readAscii(url.openStream()));
+ assertEquals("GHI", readAscii(url.openStream()));
assertEquals(Arrays.asList("verify " + hostName), hostnameVerifier.calls);
assertEquals(Arrays.asList("checkServerTrusted ["
@@ -2270,8 +2369,7 @@
server.play();
URLConnection connection = server.getUrl("/").openConnection();
- assertEquals("This is the new location!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This is the new location!", readAscii(connection.getInputStream()));
assertEquals(0, server.takeRequest().getSequenceNumber());
assertEquals("When connection: close is used, each request should get its own connection",
@@ -2285,8 +2383,7 @@
server.play();
URLConnection connection = server.getUrl("/").openConnection();
- assertEquals("This body is not allowed!",
- readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("This body is not allowed!", readAscii(connection.getInputStream()));
}
public void testSingleByteReadIsSigned() throws IOException {
@@ -2333,7 +2430,7 @@
OutputStream out = connection.getOutputStream();
out.write(upload);
- assertEquals("abc", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("abc", readAscii(connection.getInputStream()));
out.flush(); // dubious but permitted
try {
@@ -2370,7 +2467,7 @@
// Read timeout of a day, sure to cause the test to timeout and fail.
connection.setReadTimeout(24 * 3600 * 1000);
InputStream input = connection.getInputStream();
- assertEquals("ABC", readAscii(input, Integer.MAX_VALUE));
+ assertEquals("ABC", readAscii(input));
input.close();
try {
connection = server.getUrl("").openConnection();
@@ -2677,7 +2774,7 @@
server.play();
HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
InputStream in = (InputStream) connection.getContent();
- assertEquals("A", readAscii(in, Integer.MAX_VALUE));
+ assertEquals("A", readAscii(in));
}
public void testGetContentOfType() throws Exception {
@@ -2761,7 +2858,7 @@
OutputStream out = connection.getOutputStream();
out.write(new byte[] { 'A', 'B', 'C' });
out.close();
- assertEquals("A", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+ assertEquals("A", readAscii(connection.getInputStream()));
RecordedRequest request = server.takeRequest();
assertContains(request.getHeaders(), "Content-Length: 3");
}
@@ -2799,7 +2896,7 @@
server.enqueue(new MockResponse().setBody("A"));
server.play();
URL url = new URL("http", server.getHostName(), server.getPort(), "?query");
- assertEquals("A", readAscii(url.openConnection().getInputStream(), Integer.MAX_VALUE));
+ assertEquals("A", readAscii(url.openConnection().getInputStream()));
RecordedRequest request = server.takeRequest();
assertEquals("GET /?query HTTP/1.1", request.getRequestLine());
}
diff --git a/luni/src/test/java/libcore/java/util/DateTest.java b/luni/src/test/java/libcore/java/util/DateTest.java
index 1fd8193..9cd9868 100644
--- a/luni/src/test/java/libcore/java/util/DateTest.java
+++ b/luni/src/test/java/libcore/java/util/DateTest.java
@@ -51,18 +51,14 @@
c.set(Calendar.YEAR, 21);
assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString());
String actual21GmtString = c.getTime().toGMTString();
- // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
- assertTrue("Actual: " + actual21GmtString,
- "1 Jan 21 07:52:58 GMT".equals(actual21GmtString)
- || "1 Jan 21 08:00:00 GMT".equals(actual21GmtString));
+ // zic <= 2014b data produces -08:00:00, later ones produce -07:52:58 instead.
+ assertEquals("1 Jan 21 07:52:58 GMT", actual21GmtString);
c.set(Calendar.YEAR, 321);
assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
String actual321GmtString = c.getTime().toGMTString();
- // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
- assertTrue("Actual: " + actual321GmtString,
- "1 Jan 321 07:52:58 GMT".equals(actual321GmtString)
- || "1 Jan 321 08:00:00 GMT".equals(actual321GmtString));
+ // zic <= 2014b data produces -08:00:00, later ones produce -07:52:58 instead.
+ assertEquals("1 Jan 321 07:52:58 GMT", actual321GmtString);
}
public void test_toGMTString_nonUs() throws Exception {
@@ -74,18 +70,14 @@
c.set(Calendar.YEAR, 21);
assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString());
String actual21GmtString = c.getTime().toGMTString();
- // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
- assertTrue("Actual: " + actual21GmtString,
- "1 Jan 21 07:52:58 GMT".equals(actual21GmtString)
- || "1 Jan 21 08:00:00 GMT".equals(actual21GmtString));
+ // zic <= 2014b data produces -08:00:00, later ones produce -07:52:58 instead.
+ assertEquals("1 Jan 21 07:52:58 GMT", actual21GmtString);
c.set(Calendar.YEAR, 321);
assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
String actual321GmtString = c.getTime().toGMTString();
- // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
- assertTrue("Actual: " + actual321GmtString,
- "1 Jan 321 07:52:58 GMT".equals(actual321GmtString)
- || "1 Jan 321 08:00:00 GMT".equals(actual321GmtString));
+ // zic <= 2014b data produces -08:00:00, later ones produce -07:52:58 instead.
+ assertEquals("1 Jan 321 07:52:58 GMT", actual321GmtString);
}
public void test_parse_timezones() {
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 6297080..481766c 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -374,10 +374,9 @@
// zic <= 2014b produces data that suggests before -1633280400 seconds (Sun, 31 Mar 1918
// 07:00:00 GMT) the offset was -18000000.
// zic > 2014b produces data that suggests before Integer.MIN_VALUE seconds the offset was
- // -17762000 and between Integer.MIN_VALUE and -1633280400 it was -18000000. Once Android
- // moves to zic > 2014b the -18000000 can be removed. http://b/73719425
+ // -17762000 and between Integer.MIN_VALUE and -1633280400 it was -18000000.
int actualOffset = tz.getOffset(lowerTimeMillis);
- assertTrue(-18000000 == actualOffset || -17762000 == actualOffset);
+ assertEquals(-17762000, actualOffset);
// Nov 30th 2039, no daylight savings as per current rules.
assertFalse(tz.inDaylightTime(new Date(upperTimeMillis)));
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 471906f..0e2c6b5 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -16,6 +16,12 @@
package libcore.libcore.io;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -28,6 +34,8 @@
import android.system.OsConstants;
import android.system.StructAddrinfo;
+import java.io.FileDescriptor;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
@@ -39,6 +47,8 @@
import java.util.regex.Pattern;
import libcore.io.BlockGuardOs;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
import libcore.io.Os;
import dalvik.system.BlockGuard;
@@ -48,6 +58,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -130,6 +142,31 @@
}
}
+ @Test
+ public void test_connect_networkPolicy() throws ErrnoException, IOException {
+ BlockGuardOs blockGuardOs = new BlockGuardOs(mockOsDelegate);
+
+ // Test connect with a UDP socket that will not trigger a network policy check.
+ FileDescriptor udpSocket = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ try {
+ blockGuardOs.connect(udpSocket, InetAddress.getLoopbackAddress(), 0);
+ verify(mockThreadPolicy, never()).onNetwork();
+ verify(mockOsDelegate, times(1)).connect(eq(udpSocket), any(), anyInt());
+ } finally {
+ IoUtils.closeQuietly(udpSocket);
+ }
+
+ // Test connect with a TCP socket that will trigger a network policy check.
+ FileDescriptor tcpSocket = Libcore.os.socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ try {
+ blockGuardOs.connect(tcpSocket, InetAddress.getLoopbackAddress(), 0);
+ verify(mockThreadPolicy, times(1)).onNetwork();
+ verify(mockOsDelegate, times(1)).connect(eq(tcpSocket), any(), anyInt());
+ } finally {
+ IoUtils.closeQuietly(tcpSocket);
+ }
+ }
+
/**
* Checks that BlockGuardOs is updated when the Os interface changes. BlockGuardOs extends
* ForwardingOs so doing so isn't an obvious step and it can be missed. When adding methods to
diff --git a/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java b/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java
index 4de1a01..800928f 100644
--- a/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java
+++ b/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java
@@ -18,28 +18,69 @@
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Locale;
+
import junit.framework.TestCase;
import static libcore.util.HexEncoding.decode;
import static libcore.util.HexEncoding.encode;
+import static libcore.util.HexEncoding.encodeToString;
public class HexEncodingTest extends TestCase {
- public void testEncode() {
- final byte[] avocados = "avocados".getBytes(StandardCharsets.UTF_8);
- assertArraysEqual("61766F6361646F73".toCharArray(), encode(avocados));
- assertArraysEqual(avocados, decode(encode(avocados), false));
- // Make sure we can handle lower case hex encodings as well.
- assertArraysEqual(avocados, decode("61766f6361646f73".toCharArray(), false));
+ public void testEncodeByte() {
+ Object[][] testCases = new Object[][] {
+ { 0x01, "01" },
+ { 0x09, "09" },
+ { 0x0A, "0A" },
+ { 0x0F, "0F" },
+ { 0x10, "10" },
+ { 0x1F, "1F" },
+ { 0x20, "20" },
+ { 0x7F, "7F" },
+ { 0x80, "80" },
+ { 0xFF, "FF" },
+ };
+ for (Object[] testCase : testCases) {
+ Number toEncode = (Number) testCase[0];
+ String expected = (String) testCase[1];
+
+ String actualUpper = encodeToString(toEncode.byteValue(), true /* upperCase */);
+ assertEquals(upper(expected), actualUpper);
+
+ String actualLower = encodeToString(toEncode.byteValue(), false /* upperCase */);
+ assertEquals(lower(expected), actualLower);
+ }
+ }
+
+ public void testEncodeBytes() {
+ Object[][] testCases = new Object[][] {
+ { "avocados".getBytes(StandardCharsets.UTF_8), "61766F6361646F73" },
+ };
+
+ for (Object[] testCase : testCases) {
+ byte[] bytes = (byte[]) testCase[0];
+ String encodedLower = lower((String) testCase[1]);
+ String encodedUpper = upper((String) testCase[1]);
+
+ assertArraysEqual(encodedUpper.toCharArray(), encode(bytes));
+ assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */));
+ assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */));
+
+ assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */));
+
+ // Make sure we can handle lower case hex encodings as well.
+ assertArraysEqual(bytes, decode(encodedLower.toCharArray(), false /* allowSingleChar */));
+ }
}
public void testDecode_allow4Bit() {
assertArraysEqual(new byte[] { 6 }, decode("6".toCharArray(), true));
- assertArraysEqual(new byte[] { 6, 'v' }, decode("676".toCharArray(), true));
+ assertArraysEqual(new byte[] { 6, 0x76 }, decode("676".toCharArray(), true));
}
public void testDecode_disallow4Bit() {
try {
- decode("676".toCharArray(), false);
+ decode("676".toCharArray(), false /* allowSingleChar */);
fail();
} catch (IllegalArgumentException expected) {
}
@@ -47,7 +88,7 @@
public void testDecode_invalid() {
try {
- decode("DEADBARD".toCharArray(), false);
+ decode("DEADBARD".toCharArray(), false /* allowSingleChar */);
fail();
} catch (IllegalArgumentException expected) {
}
@@ -56,13 +97,13 @@
// commons uses Character.isDigit and would successfully decode a string with
// arabic and devanagari characters.
try {
- decode("६१٧٥٥F6361646F73".toCharArray(), false);
+ decode("६१٧٥٥F6361646F73".toCharArray(), false /* allowSingleChar */);
fail();
} catch (IllegalArgumentException expected) {
}
try {
- decode("#%6361646F73".toCharArray(), false);
+ decode("#%6361646F73".toCharArray(), false /* allowSingleChar */);
fail();
} catch (IllegalArgumentException expected) {
}
@@ -75,4 +116,12 @@
private static void assertArraysEqual(byte[] lhs, byte[] rhs) {
assertEquals(Arrays.toString(lhs), Arrays.toString(rhs));
}
+
+ private static String lower(String string) {
+ return string.toLowerCase(Locale.ROOT);
+ }
+
+ private static String upper(String string) {
+ return string.toUpperCase(Locale.ROOT);
+ }
}
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
index dbc0201..da717bd 100644
--- a/mmodules/core_platform_api/api/platform/current-api.txt
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -71,11 +71,6 @@
package android.system {
- public final class ErrnoException extends java.lang.Exception {
- method public java.io.IOException rethrowAsIOException() throws java.io.IOException;
- method public java.net.SocketException rethrowAsSocketException() throws java.net.SocketException;
- }
-
public class Int32Ref {
ctor public Int32Ref(int);
field @dalvik.annotation.compat.UnsupportedAppUsage public int value;
@@ -805,10 +800,6 @@
package java.lang {
- public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
- method public static String toHexString(byte, boolean);
- }
-
public final class Class<T> implements java.lang.reflect.AnnotatedElement java.lang.reflect.GenericDeclaration java.io.Serializable java.lang.reflect.Type {
method @dalvik.annotation.optimization.FastNative public java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean);
method @dalvik.annotation.optimization.FastNative public java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean);
@@ -1228,11 +1219,15 @@
public class HexEncoding {
method public static byte[] decode(String) throws java.lang.IllegalArgumentException;
+ method public static byte[] decode(String, boolean) throws java.lang.IllegalArgumentException;
method public static byte[] decode(char[]) throws java.lang.IllegalArgumentException;
method public static byte[] decode(char[], boolean) throws java.lang.IllegalArgumentException;
method public static char[] encode(byte[]);
+ method public static char[] encode(byte[], boolean);
method public static char[] encode(byte[], int, int);
+ method public static String encodeToString(byte, boolean);
method public static String encodeToString(byte[]);
+ method public static String encodeToString(byte[], boolean);
}
public class NativeAllocationRegistry {
diff --git a/mmodules/intracoreapi/api/intra/current-api.txt b/mmodules/intracoreapi/api/intra/current-api.txt
index a7a2fdc..9780457 100644
--- a/mmodules/intracoreapi/api/intra/current-api.txt
+++ b/mmodules/intracoreapi/api/intra/current-api.txt
@@ -1,12 +1,4 @@
// Signature format: 2.0
-package android.system {
-
- public final class ErrnoException extends java.lang.Exception {
- method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public java.net.SocketException rethrowAsSocketException() throws java.net.SocketException;
- }
-
-}
-
package com.android.org.conscrypt {
@libcore.api.IntraCoreApi public class DESEDESecretKeyFactory extends javax.crypto.SecretKeyFactorySpi {
diff --git a/ojluni/Android.bp b/ojluni/Android.bp
new file mode 100644
index 0000000..20a5a5a
--- /dev/null
+++ b/ojluni/Android.bp
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 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.
+
+// Phony target that causes the build to check the license file in this
+// directory, detect that it is a GPL license and then copy all the files
+// from this directory and its subdirectories in to the
+// ${OUT}/obj/PACKAGING/gpl_source_intermediates/gpl_source.tgz file.
+phony {
+ name: "ojluni-phony",
+
+ // A phony module must have at least one dependency.
+ required: [
+ "core-oj",
+ ],
+}
diff --git a/ojluni/Android.mk b/ojluni/Android.mk
deleted file mode 100644
index 8eef8b5..0000000
--- a/ojluni/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- mode: makefile -*-
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ojluni-phony
-include $(BUILD_PHONY_PACKAGE)
-
diff --git a/ojluni/annotations/mmodule/java/lang/Byte.annotated.java b/ojluni/annotations/mmodule/java/lang/Byte.annotated.java
deleted file mode 100644
index 2d61598..0000000
--- a/ojluni/annotations/mmodule/java/lang/Byte.annotated.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package java.lang;
-
-
-@SuppressWarnings({"unchecked", "deprecation", "all"})
-public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
-
-public Byte(byte value) { throw new RuntimeException("Stub!"); }
-
-public Byte(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
-
-public static byte parseByte(java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static byte parseByte(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte valueOf(java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte valueOf(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte decode(java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public byte byteValue() { throw new RuntimeException("Stub!"); }
-
-public short shortValue() { throw new RuntimeException("Stub!"); }
-
-public int intValue() { throw new RuntimeException("Stub!"); }
-
-public long longValue() { throw new RuntimeException("Stub!"); }
-
-public float floatValue() { throw new RuntimeException("Stub!"); }
-
-public double doubleValue() { throw new RuntimeException("Stub!"); }
-
-public java.lang.String toString() { throw new RuntimeException("Stub!"); }
-
-public int hashCode() { throw new RuntimeException("Stub!"); }
-
-public static int hashCode(byte value) { throw new RuntimeException("Stub!"); }
-
-public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
-
-public int compareTo(java.lang.Byte anotherByte) { throw new RuntimeException("Stub!"); }
-
-public static int compare(byte x, byte y) { throw new RuntimeException("Stub!"); }
-
-public static int toUnsignedInt(byte x) { throw new RuntimeException("Stub!"); }
-
-public static long toUnsignedLong(byte x) { throw new RuntimeException("Stub!"); }
-
-@libcore.api.CorePlatformApi
-public static java.lang.String toHexString(byte b, boolean upperCase) { throw new RuntimeException("Stub!"); }
-
-public static final int BYTES = 1; // 0x1
-
-public static final byte MAX_VALUE = 127; // 0x7f
-
-public static final byte MIN_VALUE = -128; // 0xffffff80
-
-public static final int SIZE = 8; // 0x8
-
-public static final java.lang.Class<java.lang.Byte> TYPE;
-static { TYPE = null; }
-}
-
diff --git a/ojluni/src/main/java/java/lang/Byte.java b/ojluni/src/main/java/java/lang/Byte.java
index e53899c..deb4ecb 100644
--- a/ojluni/src/main/java/java/lang/Byte.java
+++ b/ojluni/src/main/java/java/lang/Byte.java
@@ -25,6 +25,8 @@
package java.lang;
+import libcore.util.HexEncoding;
+
/**
*
* The {@code Byte} class wraps a value of primitive type {@code byte}
@@ -523,24 +525,8 @@
* @hide
*/
public static String toHexString(byte b, boolean upperCase) {
- char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
- char[] buf = new char[2]; // We always want two digits.
- buf[0] = digits[(b >> 4) & 0xf];
- buf[1] = digits[b & 0xf];
- return new String(0, 2, buf);
+ // This method currently retained because it is marked @UnsupportedAppUsage.
+ return HexEncoding.encodeToString(b, upperCase);
}
- private static final char[] DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z'
- };
-
- private static final char[] UPPER_CASE_DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z'
- };
// END Android-added: toHexString() for internal use.
}
diff --git a/ojluni/src/main/java/java/time/chrono/JapaneseEra.java b/ojluni/src/main/java/java/time/chrono/JapaneseEra.java
index 0c9e3e8..d52f3c1 100644
--- a/ojluni/src/main/java/java/time/chrono/JapaneseEra.java
+++ b/ojluni/src/main/java/java/time/chrono/JapaneseEra.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,11 +73,14 @@
import java.io.Serializable;
import java.time.DateTimeException;
import java.time.LocalDate;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalField;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.time.temporal.ValueRange;
import java.util.Arrays;
+import java.util.Locale;
import java.util.Objects;
import sun.util.calendar.CalendarDate;
@@ -85,10 +88,33 @@
/**
* An era in the Japanese Imperial calendar system.
* <p>
- * This class defines the valid eras for the Japanese chronology.
- * Japan introduced the Gregorian calendar starting with Meiji 6.
- * Only Meiji and later eras are supported;
- * dates before Meiji 6, January 1 are not supported.
+ * The Japanese government defines the official name and start date of
+ * each era. Eras are consecutive and their date ranges do not overlap,
+ * so the end date of one era is always the day before the start date
+ * of the next era.
+ * <p>
+ * The Java SE Platform supports all eras defined by the Japanese government,
+ * beginning with the Meiji era. Each era is identified in the Platform by an
+ * integer value and a name. The {@link #of(int)} and {@link #valueOf(String)}
+ * methods may be used to obtain a singleton instance of JapaneseEra for each
+ * era. The {@link #values()} method returns the singleton instances of all
+ * supported eras.
+ * <p>
+ * For convenience, this class declares a number of public static final fields
+ * that refer to singleton instances returned by the values() method.
+ *
+ * @apiNote
+ * The fields declared in this class may evolve over time, in line with the
+ * results of the {@link #values()} method. However, there is not necessarily
+ * a 1:1 correspondence between the fields and the singleton instances.
+ *
+ * @apiNote
+ * The Japanese government may announce a new era and define its start
+ * date but not its official name. In this scenario, the singleton instance
+ * that represents the new era may return a name that is not stable until
+ * the official name is defined. Developers should exercise caution when
+ * relying on the name returned by any singleton instance that does not
+ * correspond to a public static final field.
*
* @implSpec
* This class is immutable and thread-safe.
@@ -120,14 +146,20 @@
*/
public static final JapaneseEra SHOWA = new JapaneseEra(1, LocalDate.of(1926, 12, 25));
/**
- * The singleton instance for the 'Heisei' era (1989-01-08 - current)
+ * The singleton instance for the 'Heisei' era (1989-01-08 - 2019-04-30)
* which has the value 2.
*/
public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));
+ /**
+ * The singleton instance for the 'Reiwa' era (2019-05-01 - current)
+ * which has the value 3. The end date of this era is not specified, unless
+ * the Japanese Government defines it.
+ */
+ private static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
- // the number of defined JapaneseEra constants.
- // There could be an extra era defined in its configuration.
- private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET;
+ // The number of predefined JapaneseEra constants.
+ // There may be a supplemental era defined by the property.
+ private static final int N_ERA_CONSTANTS = REIWA.getValue() + ERA_OFFSET;
/**
* Serialization version.
@@ -145,6 +177,7 @@
KNOWN_ERAS[1] = TAISHO;
KNOWN_ERAS[2] = SHOWA;
KNOWN_ERAS[3] = HEISEI;
+ KNOWN_ERAS[4] = REIWA;
for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) {
CalendarDate date = ERA_CONFIG[i].getSinceDate();
LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth());
@@ -185,10 +218,18 @@
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code JapaneseEra} from an {@code int} value.
+ * <ul>
+ * <li>The value {@code 1} is associated with the 'Showa' era, because
+ * it contains 1970-01-01 (ISO calendar system).</li>
+ * <li>The values {@code -1} and {@code 0} are associated with two earlier
+ * eras, Meiji and Taisho, respectively.</li>
+ * <li>A value greater than {@code 1} is associated with a later era,
+ * beginning with Heisei ({@code 2}).</li>
+ * </ul>
* <p>
- * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1
- * Later era is numbered 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}),
- * -1 ({@link #MEIJI}), only Meiji and later eras are supported.
+ * Every instance of {@code JapaneseEra} that is returned from the {@link #values()}
+ * method has an int value (available via {@link Era#getValue()} which is
+ * accepted by this method.
*
* @param japaneseEra the era to represent
* @return the {@code JapaneseEra} singleton, not null
@@ -236,6 +277,28 @@
return Arrays.copyOf(KNOWN_ERAS, KNOWN_ERAS.length);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @param style {@inheritDoc}
+ * @param locale {@inheritDoc}
+ */
+ @Override
+ public String getDisplayName(TextStyle style, Locale locale) {
+ // If this JapaneseEra is a supplemental one, obtain the name from
+ // the era definition.
+ if (getValue() > N_ERA_CONSTANTS - ERA_OFFSET) {
+ Objects.requireNonNull(locale, "locale");
+ return style.asNormal() == TextStyle.NARROW ? getAbbreviation() : getName();
+ }
+
+ return new DateTimeFormatterBuilder()
+ .appendText(ERA, style)
+ .toFormatter(locale)
+ .withChronology(JapaneseChronology.INSTANCE)
+ .format(this == MEIJI ? MEIJI_6_ISODATE : since);
+ }
+
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code JapaneseEra} from a date.
@@ -337,11 +400,7 @@
//-----------------------------------------------------------------------
String getAbbreviation() {
- int index = ordinal(getValue());
- if (index == 0) {
- return "";
- }
- return ERA_CONFIG[index].getAbbreviation();
+ return ERA_CONFIG[ordinal(getValue())].getAbbreviation();
}
String getName() {
diff --git a/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java b/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
index 67507bc..a0ee15e 100644
--- a/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
+++ b/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
* 2 Taisho 1912-07-30 midnight local time
* 3 Showa 1926-12-25 midnight local time
* 4 Heisei 1989-01-08 midnight local time
+ * 5 Reiwa 2019-05-01 midnight local time
* ------------------------------------------------------
* </tt></pre>
*
@@ -100,6 +101,11 @@
*/
public static final int HEISEI = 4;
+ /**
+ * The ERA constant designating the Reiwa era.
+ */
+ private static final int REIWA = 5;
+
private static final int EPOCH_OFFSET = 719163; // Fixed date of January 1, 1970 (Gregorian)
private static final int EPOCH_YEAR = 1970;
@@ -132,6 +138,9 @@
// Fixed date of the first date of each era.
private static final long[] sinceFixedDates;
+ // The current era
+ private static final int currentEra;
+
/*
* <pre>
* Greatest Least
@@ -227,13 +236,25 @@
// eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
// same as Gregorian.
int index = BEFORE_MEIJI;
+ // Android-removed: Zygote could initialize this class when system has outdated time.
+ // int current = index;
sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
eras[index++] = BEFORE_MEIJI_ERA;
for (Era e : es) {
+ // Android-removed: Zygote could initialize this class when system has outdated time.
+ // Android hard-code the current era. Unlike upstream, Android does not add the new era
+ // in the code until the new era arrives. Thus, Android can't have newer era than the
+ // real world. currentEra is the latest Era that Android knows about.
+ // if(e.getSince(TimeZone.NO_TIMEZONE) < System.currentTimeMillis()) {
+ // current = index;
+ // }
CalendarDate d = e.getSinceDate();
sinceFixedDates[index] = gcal.getFixedDate(d);
eras[index++] = e;
}
+ // Android-changed: Zygote could initialize this class when system has outdated time.
+ // currentEra = current;
+ currentEra = REIWA;
LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
@@ -1716,12 +1737,12 @@
}
} else if (transitionYear) {
if (jdate.getYear() == 1) {
- // As of Heisei (since Meiji) there's no case
+ // As of Reiwa (since Meiji) there's no case
// that there are multiple transitions in a
// year. Historically there was such
// case. There might be such case again in the
// future.
- if (era > HEISEI) {
+ if (era > REIWA) {
CalendarDate pd = eras[era - 1].getSinceDate();
if (normalizedYear == pd.getYear()) {
d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
@@ -1856,7 +1877,7 @@
year = isSet(YEAR) ? internalGet(YEAR) : 1;
} else {
if (isSet(YEAR)) {
- era = eras.length - 1;
+ era = currentEra;
year = internalGet(YEAR);
} else {
// Equivalent to 1970 (Gregorian)
@@ -2341,7 +2362,7 @@
* default ERA is the current era, but a zero (unset) ERA means before Meiji.
*/
private int internalGetEra() {
- return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
+ return isSet(ERA) ? internalGet(ERA) : currentEra;
}
/**
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index 143fa5e..b71d11a 100644
--- a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -188,7 +188,6 @@
*/
private static class NoPreloadHolder {
public static HostnameVerifier defaultHostnameVerifier;
- public static final Class<? extends HostnameVerifier> originalDefaultHostnameVerifierClass;
static {
try {
/**
@@ -200,7 +199,6 @@
defaultHostnameVerifier = (HostnameVerifier)
Class.forName("com.android.okhttp.internal.tls.OkHostnameVerifier")
.getField("INSTANCE").get(null);
- originalDefaultHostnameVerifierClass = defaultHostnameVerifier.getClass();
} catch (Exception e) {
throw new AssertionError("Failed to obtain okhttp HostnameVerifier", e);
}
@@ -210,7 +208,7 @@
/**
* The <code>hostnameVerifier</code> for this object.
*/
- protected HostnameVerifier hostnameVerifier;
+ protected HostnameVerifier hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
// END Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
// Android-changed: Modified the documentation to explain side effects / discourage method use.
@@ -329,15 +327,6 @@
* @see #setDefaultHostnameVerifier(HostnameVerifier)
*/
public HostnameVerifier getHostnameVerifier() {
- // Android-added: Use the default verifier if none is set.
- // Note that this also has the side effect of *setting* (if unset)
- // hostnameVerifier to be the default one. It's not clear why this
- // was done (commit abd00f0eaa46f71f98e75a631c268c812d1ec7c1) but
- // we're keeping this behavior for lack of a strong reason to do
- // otherwise.
- if (hostnameVerifier == null) {
- hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
- }
return hostnameVerifier;
}
diff --git a/ojluni/src/main/java/sun/util/calendar/Era.java b/ojluni/src/main/java/sun/util/calendar/Era.java
index a013c57..7c02cce 100644
--- a/ojluni/src/main/java/sun/util/calendar/Era.java
+++ b/ojluni/src/main/java/sun/util/calendar/Era.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
* Taisho 1912-07-30 midnight local time
* Showa 1926-12-26 midnight local time
* Heisei 1989-01-08 midnight local time
+ * Reiwa 2019-05-01 midnight local time
* Julian calendar BeforeCommonEra -292275055-05-16T16:47:04.192Z
* CommonEra 0000-12-30 midnight local time
* Taiwanese calendar MinGuo 1911-01-01 midnight local time
diff --git a/ojluni/src/main/resources/calendars.properties b/ojluni/src/main/resources/calendars.properties
index 49f68ac..6007d7a 100644
--- a/ojluni/src/main/resources/calendars.properties
+++ b/ojluni/src/main/resources/calendars.properties
@@ -29,12 +29,14 @@
# Taisho since 1912-07-30 00:00:00 local time (Gregorian)
# Showa since 1926-12-25 00:00:00 local time (Gregorian)
# Heisei since 1989-01-08 00:00:00 local time (Gregorian)
+# Reiwa since 2019-05-01 00:00:00 local time (Gregorian)
calendar.japanese.type: LocalGregorianCalendar
calendar.japanese.eras: \
name=Meiji,abbr=M,since=-3218832000000; \
name=Taisho,abbr=T,since=-1812153600000; \
name=Showa,abbr=S,since=-1357603200000; \
- name=Heisei,abbr=H,since=600220800000
+ name=Heisei,abbr=H,since=600220800000; \
+ name=Reiwa,abbr=R,since=1556668800000
#
# Taiwanese calendar
diff --git a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
index 2bc1f4c..091b385 100644
--- a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
+++ b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -111,6 +111,9 @@
*/
@Test
public class TCKJapaneseChronology {
+
+ // Year differences from Gregorian years.
+ private static final int YDIFF_REIWA = 2018;
private static final int YDIFF_HEISEI = 1988;
private static final int YDIFF_MEIJI = 1867;
private static final int YDIFF_SHOWA = 1925;
@@ -173,6 +176,7 @@
@DataProvider(name="createByEra")
Object[][] data_createByEra() {
return new Object[][] {
+ {JapaneseEra.of(3), 2020 - YDIFF_REIWA, 2, 29, 60, LocalDate.of(2020, 2, 29)}, // NEWERA
{JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(1996, 2, 29)},
{JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(2000, 2, 29)},
{JapaneseEra.MEIJI, 1874 - YDIFF_MEIJI, 2, 28, 59, LocalDate.of(1874, 2, 28)},
@@ -365,8 +369,11 @@
@DataProvider(name="prolepticYear")
Object[][] data_prolepticYear() {
return new Object[][] {
+ {3, JapaneseEra.of(3), 1, 1 + YDIFF_REIWA, false},
+ {3, JapaneseEra.of(3), 102, 102 + YDIFF_REIWA, true},
+
{2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false},
- {2, JapaneseEra.HEISEI, 100, 100 + YDIFF_HEISEI, true},
+ {2, JapaneseEra.HEISEI, 4, 4 + YDIFF_HEISEI, true},
{-1, JapaneseEra.MEIJI, 9, 9 + YDIFF_MEIJI, true},
{-1, JapaneseEra.MEIJI, 10, 10 + YDIFF_MEIJI, false},
@@ -548,6 +555,7 @@
{ JapaneseEra.TAISHO, 0, "Taisho"},
{ JapaneseEra.SHOWA, 1, "Showa"},
{ JapaneseEra.HEISEI, 2, "Heisei"},
+ { JapaneseEra.of(3), 3, "Reiwa"},
};
}
@@ -562,7 +570,7 @@
@Test
public void test_Japanese_badEras() {
- int badEras[] = {-1000, -998, -997, -2, 3, 4, 1000};
+ int badEras[] = {-1000, -998, -997, -2, 4, 5, 1000};
for (int badEra : badEras) {
try {
Era era = JapaneseChronology.INSTANCE.eraOf(badEra);
@@ -683,6 +691,7 @@
{JapaneseChronology.INSTANCE.date(1989, 1, 7), "Japanese Showa 64-01-07"},
{JapaneseChronology.INSTANCE.date(1989, 1, 8), "Japanese Heisei 1-01-08"},
{JapaneseChronology.INSTANCE.date(2012, 12, 6), "Japanese Heisei 24-12-06"},
+ {JapaneseChronology.INSTANCE.date(2020, 1, 6), "Japanese Reiwa 2-01-06"},
};
}
diff --git a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java
index de83e1d..e37a6a5 100644
--- a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java
+++ b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,7 @@
@DataProvider(name = "JapaneseEras")
Object[][] data_of_eras() {
return new Object[][] {
+ {JapaneseEra.of(3), "Reiwa", 3},
{JapaneseEra.HEISEI, "Heisei", 2},
{JapaneseEra.SHOWA, "Showa", 1},
{JapaneseEra.TAISHO, "Taisho", 0},
diff --git a/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java b/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
index 3fbf853..03443d9 100644
--- a/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
+++ b/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
/**
* Tests for the Japanese chronology
@@ -58,6 +59,8 @@
{ JapaneseEra.SHOWA, 1, 12, 25, 1926 },
{ JapaneseEra.SHOWA, 64, 1, 7, 1989 },
{ JapaneseEra.HEISEI, 1, 1, 8, 1989 },
+ { JapaneseEra.HEISEI, 31, 4, 30, 2019 },
+ { JapaneseEra.of(3), 1, 5, 1, 2019 },
};
}
@@ -74,6 +77,8 @@
{ JapaneseEra.SHOWA, 64, 7, 1, 7 },
{ JapaneseEra.HEISEI, 1, 1, 1, 8 },
{ JapaneseEra.HEISEI, 2, 8, 1, 8 },
+ { JapaneseEra.HEISEI, 31, 120, 4, 30 },
+ { JapaneseEra.of(3), 1, 1, 5, 1 },
};
}
@@ -81,8 +86,8 @@
Object[][] rangeData() {
return new Object[][] {
// field, minSmallest, minLargest, maxSmallest, maxLargest
- { ChronoField.ERA, -1, -1, 2, 2},
- { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-1989 }, // depends on the current era
+ { ChronoField.ERA, -1, -1, 3, 3},
+ { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-2019}, // depends on the current era
{ ChronoField.DAY_OF_YEAR, 1, 1, 7, 366},
{ ChronoField.YEAR, 1873, 1873, 999999999, 999999999},
};
@@ -105,7 +110,9 @@
{ JapaneseEra.SHOWA, 65, 1, 1 },
{ JapaneseEra.HEISEI, 1, 1, 7 },
{ JapaneseEra.HEISEI, 1, 2, 29 },
- { JapaneseEra.HEISEI, Year.MAX_VALUE, 12, 31 },
+ { JapaneseEra.HEISEI, 31, 5, 1 },
+ { JapaneseEra.of(3), 1, 4, 30 },
+ { JapaneseEra.of(3), Year.MAX_VALUE, 12, 31 },
};
}
@@ -124,7 +131,10 @@
{ JapaneseEra.SHOWA, 65 },
{ JapaneseEra.HEISEI, -1 },
{ JapaneseEra.HEISEI, 0 },
- { JapaneseEra.HEISEI, Year.MAX_VALUE },
+ { JapaneseEra.HEISEI, 32 },
+ { JapaneseEra.of(3), -1 },
+ { JapaneseEra.of(3), 0 },
+ { JapaneseEra.of(3), Year.MAX_VALUE },
};
}
@@ -141,6 +151,22 @@
{ JapaneseEra.SHOWA, 64, 8 },
{ JapaneseEra.HEISEI, 1, 360 },
{ JapaneseEra.HEISEI, 2, 366 },
+ { JapaneseEra.HEISEI, 31, 121 },
+ { JapaneseEra.of(3), 1, 246 },
+ { JapaneseEra.of(3), 2, 367 },
+ };
+ }
+
+ @DataProvider
+ Object[][] eraNameData() {
+ return new Object[][] {
+ // Japanese era, name, exception
+ { "Meiji", JapaneseEra.MEIJI, null },
+ { "Taisho", JapaneseEra.TAISHO, null },
+ { "Showa", JapaneseEra.SHOWA, null },
+ { "Heisei", JapaneseEra.HEISEI, null },
+ { "Reiwa", JapaneseEra.of(3), null },
+ { "NewEra", null, IllegalArgumentException.class},
};
}
@@ -192,4 +218,13 @@
JapaneseDate date = JAPANESE.dateYearDay(era, yearOfEra, dayOfYear);
System.out.printf("No DateTimeException with era=%s, year=%d, dayOfYear=%d%n", era, yearOfEra, dayOfYear);
}
+
+ @Test(dataProvider="eraNameData")
+ public void test_eraName(String eraName, JapaneseEra era, Class expectedEx) {
+ try {
+ assertEquals(JapaneseEra.valueOf(eraName), era);
+ } catch (Exception ex) {
+ assertTrue(expectedEx.isInstance(ex));
+ }
+ }
}
diff --git a/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java b/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
index ab61c71..f86f144 100644
--- a/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
+++ b/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,6 +72,7 @@
/**
* Tests for the Umm alQura chronology and data.
* Note: The dates used for testing are just a sample of calendar data.
+ * @bug 8067800
*/
@Test
public class TestUmmAlQuraChronology {
@@ -548,6 +549,7 @@
assertFalse(HijrahChronology.INSTANCE.isLeapYear(y), "Out of range leap year");
}
+
// Date samples to convert HijrahDate to LocalDate and vice versa
@DataProvider(name="samples")
Object[][] data_samples() {
@@ -773,8 +775,10 @@
{HijrahDate.of(1350,5,15), "Japanese Showa 6-09-28"},
{HijrahDate.of(1434,5,1), "Japanese Heisei 25-03-13"},
{HijrahDate.of(1436,1,1), "Japanese Heisei 26-10-25"},
- {HijrahDate.of(1500,6,12), "Japanese Heisei 89-05-05"},
- {HijrahDate.of(1550,3,11), "Japanese Heisei 137-08-11"},
+ {HijrahDate.of(1440,8,25), "Japanese Heisei 31-04-30"},
+ {HijrahDate.of(1440,8,26), "Japanese Reiwa 1-05-01"},
+ {HijrahDate.of(1500,6,12), "Japanese Reiwa 59-05-05"},
+ {HijrahDate.of(1550,3,11), "Japanese Reiwa 107-08-11"},
};
}
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java b/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java
index 1edaba6..e2c2b4a 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -20,6 +20,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/*
+ *
+ * @test
+ * @bug 8206120
+ */
+
package test.java.time.format;
import static org.testng.Assert.assertEquals;
@@ -37,6 +44,7 @@
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.FormatStyle;
+import java.time.format.ResolverStyle;
import java.time.format.TextStyle;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
@@ -134,6 +142,19 @@
};
}
+ @DataProvider(name="lenient_eraYear")
+ Object[][] lenientEraYear() {
+ return new Object[][] {
+ // Chronology, lenient era/year, strict era/year
+ { JAPANESE, "Meiji 123", "Heisei 2" },
+ // Android-changed: Eras names have been changed in CLDR data.
+ // { JAPANESE, "Showa 65", "Heisei 2" }
+ // { JAPANESE, "Heisei 32", "NewEra 2" }, // NewEra
+ { JAPANESE, "Shōwa 65", "Heisei 2" },
+ { JAPANESE, "Heisei 32", "Qqqq 2" }, // NewEra
+ };
+ }
+
@Test(dataProvider="format_data")
public void test_formatLocalizedDate(Chronology chrono, Locale formatLocale, Locale numberingLocale,
ChronoLocalDate date, String expected) {
@@ -172,4 +193,15 @@
Chronology cal = ta.query(TemporalQueries.chronology());
assertEquals(cal, chrono);
}
+
+ @Test(dataProvider="lenient_eraYear")
+ public void test_lenientEraYear(Chronology chrono, String lenient, String strict) {
+ String mdStr = "-01-01";
+ DateTimeFormatter dtf = new DateTimeFormatterBuilder()
+ .appendPattern("GGGG y-M-d")
+ .toFormatter()
+ .withChronology(chrono);
+ DateTimeFormatter dtfLenient = dtf.withResolverStyle(ResolverStyle.LENIENT);
+ assertEquals(LocalDate.parse(lenient+mdStr, dtfLenient), LocalDate.parse(strict+mdStr, dtf));
+ }
}
diff --git a/support/src/test/java/libcore/testing/io/TestIoUtils.java b/support/src/test/java/libcore/testing/io/TestIoUtils.java
index 8e241df..34a2cf7 100644
--- a/support/src/test/java/libcore/testing/io/TestIoUtils.java
+++ b/support/src/test/java/libcore/testing/io/TestIoUtils.java
@@ -17,6 +17,10 @@
package libcore.testing.io;
import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Random;
public class TestIoUtils {
@@ -25,6 +29,13 @@
private TestIoUtils() {}
/**
+ * Returns the contents of 'path' as a string. The contents are assumed to be UTF-8.
+ */
+ public static String readFileAsString(String absolutePath) throws IOException {
+ return new String(Files.readAllBytes(Paths.get(absolutePath)), StandardCharsets.UTF_8);
+ }
+
+ /**
* Creates a unique new temporary directory under "java.io.tmpdir".
*/
public static File createTemporaryDirectory(String prefix) {