Merge "Test for android.icu.util.LocaleData"
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index c1290ff..195c251 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -512,5 +512,20 @@
*
* @param agent The path to the agent .so file plus optional agent arguments.
*/
- public static native void attachAgent(String agent) throws IOException;
+ public static void attachAgent(String agent) throws IOException {
+ attachAgent(agent, null);
+ }
+
+ /**
+ * Attaches an agent to the VM.
+ *
+ * @param agent The path to the agent .so file plus optional agent arguments.
+ * @param classLoader The classloader to use as a loading context.
+ */
+ public static void attachAgent(String agent, ClassLoader classLoader) throws IOException {
+ nativeAttachAgent(agent, classLoader);
+ }
+
+ private static native void nativeAttachAgent(String agent, ClassLoader classLoader)
+ throws IOException;
}
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index 0e2cb45..f25c78c 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -400,7 +400,7 @@
Exception syntheticException = new TimeoutException(message);
// We use the stack from where finalize() was running to show where it was stuck.
syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
- Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();
+
// Send SIGQUIT to get native stack traces.
try {
Os.kill(Os.getpid(), OsConstants.SIGQUIT);
@@ -411,15 +411,29 @@
} catch (OutOfMemoryError ignored) {
// May occur while trying to allocate the exception.
}
- if (h == null) {
+
+ // Ideally, we'd want to do this if this Thread had no handler to dispatch to.
+ // Unfortunately, it's extremely to messy to query whether a given Thread has *some*
+ // handler to dispatch to, either via a handler set on itself, via its ThreadGroup
+ // object or via the defaultUncaughtExceptionHandler.
+ //
+ // As an approximation, we log by hand an exit if there's no pre-exception handler nor
+ // a default uncaught exception handler.
+ //
+ // Note that this condition will only ever be hit by ART host tests and standalone
+ // dalvikvm invocations. All zygote forked process *will* have a pre-handler set
+ // in RuntimeInit and they cannot subsequently override it.
+ if (Thread.getUncaughtExceptionPreHandler() == null &&
+ Thread.getDefaultUncaughtExceptionHandler() == null) {
// If we have no handler, log and exit.
System.logE(message, syntheticException);
System.exit(2);
}
+
// Otherwise call the handler to do crash reporting.
// We don't just throw because we're not the thread that
// timed out; we're the thread that detected it.
- h.uncaughtException(Thread.currentThread(), syntheticException);
+ Thread.currentThread().dispatchUncaughtException(syntheticException);
}
}
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index cc24cc5..5d967dc 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -280,12 +280,7 @@
/** @hide */ public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
- libcore.util.MutableInt internalArg = new libcore.util.MutableInt(arg.value);
- try {
- return Libcore.os.ioctlInt(fd, cmd, internalArg);
- } finally {
- arg.value = internalArg.value;
- }
+ return Libcore.os.ioctlInt(fd, cmd, arg);
}
/**
@@ -472,18 +467,8 @@
/**
* See <a href="http://man7.org/linux/man-pages/man2/sendfile.2.html">sendfile(2)</a>.
*/
- public static long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref inOffset, long byteCount) throws ErrnoException {
- if (inOffset == null) {
- return Libcore.os.sendfile(outFd, inFd, null, byteCount);
- } else {
- libcore.util.MutableLong internalInOffset = new libcore.util.MutableLong(
- inOffset.value);
- try {
- return Libcore.os.sendfile(outFd, inFd, internalInOffset, byteCount);
- } finally {
- inOffset.value = internalInOffset.value;
- }
- }
+ public static long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException {
+ return Libcore.os.sendfile(outFd, inFd, offset, byteCount);
}
/**
@@ -652,16 +637,7 @@
* @throws IllegalArgumentException if {@code status != null && status.length != 1}
*/
public static int waitpid(int pid, Int32Ref status, int options) throws ErrnoException {
- if (status == null) {
- return Libcore.os.waitpid(pid, null, options);
- } else {
- libcore.util.MutableInt internalStatus = new libcore.util.MutableInt(status.value);
- try {
- return Libcore.os.waitpid(pid, internalStatus, options);
- } finally {
- status.value = internalStatus.value;
- }
- }
+ return Libcore.os.waitpid(pid, status, options);
}
/**
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index a8fa8fe..d95668a 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -18,6 +18,7 @@
import android.system.ErrnoException;
import android.system.GaiException;
+import android.system.Int64Ref;
import android.system.OsConstants;
import android.system.StructAddrinfo;
import android.system.StructLinger;
@@ -33,7 +34,6 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import libcore.util.MutableLong;
import static android.system.OsConstants.*;
@@ -289,9 +289,9 @@
os.rename(oldPath, newPath);
}
- @Override public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException {
+ @Override public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
- return os.sendfile(outFd, inFd, inOffset, byteCount);
+ return os.sendfile(outFd, inFd, offset, byteCount);
}
@Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index 3ad6f7e..98ee486 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -18,6 +18,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
+import android.system.Int32Ref;
+import android.system.Int64Ref;
import android.system.StructAddrinfo;
import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
@@ -41,8 +43,6 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import libcore.util.MutableInt;
-import libcore.util.MutableLong;
/**
* Subclass this if you want to override some {@link Os} methods but otherwise delegate.
@@ -117,7 +117,7 @@
public InetAddress inet_pton(int family, String address) { return os.inet_pton(family, address); }
public int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException { return os.ioctlFlags(fd, interfaceName); };
public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return os.ioctlInetAddress(fd, cmd, interfaceName); }
- public int ioctlInt(FileDescriptor fd, int cmd, MutableInt arg) throws ErrnoException { return os.ioctlInt(fd, cmd, arg); }
+ public int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException { return os.ioctlInt(fd, cmd, arg); }
public int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException { return os.ioctlMTU(fd, interfaceName); };
public boolean isatty(FileDescriptor fd) { return os.isatty(fd); }
public void kill(int pid, int signal) throws ErrnoException { os.kill(pid, signal); }
@@ -154,7 +154,7 @@
public void remove(String path) throws ErrnoException { os.remove(path); }
public void removexattr(String path, String name) throws ErrnoException { os.removexattr(path, name); }
public void rename(String oldPath, String newPath) throws ErrnoException { os.rename(oldPath, newPath); }
- public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException { return os.sendfile(outFd, inFd, inOffset, byteCount); }
+ public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException { return os.sendfile(outFd, inFd, offset, byteCount); }
public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, buffer, flags, inetAddress, port); }
public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); }
public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
@@ -191,7 +191,7 @@
public StructUtsname uname() { return os.uname(); }
public void unlink(String pathname) throws ErrnoException { os.unlink(pathname); }
public void unsetenv(String name) throws ErrnoException { os.unsetenv(name); }
- public int waitpid(int pid, MutableInt status, int options) throws ErrnoException { return os.waitpid(pid, status, options); }
+ public int waitpid(int pid, Int32Ref status, int options) throws ErrnoException { return os.waitpid(pid, status, options); }
public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return os.write(fd, buffer); }
public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return os.write(fd, bytes, byteOffset, byteCount); }
public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return os.writev(fd, buffers, offsets, byteCounts); }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index a67a7c5..a950bf5 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -17,6 +17,7 @@
package libcore.io;
import android.system.ErrnoException;
+import android.system.Int32Ref;
import android.system.StructGroupReq;
import android.system.StructLinger;
import android.system.StructPollfd;
@@ -42,7 +43,6 @@
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
-import libcore.util.MutableInt;
import static android.system.OsConstants.*;
@@ -56,7 +56,7 @@
public static int available(FileDescriptor fd) throws IOException {
try {
- MutableInt available = new MutableInt(0);
+ Int32Ref available = new Int32Ref(0);
Libcore.os.ioctlInt(fd, FIONREAD, available);
if (available.value < 0) {
// If the fd refers to a regular file, the result is the difference between
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
index 2fad632..36244f5 100644
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -18,6 +18,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
+import android.system.Int32Ref;
+import android.system.Int64Ref;
import android.system.StructAddrinfo;
import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
@@ -42,8 +44,6 @@
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.NioUtils;
-import libcore.util.MutableInt;
-import libcore.util.MutableLong;
public final class Linux implements Os {
Linux() { }
@@ -108,7 +108,7 @@
public native InetAddress inet_pton(int family, String address);
public native int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException;
public native InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException;
- public native int ioctlInt(FileDescriptor fd, int cmd, MutableInt arg) throws ErrnoException;
+ public native int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException;
public native int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException;
public native boolean isatty(FileDescriptor fd);
public native void kill(int pid, int signal) throws ErrnoException;
@@ -209,7 +209,7 @@
public native void remove(String path) throws ErrnoException;
public native void removexattr(String path, String name) throws ErrnoException;
public native void rename(String oldPath, String newPath) throws ErrnoException;
- public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException;
+ public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException;
public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
final int bytesSent;
final int position = buffer.position();
@@ -271,7 +271,7 @@
public native StructUtsname uname();
public native void unlink(String pathname) throws ErrnoException;
public native void unsetenv(String name) throws ErrnoException;
- public native int waitpid(int pid, MutableInt status, int options) throws ErrnoException;
+ public native int waitpid(int pid, Int32Ref status, int options) throws ErrnoException;
public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
final int bytesWritten;
final int position = buffer.position();
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index f7ca995..fffc479 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -18,6 +18,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
+import android.system.Int32Ref;
+import android.system.Int64Ref;
import android.system.StructAddrinfo;
import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
@@ -41,8 +43,6 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import libcore.util.MutableInt;
-import libcore.util.MutableLong;
public interface Os {
public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
@@ -106,7 +106,7 @@
public InetAddress inet_pton(int family, String address);
public int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException;
public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException;
- public int ioctlInt(FileDescriptor fd, int cmd, MutableInt arg) throws ErrnoException;
+ public int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException;
public int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException;
public boolean isatty(FileDescriptor fd);
public void kill(int pid, int signal) throws ErrnoException;
@@ -147,7 +147,7 @@
public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException;
public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException;
public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException;
- public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException;
+ public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException;
public void setegid(int egid) throws ErrnoException;
public void setenv(String name, String value, boolean overwrite) throws ErrnoException;
public void seteuid(int euid) throws ErrnoException;
@@ -181,7 +181,7 @@
public StructUtsname uname();
public void unlink(String pathname) throws ErrnoException;
public void unsetenv(String name) throws ErrnoException;
- public int waitpid(int pid, MutableInt status, int options) throws ErrnoException;
+ public int waitpid(int pid, Int32Ref status, int options) throws ErrnoException;
public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException;
public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException;
public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index 693b6da..3ab4300 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -114,6 +114,7 @@
add("application/vnd.sun.xml.writer.global", "sxg");
add("application/vnd.sun.xml.writer.template", "stw");
add("application/vnd.visio", "vsd");
+ add("application/vnd.youtube.yt", "yt");
add("application/x-abiword", "abw");
add("application/x-apple-diskimage", "dmg");
add("application/x-bcpio", "bcpio");
diff --git a/luni/src/main/java/libcore/util/CountryTimeZones.java b/luni/src/main/java/libcore/util/CountryTimeZones.java
new file mode 100644
index 0000000..f190278
--- /dev/null
+++ b/luni/src/main/java/libcore/util/CountryTimeZones.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2017 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.util;
+
+import android.icu.util.TimeZone;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Information about a country's time zones.
+ */
+public class CountryTimeZones {
+ private final String countryIso;
+ private final String defaultTimeZoneId;
+ private final List<String> timeZoneIds;
+
+ // Memoized frozen ICU TimeZone object for the default.
+ private TimeZone icuDefaultTimeZone;
+ // Memoized frozen ICU TimeZone objects for the timeZoneIds.
+ private List<TimeZone> icuTimeZones;
+
+ private CountryTimeZones(String countryIso, String defaultTimeZoneId,
+ List<String> timeZoneIds) {
+ this.countryIso = countryIso;
+ this.defaultTimeZoneId = defaultTimeZoneId;
+ // Create a defensive copy of the IDs list.
+ this.timeZoneIds = Collections.unmodifiableList(new ArrayList<>(timeZoneIds));
+ }
+
+ /**
+ * Creates a {@link CountryTimeZones} object containing only known time zone IDs.
+ */
+ public static CountryTimeZones createValidated(String countryIso, String defaultTimeZoneId,
+ List<String> countryTimeZoneIds, String debugInfo) {
+
+ // We rely on ZoneInfoDB to tell us what the known valid time zone IDs are. ICU may
+ // recognize more but we want to be sure that zone IDs can be used with java.util as well as
+ // android.icu and ICU is expected to have a superset.
+ String[] validTimeZoneIdsArray = ZoneInfoDB.getInstance().getAvailableIDs();
+ HashSet<String> validTimeZoneIdsSet = new HashSet<>(Arrays.asList(validTimeZoneIdsArray));
+ List<String> validCountryTimeZoneIds = new ArrayList<>();
+ for (String countryTimeZoneId : countryTimeZoneIds) {
+ if (!validTimeZoneIdsSet.contains(countryTimeZoneId)) {
+ System.logW("Skipping invalid zone: " + countryTimeZoneId + " at " + debugInfo);
+ } else {
+ validCountryTimeZoneIds.add(countryTimeZoneId);
+ }
+ }
+
+ // We don't get too strict at runtime about whether the defaultTimeZoneId must be
+ // one of the country's time zones because this is the data we have to use (we also
+ // assume the data was validated by earlier steps). The default time zone ID must just
+ // be a recognized zone ID: if it's not valid we leave it null.
+ if (!validTimeZoneIdsSet.contains(defaultTimeZoneId)) {
+ System.logW("Invalid default time zone ID: " + defaultTimeZoneId
+ + " at " + debugInfo);
+ defaultTimeZoneId = null;
+ }
+
+ return new CountryTimeZones(countryIso, defaultTimeZoneId, validCountryTimeZoneIds);
+ }
+
+ /**
+ * Returns the ISO code for the country.
+ */
+ public String getCountryIso() {
+ return countryIso;
+ }
+
+ /**
+ * Returns the default time zone ID for the country. Can return null in cases when no data is
+ * available or the time zone ID provided to
+ * {@link #createValidated(String, String, List, String)} was not recognized.
+ */
+ public synchronized TimeZone getDefaultTimeZone() {
+ if (icuDefaultTimeZone == null) {
+ TimeZone defaultTimeZone;
+ if (defaultTimeZoneId == null) {
+ defaultTimeZone = null;
+ } else {
+ defaultTimeZone = getValidFrozenTimeZoneOrNull(defaultTimeZoneId);
+ }
+ icuDefaultTimeZone = defaultTimeZone;
+ }
+ return icuDefaultTimeZone;
+ }
+
+ /**
+ * Returns the default time zone ID for the country. Can return null in cases when no data is
+ * available or the time zone ID provided to
+ * {@link #createValidated(String, String, List, String)} was not recognized.
+ */
+ public String getDefaultTimeZoneId() {
+ return defaultTimeZoneId;
+ }
+
+ /**
+ * Returns an ordered list of time zone IDs for the country in an undefined but "priority"
+ * order for a country. The list can be empty if there were no zones configured or the
+ * configured zone IDs were not recognized.
+ */
+ public List<String> getTimeZoneIds() {
+ return timeZoneIds;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ CountryTimeZones that = (CountryTimeZones) o;
+
+ if (!countryIso.equals(that.countryIso)) {
+ return false;
+ }
+ if (defaultTimeZoneId != null ? !defaultTimeZoneId.equals(that.defaultTimeZoneId)
+ : that.defaultTimeZoneId != null) {
+ return false;
+ }
+ return timeZoneIds.equals(that.timeZoneIds);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = countryIso.hashCode();
+ result = 31 * result + (defaultTimeZoneId != null ? defaultTimeZoneId.hashCode() : 0);
+ result = 31 * result + timeZoneIds.hashCode();
+ return result;
+ }
+
+ /**
+ * Returns an ordered list of time zones for the country in an undefined but "priority"
+ * order for a country. The list can be empty if there were no zones configured or the
+ * configured zone IDs were not recognized.
+ */
+ public synchronized List<TimeZone> getIcuTimeZones() {
+ if (icuTimeZones == null) {
+ ArrayList<TimeZone> mutableList = new ArrayList<>(timeZoneIds.size());
+ for (String timeZoneId : timeZoneIds) {
+ TimeZone timeZone;
+ if (timeZoneId.equals(defaultTimeZoneId)) {
+ timeZone = getDefaultTimeZone();
+ } else {
+ timeZone = getValidFrozenTimeZoneOrNull(timeZoneId);
+ }
+ // This shouldn't happen given the validation that takes place in
+ // createValidatedCountryTimeZones().
+ if (timeZone == null) {
+ System.logW("Skipping invalid zone: " + timeZoneId);
+ continue;
+ }
+ mutableList.add(timeZone);
+ }
+ icuTimeZones = Collections.unmodifiableList(mutableList);
+ }
+ return icuTimeZones;
+ }
+
+ /**
+ * Returns true if the country has at least one zone that is the same as UTC at the given time.
+ */
+ public boolean hasUtcZone(long whenMillis) {
+ for (TimeZone zone : getIcuTimeZones()) {
+ if (zone.getOffset(whenMillis) == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code true} if the default time zone for the country is either the only zone used or
+ * if it has the same offsets as all other zones used by the country <em>at the specified time
+ * </em> making the default equivalent to all other zones used by the country <em>at that time
+ * </em>.
+ */
+ public boolean isDefaultOkForCountryTimeZoneDetection(long whenMillis) {
+ List<TimeZone> candidates = getIcuTimeZones();
+ if (candidates.isEmpty()) {
+ // Should never happen unless there's been an error loading the data.
+ return false;
+ } else if (candidates.size() == 1) {
+ // The default is the only zone so it's a good candidate.
+ return true;
+ } else {
+ TimeZone countryDefault = getDefaultTimeZone();
+ if (countryDefault == null) {
+ return false;
+ }
+
+ int countryDefaultOffset = countryDefault.getOffset(whenMillis);
+ for (TimeZone candidate : candidates) {
+ if (candidate == countryDefault) {
+ continue;
+ }
+
+ int candidateOffset = candidate.getOffset(whenMillis);
+ if (countryDefaultOffset != candidateOffset) {
+ // Multiple different offsets means the default should not be used.
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Returns a time zone for the country, if there is one, that has the desired properties. If
+ * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
+ * an arbitrary match is returned based on the {@link #getTimeZoneIds()} ordering.
+ *
+ * @param offsetSeconds the offset from UTC at {@code whenMillis}
+ * @param isDst whether the zone is in DST
+ * @param whenMillis the UTC time to match against
+ * @param bias the time zone to prefer, can be null
+ */
+ public TimeZone lookupByOffsetWithBias(int offsetSeconds, boolean isDst, long whenMillis,
+ TimeZone bias) {
+ if (timeZoneIds == null || timeZoneIds.isEmpty()) {
+ return null;
+ }
+
+ List<TimeZone> candidates = getIcuTimeZones();
+ TimeZone firstMatch = null;
+ for (TimeZone match : candidates) {
+ if (!offsetMatchesAtTime(match, offsetSeconds, isDst, whenMillis)) {
+ continue;
+ }
+
+ if (firstMatch == null) {
+ if (bias == null) {
+ // No bias, so we can stop at the first match.
+ return match;
+ }
+ // We have to carry on checking in case the bias matches. We want to return the
+ // first if it doesn't, though.
+ firstMatch = match;
+ }
+
+ // Check if match is also the bias. There must be a bias otherwise we'd have terminated
+ // already.
+ if (match.getID().equals(bias.getID())) {
+ return match;
+ }
+ }
+ // Return firstMatch, which can be null if there was no match.
+ return firstMatch;
+ }
+
+ /**
+ * Returns {@code true} if the specified offset, DST state and time would be valid in the
+ * timeZone.
+ */
+ private static boolean offsetMatchesAtTime(TimeZone timeZone, int offsetMillis, boolean isDst,
+ long whenMillis) {
+ int[] offsets = new int[2];
+ timeZone.getOffset(whenMillis, false /* local */, offsets);
+
+ // offsets[1] == 0 when the zone is not in DST.
+ boolean zoneIsDst = offsets[1] != 0;
+ if (isDst != zoneIsDst) {
+ return false;
+ }
+ return offsetMillis == (offsets[0] + offsets[1]);
+ }
+
+ private static TimeZone getValidFrozenTimeZoneOrNull(String timeZoneId) {
+ TimeZone timeZone = TimeZone.getFrozenTimeZone(timeZoneId);
+ if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
+ return null;
+ }
+ return timeZone;
+ }
+}
diff --git a/luni/src/main/java/libcore/util/MutableInt.java b/luni/src/main/java/libcore/util/MutableInt.java
deleted file mode 100644
index 739a04b..0000000
--- a/luni/src/main/java/libcore/util/MutableInt.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.util;
-
-/**
- * Libcore-internal version of {@code android.util.MutableInt}. Code outside libcore
- * should use that class instead.
- * @hide
- */
-public class MutableInt {
- public int value;
-
- public MutableInt(int value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableLong.java b/luni/src/main/java/libcore/util/MutableLong.java
deleted file mode 100644
index 7725df4..0000000
--- a/luni/src/main/java/libcore/util/MutableLong.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.util;
-
-/**
- * Libcore-internal version of {@code android.util.MutableLong}. Code outside libcore
- * should use that class instead.
- * @hide
- */
-public class MutableLong {
- public long value;
-
- public MutableLong(long value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/TimeZoneFinder.java b/luni/src/main/java/libcore/util/TimeZoneFinder.java
index fa15086..98af74a 100644
--- a/luni/src/main/java/libcore/util/TimeZoneFinder.java
+++ b/luni/src/main/java/libcore/util/TimeZoneFinder.java
@@ -172,53 +172,11 @@
public TimeZone lookupTimeZoneByCountryAndOffset(
String countryIso, int offsetSeconds, boolean isDst, long whenMillis, TimeZone bias) {
- countryIso = normalizeCountryIso(countryIso);
- List<TimeZone> candidates = lookupTimeZonesByCountry(countryIso);
- if (candidates == null || candidates.isEmpty()) {
+ CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
+ if (countryTimeZones == null) {
return null;
}
-
- TimeZone firstMatch = null;
- for (TimeZone match : candidates) {
- if (!offsetMatchesAtTime(match, offsetSeconds, isDst, whenMillis)) {
- continue;
- }
-
- if (firstMatch == null) {
- if (bias == null) {
- // No bias, so we can stop at the first match.
- return match;
- }
- // We have to carry on checking in case the bias matches. We want to return the
- // first if it doesn't, though.
- firstMatch = match;
- }
-
- // Check if match is also the bias. There must be a bias otherwise we'd have terminated
- // already.
- if (match.getID().equals(bias.getID())) {
- return match;
- }
- }
- // Return firstMatch, which can be null if there was no match.
- return firstMatch;
- }
-
- /**
- * Returns {@code true} if the specified offset, DST state and time would be valid in the
- * timeZone.
- */
- private static boolean offsetMatchesAtTime(TimeZone timeZone, int offsetMillis, boolean isDst,
- long whenMillis) {
- int[] offsets = new int[2];
- timeZone.getOffset(whenMillis, false /* local */, offsets);
-
- // offsets[1] == 0 when the zone is not in DST.
- boolean zoneIsDst = offsets[1] != 0;
- if (isDst != zoneIsDst) {
- return false;
- }
- return offsetMillis == (offsets[0] + offsets[1]);
+ return countryTimeZones.lookupByOffsetWithBias(offsetSeconds, isDst, whenMillis, bias);
}
/**
@@ -231,8 +189,7 @@
* null.
*/
public String lookupDefaultTimeZoneIdByCountry(String countryIso) {
- countryIso = normalizeCountryIso(countryIso);
- CountryTimeZones countryTimeZones = findCountryTimeZones(countryIso);
+ CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
return countryTimeZones == null ? null : countryTimeZones.getDefaultTimeZoneId();
}
@@ -244,9 +201,8 @@
* zone IDs.
*/
public List<TimeZone> lookupTimeZonesByCountry(String countryIso) {
- countryIso = normalizeCountryIso(countryIso);
- CountryTimeZones countryTimeZones = findCountryTimeZones(countryIso);
- return countryTimeZones == null ? null : countryTimeZones.getTimeZones();
+ CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
+ return countryTimeZones == null ? null : countryTimeZones.getIcuTimeZones();
}
/**
@@ -258,17 +214,17 @@
* in a case when the underlying data files reference only unknown zone IDs.
*/
public List<String> lookupTimeZoneIdsByCountry(String countryIso) {
- countryIso = normalizeCountryIso(countryIso);
- CountryTimeZones countryTimeZones = findCountryTimeZones(countryIso);
+ CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
return countryTimeZones == null ? null : countryTimeZones.getTimeZoneIds();
}
/**
* Returns a {@link CountryTimeZones} object associated with the specified country code.
* Caching is handled as needed. If the country code is not recognized or there is an error
- * during lookup this can return null.
+ * during lookup this method can return null.
*/
- private CountryTimeZones findCountryTimeZones(String countryIso) {
+ public CountryTimeZones lookupCountryTimeZones(String countryIso) {
+ countryIso = normalizeCountryIso(countryIso);
synchronized (this) {
if (lastCountryTimeZones != null
&& lastCountryTimeZones.getCountryIso().equals(countryIso)) {
@@ -623,7 +579,7 @@
if (!countryCodeToMatch.equals(countryIso)) {
return CONTINUE;
}
- validatedCountryTimeZones = createValidatedCountryTimeZones(countryIso,
+ validatedCountryTimeZones = CountryTimeZones.createValidated(countryIso,
defaultTimeZoneId, countryTimeZoneIds, debugInfo);
return HALT;
@@ -632,7 +588,7 @@
/**
* Returns the CountryTimeZones that matched, or {@code null} if there were no matches.
*/
- CountryTimeZones getValidatedCountryTimeZones() {
+ private CountryTimeZones getValidatedCountryTimeZones() {
return validatedCountryTimeZones;
}
}
@@ -660,113 +616,9 @@
}
}
- /**
- * Information about a country's time zones.
- */
- // VisibleForTesting
- public static class CountryTimeZones {
- private final String countryIso;
- private final String defaultTimeZoneId;
- private final List<String> timeZoneIds;
-
- // Memoized frozen ICU TimeZone objects for the timeZoneIds.
- private List<TimeZone> timeZones;
-
- public CountryTimeZones(String countryIso, String defaultTimeZoneId,
- List<String> timeZoneIds) {
- this.countryIso = countryIso;
- this.defaultTimeZoneId = defaultTimeZoneId;
- // Create a defensive copy of the IDs list.
- this.timeZoneIds = Collections.unmodifiableList(new ArrayList<>(timeZoneIds));
- }
-
- public String getCountryIso() {
- return countryIso;
- }
-
- /**
- * Returns the default time zone ID for a country. Can return null in extreme cases when
- * invalid data is found.
- */
- public String getDefaultTimeZoneId() {
- return defaultTimeZoneId;
- }
-
- /**
- * Returns an ordered list of time zone IDs for a country in an undefined but "priority"
- * order for a country. The list can be empty if there were no zones configured or the
- * configured zone IDs were not recognized.
- */
- public List<String> getTimeZoneIds() {
- return timeZoneIds;
- }
-
- /**
- * Returns an ordered list of time zones for a country in an undefined but "priority"
- * order for a country. The list can be empty if there were no zones configured or the
- * configured zone IDs were not recognized.
- */
- public synchronized List<TimeZone> getTimeZones() {
- if (timeZones == null) {
- ArrayList<TimeZone> mutableList = new ArrayList<>(timeZoneIds.size());
- for (String timeZoneId : timeZoneIds) {
- TimeZone timeZone = getValidFrozenTimeZoneOrNull(timeZoneId);
- // This shouldn't happen given the validation that takes place in
- // createValidatedCountryTimeZones().
- if (timeZone == null) {
- System.logW("Skipping invalid zone: " + timeZoneId);
- continue;
- }
- mutableList.add(timeZone);
- }
- timeZones = Collections.unmodifiableList(mutableList);
- }
- return timeZones;
- }
-
- private static TimeZone getValidFrozenTimeZoneOrNull(String timeZoneId) {
- TimeZone timeZone = TimeZone.getFrozenTimeZone(timeZoneId);
- if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
- return null;
- }
- return timeZone;
- }
- }
-
private static String normalizeCountryIso(String countryIso) {
// Lowercase ASCII is normalized for the purposes of the input files and the code in this
// class.
return countryIso.toLowerCase(Locale.US);
}
-
- // VisibleForTesting
- public static CountryTimeZones createValidatedCountryTimeZones(String countryIso,
- String defaultTimeZoneId, List<String> countryTimeZoneIds, String debugInfo) {
-
- // We rely on ZoneInfoDB to tell us what the known valid time zone IDs are. ICU may
- // recognize more but we want to be sure that zone IDs can be used with java.util as well as
- // android.icu and ICU is expected to have a superset.
- String[] validTimeZoneIdsArray = ZoneInfoDB.getInstance().getAvailableIDs();
- HashSet<String> validTimeZoneIdsSet = new HashSet<>(Arrays.asList(validTimeZoneIdsArray));
- List<String> validCountryTimeZoneIds = new ArrayList<>();
- for (String countryTimeZoneId : countryTimeZoneIds) {
- if (!validTimeZoneIdsSet.contains(countryTimeZoneId)) {
- System.logW("Skipping invalid zone: " + countryTimeZoneId + " at " + debugInfo);
- } else {
- validCountryTimeZoneIds.add(countryTimeZoneId);
- }
- }
-
- // We don't get too strict at runtime about whether the defaultTimeZoneId must be
- // one of the country's time zones because this is the data we have to use (we also
- // assume the data was validated by earlier steps). The default time zone ID must just
- // be a recognized zone ID: if it's not valid we leave it null.
- if (!validTimeZoneIdsSet.contains(defaultTimeZoneId)) {
- System.logW("Invalid default time zone ID: " + defaultTimeZoneId
- + " at " + debugInfo);
- defaultTimeZoneId = null;
- }
-
- return new CountryTimeZones(countryIso, defaultTimeZoneId, validCountryTimeZoneIds);
- }
}
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index 15d8c70..9fa06a3 100644
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -78,8 +78,8 @@
namespace {
-jfieldID mutableIntValueFid;
-jfieldID mutableLongValueFid;
+jfieldID int32RefValueFid;
+jfieldID int64RefValueFid;
} // namespace
@@ -1695,10 +1695,10 @@
// This is complicated because ioctls may return their result by updating their argument
// or via their return value, so we need to support both.
int fd = jniGetFDFromFileDescriptor(env, javaFd);
- jint arg = env->GetIntField(javaArg, mutableIntValueFid);
+ jint arg = env->GetIntField(javaArg, int32RefValueFid);
int rc = throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, cmd, &arg)));
if (!env->ExceptionCheck()) {
- env->SetIntField(javaArg, mutableIntValueFid, arg);
+ env->SetIntField(javaArg, int32RefValueFid, arg);
}
return rc;
}
@@ -2106,7 +2106,7 @@
off_t* offsetPtr = NULL;
if (javaOffset != NULL) {
// TODO: fix bionic so we can have a 64-bit off_t!
- offset = env->GetLongField(javaOffset, mutableLongValueFid);
+ offset = env->GetLongField(javaOffset, int64RefValueFid);
offsetPtr = &offset;
}
jlong result = throwIfMinusOne(env, "sendfile", TEMP_FAILURE_RETRY(sendfile(outFd, inFd, offsetPtr, byteCount)));
@@ -2114,7 +2114,7 @@
return -1;
}
if (javaOffset != NULL) {
- env->SetLongField(javaOffset, mutableLongValueFid, offset);
+ env->SetLongField(javaOffset, int64RefValueFid, offset);
}
return result;
}
@@ -2422,7 +2422,7 @@
int status;
int rc = throwIfMinusOne(env, "waitpid", TEMP_FAILURE_RETRY(waitpid(pid, &status, options)));
if (rc != -1) {
- env->SetIntField(javaStatus, mutableIntValueFid, status);
+ env->SetIntField(javaStatus, int32RefValueFid, status);
}
return rc;
}
@@ -2506,7 +2506,7 @@
NATIVE_METHOD(Linux, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
NATIVE_METHOD(Linux, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
NATIVE_METHOD(Linux, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
- NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;ILlibcore/util/MutableInt;)I"),
+ NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/system/Int32Ref;)I"),
NATIVE_METHOD(Linux, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
NATIVE_METHOD(Linux, isatty, "(Ljava/io/FileDescriptor;)Z"),
NATIVE_METHOD(Linux, kill, "(II)V"),
@@ -2539,7 +2539,7 @@
NATIVE_METHOD(Linux, remove, "(Ljava/lang/String;)V"),
NATIVE_METHOD(Linux, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
NATIVE_METHOD(Linux, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
- NATIVE_METHOD(Linux, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Llibcore/util/MutableLong;J)J"),
+ NATIVE_METHOD(Linux, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/system/Int64Ref;J)J"),
NATIVE_METHOD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
NATIVE_METHOD_OVERLOAD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
NATIVE_METHOD(Linux, setegid, "(I)V"),
@@ -2575,22 +2575,22 @@
NATIVE_METHOD(Linux, uname, "()Landroid/system/StructUtsname;"),
NATIVE_METHOD(Linux, unlink, "(Ljava/lang/String;)V"),
NATIVE_METHOD(Linux, unsetenv, "(Ljava/lang/String;)V"),
- NATIVE_METHOD(Linux, waitpid, "(ILlibcore/util/MutableInt;I)I"),
+ NATIVE_METHOD(Linux, waitpid, "(ILandroid/system/Int32Ref;I)I"),
NATIVE_METHOD(Linux, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
NATIVE_METHOD(Linux, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
};
void register_libcore_io_Linux(JNIEnv* env) {
// Note: it is safe to only cache the fields as boot classpath classes are never
// unloaded.
- ScopedLocalRef<jclass> mutableIntClass(env, env->FindClass("libcore/util/MutableInt"));
- CHECK(mutableIntClass != nullptr);
- mutableIntValueFid = env->GetFieldID(mutableIntClass.get(), "value", "I");
- CHECK(mutableIntValueFid != nullptr);
+ ScopedLocalRef<jclass> int32RefClass(env, env->FindClass("android/system/Int32Ref"));
+ CHECK(int32RefClass != nullptr);
+ int32RefValueFid = env->GetFieldID(int32RefClass.get(), "value", "I");
+ CHECK(int32RefValueFid != nullptr);
- ScopedLocalRef<jclass> mutableLongClass(env, env->FindClass("libcore/util/MutableLong"));
- CHECK(mutableLongClass != nullptr);
- mutableLongValueFid = env->GetFieldID(mutableLongClass.get(), "value", "J");
- CHECK(mutableLongValueFid != nullptr);
+ ScopedLocalRef<jclass> int64RefClass(env, env->FindClass("android/system/Int64Ref"));
+ CHECK(int64RefClass != nullptr);
+ int64RefValueFid = env->GetFieldID(int64RefClass.get(), "value", "J");
+ CHECK(int64RefValueFid != nullptr);
jniRegisterNativeMethods(env, "libcore/io/Linux", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/test/java/libcore/java/util/TreeMapTest.java b/luni/src/test/java/libcore/java/util/TreeMapTest.java
index 7c98ecd..cdb9699 100644
--- a/luni/src/test/java/libcore/java/util/TreeMapTest.java
+++ b/luni/src/test/java/libcore/java/util/TreeMapTest.java
@@ -614,33 +614,6 @@
return bound == '[' || bound == '(';
}
- // http://b//26336181
- //
- // Note that this is only worth working around because these bogus comparators worked
- // somewhat-fine on M and below provided that :
- //
- // (1) put was called with distinct elements (i.e, with no two elements equal() to each other)
- // (2) get or get-like methods are never called
- //
- // These comparators are clearly bogus but are somewhat common.
- public void testTreeMapWithBogusComparator() {
- TreeMap<String, String> treeMap = new TreeMap<String, String>(
- new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- if (o1.equals(o2)) {
- throw new IllegalArgumentException("Expected unequal elements");
- }
-
- return o1.compareTo(o2);
- }
- }
- );
-
- treeMap.put("candy", "floss");
- treeMap.put("cheddar", "cheese");
- }
-
public void test_spliterator_keySet() {
TreeMap<String, String> treeMap = new TreeMap<>();
// Elements are added out of order to ensure ordering is still preserved.
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
index d287b97..5e174bd 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
@@ -15,10 +15,16 @@
*/
package libcore.javax.crypto.spec;
+import java.security.KeyFactory;
import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import tests.security.CipherAsymmetricCryptHelper;
+import tests.security.DefaultKeys;
import tests.security.KeyFactoryTest;
public class KeyFactoryTestRSA extends
@@ -33,4 +39,20 @@
protected void check(KeyPair keyPair) throws Exception {
new CipherAsymmetricCryptHelper("RSA").test(keyPair);
}
+
+ public void testExtraBufferSpace_Private() throws Exception {
+ PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+ byte[] encoded = privateKey.getEncoded();
+ byte[] longBuffer = new byte[encoded.length + 147];
+ System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
+ KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
+ }
+
+ public void testExtraBufferSpace_Public() throws Exception {
+ PublicKey publicKey = DefaultKeys.getPublicKey("RSA");
+ byte[] encoded = publicKey.getEncoded();
+ byte[] longBuffer = new byte[encoded.length + 147];
+ System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
+ KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(longBuffer));
+ }
}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/HttpsURLConnectionTest.java b/luni/src/test/java/libcore/javax/net/ssl/HttpsURLConnectionTest.java
deleted file mode 100644
index cbaea20..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/HttpsURLConnectionTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2014 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.javax.net.ssl;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.net.URL;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocketFactory;
-
-public class HttpsURLConnectionTest extends TestCase {
-
- /**
- * HTTPS URL which cannot be resolved and is thus safe to use in tests where network traffic
- * should be avoided.
- */
- private static final String UNRESOLVABLE_HTTPS_URL = "https:///";
-
- public void testDefaultHostnameVerifierNotNull() {
- assertNotNull(HttpsURLConnection.getDefaultHostnameVerifier());
- }
-
- public void testDefaultHostnameVerifierUsedForNewConnectionsByDefault() throws IOException {
- HostnameVerifier originalHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
- HttpsURLConnection connection =
- (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
- try {
- assertSame(originalHostnameVerifier, connection.getHostnameVerifier());
- } finally {
- connection.disconnect();
- }
-
- HostnameVerifier anotherVerifier = new FakeHostnameVerifier();
- try {
- HttpsURLConnection.setDefaultHostnameVerifier(anotherVerifier);
- connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
- try {
- assertSame(anotherVerifier, connection.getHostnameVerifier());
- } finally {
- connection.disconnect();
- }
-
- HttpsURLConnection.setDefaultHostnameVerifier(originalHostnameVerifier);
- connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
- try {
- assertSame(originalHostnameVerifier, connection.getHostnameVerifier());
- } finally {
- connection.disconnect();
- }
- } finally {
- HttpsURLConnection.setDefaultHostnameVerifier(originalHostnameVerifier);
- }
- }
-
- public void testDefaultSSLSocketFactoryNotNull() {
- assertNotNull(HttpsURLConnection.getDefaultSSLSocketFactory());
- }
-
- public void testDefaultSSLSocketFactoryUsedForNewConnectionsByDefault() throws IOException {
- SSLSocketFactory originalFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
- HttpsURLConnection connection =
- (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
- try {
- assertSame(originalFactory, connection.getSSLSocketFactory());
- } finally {
- connection.disconnect();
- }
-
- SSLSocketFactory anotherFactory = new SSLSocketFactoryTest.FakeSSLSocketFactory();
- try {
- HttpsURLConnection.setDefaultSSLSocketFactory(anotherFactory);
- connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
- try {
- assertSame(anotherFactory, connection.getSSLSocketFactory());
- } finally {
- connection.disconnect();
- }
-
- HttpsURLConnection.setDefaultSSLSocketFactory(originalFactory);
- connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
- try {
- assertSame(originalFactory, connection.getSSLSocketFactory());
- } finally {
- connection.disconnect();
- }
- } finally {
- HttpsURLConnection.setDefaultSSLSocketFactory(originalFactory);
- }
- }
-
- private static class FakeHostnameVerifier implements HostnameVerifier {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- return true;
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
deleted file mode 100644
index cd693c9..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore.Builder;
-import java.security.KeyStore.PasswordProtection;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Set;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.KeyStoreBuilderParameters;
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509KeyManager;
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-
-public class KeyManagerFactoryTest extends TestCase {
-
- private TestKeyStore testKeyStore;
-
- @Override
- protected void setUp() throws Exception {
- // note the rare usage of DSA keys here in addition to RSA
- testKeyStore = new TestKeyStore.Builder()
- .keyAlgorithms("RSA", "DH_RSA", "DSA", "DH_DSA", "EC", "EC_RSA")
- .aliasPrefix("rsa-dsa-ec-dh")
- .build();
- }
-
- private TestKeyStore getTestKeyStore() throws Exception {
- return testKeyStore;
- }
-
- public void test_KeyManagerFactory_getDefaultAlgorithm() throws Exception {
- String algorithm = KeyManagerFactory.getDefaultAlgorithm();
- assertEquals(StandardNames.KEY_MANAGER_FACTORY_DEFAULT, algorithm);
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
- test_KeyManagerFactory(kmf);
- }
-
- private static class UselessManagerFactoryParameters implements ManagerFactoryParameters {}
-
- private static boolean supportsManagerFactoryParameters(String algorithm) {
- // Only the "New" one supports ManagerFactoryParameters
- return algorithm.equals("NewSunX509");
- }
-
- private static String[] keyTypes(String algorithm) {
- // Although the "New" one supports ManagerFactoryParameters,
- // it can't handle nulls in the key types array.
- return (algorithm.equals("NewSunX509")
- ? KEY_TYPES_WITH_EMPTY
- : KEY_TYPES_WITH_EMPTY_AND_NULL);
- }
-
- private void test_KeyManagerFactory(KeyManagerFactory kmf) throws Exception {
- assertNotNull(kmf);
- assertNotNull(kmf.getAlgorithm());
- assertNotNull(kmf.getProvider());
-
- // before init
- try {
- kmf.getKeyManagers();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- // init with null ManagerFactoryParameters
- try {
- kmf.init(null);
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
-
- // init with useless ManagerFactoryParameters
- try {
- kmf.init(new UselessManagerFactoryParameters());
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
-
- // init with KeyStoreBuilderParameters ManagerFactoryParameters
- PasswordProtection pp = new PasswordProtection(getTestKeyStore().storePassword);
- Builder builder = Builder.newInstance(getTestKeyStore().keyStore, pp);
- KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(builder);
- if (supportsManagerFactoryParameters(kmf.getAlgorithm())) {
- kmf.init(ksbp);
- test_KeyManagerFactory_getKeyManagers(kmf, false);
- } else {
- try {
- kmf.init(ksbp);
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
- }
-
- // init with null for default behavior
- kmf.init(null, null);
- test_KeyManagerFactory_getKeyManagers(kmf, true);
-
- // init with specific key store and password
- kmf.init(getTestKeyStore().keyStore, getTestKeyStore().storePassword);
- test_KeyManagerFactory_getKeyManagers(kmf, false);
- }
-
- private void test_KeyManagerFactory_getKeyManagers(KeyManagerFactory kmf, boolean empty)
- throws Exception {
- KeyManager[] keyManagers = kmf.getKeyManagers();
- assertNotNull(keyManagers);
- assertTrue(keyManagers.length > 0);
- for (KeyManager keyManager : keyManagers) {
- assertNotNull(keyManager);
- if (keyManager instanceof X509KeyManager) {
- test_X509KeyManager((X509KeyManager) keyManager, empty, kmf.getAlgorithm());
- }
- }
- }
-
- private static final String[] KEY_TYPES_ONLY
- = StandardNames.KEY_TYPES.toArray(new String[StandardNames.KEY_TYPES.size()]);
- private static final String[] KEY_TYPES_WITH_EMPTY
- = new String[KEY_TYPES_ONLY.length + 1];
- private static final String[] KEY_TYPES_WITH_EMPTY_AND_NULL
- = new String[KEY_TYPES_ONLY.length + 2];
- static {
- System.arraycopy(KEY_TYPES_ONLY, 0,
- KEY_TYPES_WITH_EMPTY, 0,
- KEY_TYPES_ONLY.length);
- KEY_TYPES_WITH_EMPTY[KEY_TYPES_WITH_EMPTY.length-1] = "";
-
- System.arraycopy(KEY_TYPES_WITH_EMPTY, 0,
- KEY_TYPES_WITH_EMPTY_AND_NULL, 0,
- KEY_TYPES_WITH_EMPTY.length);
- // extra null at end requires no initialization
- }
-
- private void test_X509KeyManager(X509KeyManager km, boolean empty, String algorithm)
- throws Exception {
- String[] keyTypes = keyTypes(algorithm);
- for (String keyType : keyTypes) {
- String[] aliases = km.getClientAliases(keyType, null);
- if (empty || keyType == null || keyType.isEmpty()) {
- assertNull(keyType, aliases);
- continue;
- }
- assertNotNull(keyType, aliases);
- for (String alias : aliases) {
- test_X509KeyManager_alias(km, alias, keyType, false, empty);
- }
- }
- for (String keyType : keyTypes) {
- String[] aliases = km.getServerAliases(keyType, null);
- if (empty || keyType == null || keyType.isEmpty()) {
- assertNull(keyType, aliases);
- continue;
- }
- assertNotNull(keyType, aliases);
- for (String alias : aliases) {
- test_X509KeyManager_alias(km, alias, keyType, false, empty);
- }
- }
-
- String a = km.chooseClientAlias(keyTypes, null, null);
- test_X509KeyManager_alias(km, a, null, true, empty);
-
- for (String keyType : keyTypes) {
- String[] array = new String[] { keyType };
- String alias = km.chooseClientAlias(array, null, null);
- test_X509KeyManager_alias(km, alias, keyType, false, empty);
- }
- for (String keyType : keyTypes) {
- String alias = km.chooseServerAlias(keyType, null, null);
- test_X509KeyManager_alias(km, alias, keyType, false, empty);
- }
- if (km instanceof X509ExtendedKeyManager) {
- test_X509ExtendedKeyManager((X509ExtendedKeyManager) km, empty, algorithm);
- }
- }
-
- private void test_X509ExtendedKeyManager(X509ExtendedKeyManager km,
- boolean empty, String algorithm) throws Exception {
- String[] keyTypes = keyTypes(algorithm);
- String a = km.chooseEngineClientAlias(keyTypes, null, null);
- test_X509KeyManager_alias(km, a, null, true, empty);
- for (String keyType : keyTypes) {
- String[] array = new String[] { keyType };
- String alias = km.chooseEngineClientAlias(array, null, null);
- test_X509KeyManager_alias(km, alias, keyType, false, empty);
- }
- for (String keyType : keyTypes) {
- String alias = km.chooseEngineServerAlias(keyType, null, null);
- test_X509KeyManager_alias(km, alias, keyType, false, empty);
- }
- }
-
- private void test_X509KeyManager_alias(X509KeyManager km,
- String alias,
- String keyType,
- boolean many,
- boolean empty) throws Exception {
- if (empty || (!many && (keyType == null || keyType.isEmpty()))) {
- assertNull(keyType, alias);
- assertNull(keyType, km.getCertificateChain(alias));
- assertNull(keyType, km.getPrivateKey(alias));
- return;
- }
- assertNotNull(keyType, alias);
-
- X509Certificate[] certificateChain = km.getCertificateChain(alias);
- PrivateKey privateKey = km.getPrivateKey(alias);
-
- String keyAlgName = privateKey.getAlgorithm();
-
- X509Certificate certificate = certificateChain[0];
- assertEquals(keyType, keyAlgName, certificate.getPublicKey().getAlgorithm());
-
- String sigAlgName = certificate.getSigAlgName();
-
- PrivateKeyEntry privateKeyEntry = getTestKeyStore().getPrivateKey(keyAlgName, sigAlgName);
-
- assertEquals(keyType,
- Arrays.<Certificate>asList(privateKeyEntry.getCertificateChain()),
- Arrays.<Certificate>asList(certificateChain));
- assertEquals(keyType,
- privateKeyEntry.getPrivateKey(), privateKey);
-
- if (keyType != null) {
- assertEquals(TestKeyStore.keyAlgorithm(keyType), keyAlgName);
-
- // Skip this when we're given only "DH" or "EC" instead of "DH_DSA",
- // "EC_RSA", etc. since we don't know what the expected
- // algorithm was.
- if (!keyType.equals("DH") && !keyType.equals("EC")) {
- assertTrue(sigAlgName.contains(TestKeyStore.signatureAlgorithm(keyType)));
- }
- }
- }
-
- public void test_KeyManagerFactory_getInstance() throws Exception {
- Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("KeyManagerFactory")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- try {
- {
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
- assertEquals(algorithm, kmf.getAlgorithm());
- test_KeyManagerFactory(kmf);
- }
-
- {
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm,
- provider);
- assertEquals(algorithm, kmf.getAlgorithm());
- assertEquals(provider, kmf.getProvider());
- test_KeyManagerFactory(kmf);
- }
-
- {
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm,
- provider.getName());
- assertEquals(algorithm, kmf.getAlgorithm());
- assertEquals(provider, kmf.getProvider());
- test_KeyManagerFactory(kmf);
- }
- } catch (Exception e) {
- throw new Exception("Problem with algorithm " + algorithm, e);
- }
- }
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/KeyStoreBuilderParametersTest.java b/luni/src/test/java/libcore/javax/net/ssl/KeyStoreBuilderParametersTest.java
deleted file mode 100644
index d73e4a3..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/KeyStoreBuilderParametersTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import java.security.KeyStore.Builder;
-import java.security.KeyStore.PasswordProtection;
-import javax.net.ssl.KeyStoreBuilderParameters;
-import java.util.Arrays;
-import java.util.List;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class KeyStoreBuilderParametersTest extends TestCase {
- public void test_init_Builder_null() {
- try {
- new KeyStoreBuilderParameters((Builder) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_init_Builder() {
- TestKeyStore testKeyStore = TestKeyStore.getClient();
- Builder builder = Builder.newInstance(testKeyStore.keyStore,
- new PasswordProtection(testKeyStore.storePassword));
- KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(builder);
- assertNotNull(ksbp);
- assertNotNull(ksbp.getParameters());
- assertEquals(1, ksbp.getParameters().size());
- assertSame(builder, ksbp.getParameters().get(0));
- }
-
- public void test_init_List_null() {
- try {
- new KeyStoreBuilderParameters((List) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_init_List() {
- TestKeyStore testKeyStore1 = TestKeyStore.getClient();
- TestKeyStore testKeyStore2 = TestKeyStore.getServer();
- Builder builder1 = Builder.newInstance(testKeyStore1.keyStore,
- new PasswordProtection(testKeyStore1.storePassword));
- Builder builder2 = Builder.newInstance(testKeyStore2.keyStore,
- new PasswordProtection(testKeyStore2.storePassword));
-
- List list = Arrays.asList(builder1, builder2);
- KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(list);
- assertNotNull(ksbp);
- assertNotNull(ksbp.getParameters());
- assertNotSame(list, ksbp.getParameters());
- assertEquals(2, ksbp.getParameters().size());
- assertSame(builder1, ksbp.getParameters().get(0));
- assertSame(builder2, ksbp.getParameters().get(1));
-
- // confirm result is not modifiable
- try {
- ksbp.getParameters().set(0, builder2);
- fail();
- } catch (UnsupportedOperationException expected) {
- }
-
- // confirm result is a copy of original
- list.set(0, builder2);
- assertSame(builder1, ksbp.getParameters().get(0));
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java b/luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java
deleted file mode 100644
index 1daa346..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2014 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.javax.net.ssl;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.Socket;
-import javax.crypto.SecretKey;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLEngine;
-
-/**
- * Reflection-based implementation of {@code PSKKeyManager} from Conscrypt on which these tests
- * cannot depend directly.
- */
-class PSKKeyManagerProxy implements InvocationHandler {
-
- static KeyManager getConscryptPSKKeyManager(PSKKeyManagerProxy delegate) {
- Class<?> pskKeyManagerInterface;
- try {
- pskKeyManagerInterface = Class.forName("com.android.org.conscrypt.PSKKeyManager");
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- return (KeyManager) Proxy.newProxyInstance(
- PSKKeyManagerProxy.class.getClassLoader(),
- new Class[] {pskKeyManagerInterface},
- delegate);
- }
-
- @SuppressWarnings("unused")
- protected SecretKey getKey(String identityHint, String identity, Socket socket) {
- return null;
- }
-
- @SuppressWarnings("unused")
- protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
- return null;
- }
-
- @SuppressWarnings("unused")
- protected String chooseServerKeyIdentityHint(Socket socket) {
- return null;
- }
-
- @SuppressWarnings("unused")
- protected String chooseServerKeyIdentityHint(SSLEngine engine) {
- return null;
- }
-
- @SuppressWarnings("unused")
- protected String chooseClientKeyIdentity(String identityHint, Socket socket) {
- return null;
- }
-
- @SuppressWarnings("unused")
- protected String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
- return null;
- }
-
- @Override
- public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- String methodName = method.getName();
- Class<?>[] parameterTypes = method.getParameterTypes();
- boolean sslEngineVariant = (parameterTypes.length > 0)
- && (SSLEngine.class.equals(parameterTypes[parameterTypes.length - 1]));
- if ("getKey".equals(methodName)) {
- if (sslEngineVariant) {
- return getKey((String) args[0], (String) args[1], (SSLEngine) args[2]);
- } else {
- return getKey((String) args[0], (String) args[1], (Socket) args[2]);
- }
- } else if ("chooseServerKeyIdentityHint".equals(methodName)) {
- if (sslEngineVariant) {
- return chooseServerKeyIdentityHint((SSLEngine) args[0]);
- } else {
- return chooseServerKeyIdentityHint((Socket) args[0]);
- }
- } else if ("chooseClientKeyIdentity".equals(methodName)) {
- if (sslEngineVariant) {
- return chooseClientKeyIdentity((String) args[0], (SSLEngine) args[1]);
- } else {
- return chooseClientKeyIdentity((String) args[0], (Socket) args[1]);
- }
- } else {
- throw new IllegalArgumentException("Unexpected method: " + method);
- }
- }
-}
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/javax/net/ssl/README b/luni/src/test/java/libcore/javax/net/ssl/README
new file mode 100644
index 0000000..59f34f9
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/README
@@ -0,0 +1,2 @@
+Most tests for javax.net.ssl can be found in external/conscrypt. They
+should be updated at http://github.com/google/conscrypt.
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SNIHostNameTest.java b/luni/src/test/java/libcore/javax/net/ssl/SNIHostNameTest.java
deleted file mode 100644
index 0e4ed61..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SNIHostNameTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package libcore.javax.net.ssl;
-
-import java.util.Arrays;
-import javax.net.ssl.SNIHostName;
-import javax.net.ssl.StandardConstants;
-import junit.framework.TestCase;
-
-public class SNIHostNameTest extends TestCase {
- public void test_byteArray_Constructor() throws Exception {
- // From draft-josefsson-idn-test-vectors-00 section 5.2
- byte[] idnEncoded = new byte[] {
- (byte) 0xE4, (byte) 0xBB, (byte) 0x96, (byte) 0xE4, (byte) 0xBB, (byte) 0xAC,
- (byte) 0xE4, (byte) 0xB8, (byte) 0xBA, (byte) 0xE4, (byte) 0xBB, (byte) 0x80,
- (byte) 0xE4, (byte) 0xB9, (byte) 0x88, (byte) 0xE4, (byte) 0xB8, (byte) 0x8D,
- (byte) 0xE8, (byte) 0xAF, (byte) 0xB4, (byte) 0xE4, (byte) 0xB8, (byte) 0xAD,
- (byte) 0xE6, (byte) 0x96, (byte) 0x87,
- };
-
- SNIHostName hostName = new SNIHostName(idnEncoded);
- assertEquals("xn--ihqwcrb4cv8a8dqg056pqjye", hostName.getAsciiName());
- assertEquals(StandardConstants.SNI_HOST_NAME, hostName.getType());
- assertEquals(Arrays.toString(idnEncoded), Arrays.toString(hostName.getEncoded()));
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
deleted file mode 100644
index 9c8fe91..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import java.io.Closeable;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.UnrecoverableKeyException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import libcore.java.security.StandardNames;
-import javax.net.ServerSocketFactory;
-import javax.net.SocketFactory;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.KeyManagerFactorySpi;
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.TrustManagerFactorySpi;
-import javax.net.ssl.X509KeyManager;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-public class SSLContextTest extends TestCase {
-
- public void test_SSLContext_getDefault() throws Exception {
- SSLContext sslContext = SSLContext.getDefault();
- assertNotNull(sslContext);
- try {
- sslContext.init(null, null, null);
- fail();
- } catch (KeyManagementException expected) {
- }
- }
-
- public void test_SSLContext_setDefault() throws Exception {
- try {
- SSLContext.setDefault(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- SSLContext defaultContext = SSLContext.getDefault();
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext oldContext = SSLContext.getDefault();
- assertNotNull(oldContext);
- SSLContext newContext = SSLContext.getInstance(protocol);
- assertNotNull(newContext);
- assertNotSame(oldContext, newContext);
- SSLContext.setDefault(newContext);
- assertSame(newContext, SSLContext.getDefault());
- }
- SSLContext.setDefault(defaultContext);
- }
-
- public void test_SSLContext_defaultConfiguration() throws Exception {
- SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(SSLContext.getDefault());
-
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
- SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(sslContext);
- }
- }
-
- public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
- // Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
- // provided.
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(
- new KeyManager[] {
- PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
- },
- new TrustManager[0],
- null);
- List<String> expectedCipherSuites =
- new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
- expectedCipherSuites.add(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION);
- assertEnabledCipherSuites(expectedCipherSuites, sslContext);
- }
-
- public void test_SSLContext_x509AndPskConfiguration_defaultProviderOnly() throws Exception {
- // Test the scenario where an X509TrustManager and PSKKeyManager are provided.
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(
- new KeyManager[] {
- PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
- },
- null, // Use default trust managers, one of which is an X.509 one.
- null);
- List<String> expectedCipherSuites =
- new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
- expectedCipherSuites.addAll(StandardNames.CIPHER_SUITES_DEFAULT);
- assertEnabledCipherSuites(expectedCipherSuites, sslContext);
-
- // Test the scenario where an X509KeyManager and PSKKeyManager are provided.
- sslContext = SSLContext.getInstance("TLS");
- // Just an arbitrary X509KeyManager -- it won't be invoked in this test.
- X509KeyManager x509KeyManager = new RandomPrivateKeyX509ExtendedKeyManager(null);
- sslContext.init(
- new KeyManager[] {
- x509KeyManager,
- PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
- },
- new TrustManager[0],
- null);
- assertEnabledCipherSuites(expectedCipherSuites, sslContext);
- }
-
- public void test_SSLContext_emptyConfiguration_defaultProviderOnly() throws Exception {
- // Test the scenario where neither X.509 nor PSK KeyManagers or TrustManagers are provided.
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(
- new KeyManager[0],
- new TrustManager[0],
- null);
- assertEnabledCipherSuites(
- Arrays.asList(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION),
- sslContext);
- }
-
- public void test_SSLContext_init_correctProtocolVersionsEnabled() throws Exception {
- for (String tlsVersion : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- // Don't test the "Default" instance.
- if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(tlsVersion)) {
- continue;
- }
-
- SSLContext context = SSLContext.getInstance(tlsVersion);
- context.init(null, null, null);
-
- StandardNames.assertSSLContextEnabledProtocols(tlsVersion, ((SSLSocket) (context.getSocketFactory()
- .createSocket())).getEnabledProtocols());
- StandardNames.assertSSLContextEnabledProtocols(tlsVersion, ((SSLServerSocket) (context
- .getServerSocketFactory().createServerSocket())).getEnabledProtocols());
- StandardNames.assertSSLContextEnabledProtocols(tlsVersion, context.getDefaultSSLParameters()
- .getProtocols());
- StandardNames.assertSSLContextEnabledProtocols(tlsVersion, context.createSSLEngine()
- .getEnabledProtocols());
- }
- }
-
- private static void assertEnabledCipherSuites(
- List<String> expectedCipherSuites, SSLContext sslContext) throws Exception {
- assertContentsInOrder(
- expectedCipherSuites, sslContext.createSSLEngine().getEnabledCipherSuites());
- assertContentsInOrder(
- expectedCipherSuites,
- sslContext.createSSLEngine().getSSLParameters().getCipherSuites());
- assertContentsInOrder(
- expectedCipherSuites, sslContext.getSocketFactory().getDefaultCipherSuites());
- assertContentsInOrder(
- expectedCipherSuites, sslContext.getServerSocketFactory().getDefaultCipherSuites());
-
- SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
- try {
- assertContentsInOrder(
- expectedCipherSuites, sslSocket.getEnabledCipherSuites());
- assertContentsInOrder(
- expectedCipherSuites, sslSocket.getSSLParameters().getCipherSuites());
- } finally {
- closeQuietly(sslSocket);
- }
-
- SSLServerSocket sslServerSocket =
- (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket();
- try {
- assertContentsInOrder(
- expectedCipherSuites, sslServerSocket.getEnabledCipherSuites());
- } finally {
- closeQuietly(sslSocket);
- }
- }
-
- public void test_SSLContext_getInstance() throws Exception {
- try {
- SSLContext.getInstance(null);
- fail();
- } catch (NullPointerException expected) {
- }
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- assertNotNull(SSLContext.getInstance(protocol));
- assertNotSame(SSLContext.getInstance(protocol),
- SSLContext.getInstance(protocol));
- }
-
- try {
- SSLContext.getInstance(null, (String) null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- SSLContext.getInstance(null, "");
- fail();
- } catch (IllegalArgumentException expected) {
- }
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- try {
- SSLContext.getInstance(protocol, (String) null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
- try {
- SSLContext.getInstance(null, StandardNames.JSSE_PROVIDER_NAME);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_SSLContext_getProtocol() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- String protocolName = SSLContext.getInstance(protocol).getProtocol();
- assertNotNull(protocolName);
- assertTrue(protocol.startsWith(protocolName));
- }
- }
-
- public void test_SSLContext_getProvider() throws Exception {
- Provider provider = SSLContext.getDefault().getProvider();
- assertNotNull(provider);
- assertEquals(StandardNames.JSSE_PROVIDER_NAME, provider.getName());
- }
-
- public void test_SSLContext_init_Default() throws Exception {
- // Assert that initializing a default SSLContext fails because it's supposed to be
- // initialized already.
- SSLContext sslContext = SSLContext.getInstance(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT);
- try {
- sslContext.init(null, null, null);
- fail();
- } catch (KeyManagementException expected) {}
- try {
- sslContext.init(new KeyManager[0], new TrustManager[0], null);
- fail();
- } catch (KeyManagementException expected) {}
- try {
- sslContext.init(
- new KeyManager[] {new KeyManager() {}},
- new TrustManager[] {new TrustManager() {}},
- null);
- fail();
- } catch (KeyManagementException expected) {}
- }
-
- public void test_SSLContext_init_withNullManagerArrays() throws Exception {
- // Assert that SSLContext.init works fine even when provided with null arrays of
- // KeyManagers and TrustManagers.
- // The contract of SSLContext.init is that it will for default X.509 KeyManager and
- // TrustManager from the highest priority KeyManagerFactory and TrustManagerFactory.
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- // Default SSLContext is provided in an already initialized state
- continue;
- }
- SSLContext sslContext = SSLContext.getInstance(protocol);
- sslContext.init(null, null, null);
- }
- }
-
- public void test_SSLContext_init_withEmptyManagerArrays() throws Exception {
- // Assert that SSLContext.init works fine even when provided with empty arrays of
- // KeyManagers and TrustManagers.
- // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
- // TrustManager.
- // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
- // factories throw exceptions which will make this test fail if the factories are used.
- Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
- invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- assertEquals(
- ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
- TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
- .getProvider().getClass());
- assertEquals(
- ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
- KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
- .getProvider().getClass());
-
- KeyManager[] keyManagers = new KeyManager[0];
- TrustManager[] trustManagers = new TrustManager[0];
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- // Default SSLContext is provided in an already initialized state
- continue;
- }
- SSLContext sslContext = SSLContext.getInstance(protocol);
- sslContext.init(keyManagers, trustManagers, null);
- }
-
- return null;
- }
- });
- }
-
- public void test_SSLContext_init_withoutX509() throws Exception {
- // Assert that SSLContext.init works fine even when provided with KeyManagers and
- // TrustManagers which don't include the X.509 ones.
- // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
- // TrustManager.
- // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
- // factories throw exceptions which will make this test fail if the factories are used.
- Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
- invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- assertEquals(
- ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
- TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
- .getProvider().getClass());
- assertEquals(
- ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
- KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
- .getProvider().getClass());
-
- KeyManager[] keyManagers = new KeyManager[] {new KeyManager() {}};
- TrustManager[] trustManagers = new TrustManager[] {new TrustManager() {}};
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- // Default SSLContext is provided in an already initialized state
- continue;
- }
- SSLContext sslContext = SSLContext.getInstance(protocol);
- sslContext.init(keyManagers, trustManagers, null);
- }
-
- return null;
- }
- });
- }
-
- public static class ThrowExceptionKeyAndTrustManagerFactoryProvider extends Provider {
- public ThrowExceptionKeyAndTrustManagerFactoryProvider() {
- super("ThrowExceptionKeyAndTrustManagerProvider",
- 1.0,
- "SSLContextTest fake KeyManagerFactory and TrustManagerFactory provider");
-
- put("TrustManagerFactory." + TrustManagerFactory.getDefaultAlgorithm(),
- ThrowExceptionTrustManagagerFactorySpi.class.getName());
- put("TrustManagerFactory.PKIX", ThrowExceptionTrustManagagerFactorySpi.class.getName());
-
- put("KeyManagerFactory." + KeyManagerFactory.getDefaultAlgorithm(),
- ThrowExceptionKeyManagagerFactorySpi.class.getName());
- put("KeyManagerFactory.PKIX", ThrowExceptionKeyManagagerFactorySpi.class.getName());
- }
- }
-
- public static class ThrowExceptionTrustManagagerFactorySpi extends TrustManagerFactorySpi {
- @Override
- protected void engineInit(KeyStore ks) throws KeyStoreException {
- fail();
- }
-
- @Override
- protected void engineInit(ManagerFactoryParameters spec)
- throws InvalidAlgorithmParameterException {
- fail();
- }
-
- @Override
- protected TrustManager[] engineGetTrustManagers() {
- throw new AssertionFailedError();
- }
- }
-
- public static class ThrowExceptionKeyManagagerFactorySpi extends KeyManagerFactorySpi {
- @Override
- protected void engineInit(KeyStore ks, char[] password) throws KeyStoreException,
- NoSuchAlgorithmException, UnrecoverableKeyException {
- fail();
- }
-
- @Override
- protected void engineInit(ManagerFactoryParameters spec)
- throws InvalidAlgorithmParameterException {
- fail();
- }
-
- @Override
- protected KeyManager[] engineGetKeyManagers() {
- throw new AssertionFailedError();
- }
- }
-
- /**
- * Installs the specified security provider as the highest provider, invokes the provided
- * {@link Callable}, and removes the provider.
- *
- * @return result returned by the {@code callable}.
- */
- private static <T> T invokeWithHighestPrioritySecurityProvider(
- Provider provider, Callable<T> callable) throws Exception {
- int providerPosition = -1;
- try {
- providerPosition = Security.insertProviderAt(provider, 1);
- assertEquals(1, providerPosition);
- return callable.call();
- } finally {
- if (providerPosition != -1) {
- Security.removeProvider(provider.getName());
- }
- }
- }
-
- public void test_SSLContext_getSocketFactory() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- SSLContext.getInstance(protocol).getSocketFactory();
- } else {
- try {
- SSLContext.getInstance(protocol).getSocketFactory();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
- SocketFactory sf = sslContext.getSocketFactory();
- assertNotNull(sf);
- assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
- }
- }
-
- public void test_SSLContext_getServerSocketFactory() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- SSLContext.getInstance(protocol).getServerSocketFactory();
- } else {
- try {
- SSLContext.getInstance(protocol).getServerSocketFactory();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
- ServerSocketFactory ssf = sslContext.getServerSocketFactory();
- assertNotNull(ssf);
- assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
- }
- }
-
- public void test_SSLContext_createSSLEngine() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
-
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- SSLContext.getInstance(protocol).createSSLEngine();
- } else {
- try {
- SSLContext.getInstance(protocol).createSSLEngine();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- SSLContext.getInstance(protocol).createSSLEngine(null, -1);
- } else {
- try {
- SSLContext.getInstance(protocol).createSSLEngine(null, -1);
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
- SSLEngine se = sslContext.createSSLEngine();
- assertNotNull(se);
- }
-
- {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
- SSLEngine se = sslContext.createSSLEngine(null, -1);
- assertNotNull(se);
- }
- }
- }
-
- public void test_SSLContext_getServerSessionContext() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- SSLSessionContext sessionContext = sslContext.getServerSessionContext();
- assertNotNull(sessionContext);
-
- if (!StandardNames.IS_RI &&
- protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- assertSame(SSLContext.getInstance(protocol).getServerSessionContext(),
- sessionContext);
- } else {
- assertNotSame(SSLContext.getInstance(protocol).getServerSessionContext(),
- sessionContext);
- }
- }
- }
-
- public void test_SSLContext_getClientSessionContext() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- SSLSessionContext sessionContext = sslContext.getClientSessionContext();
- assertNotNull(sessionContext);
-
- if (!StandardNames.IS_RI &&
- protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- assertSame(SSLContext.getInstance(protocol).getClientSessionContext(),
- sessionContext);
- } else {
- assertNotSame(SSLContext.getInstance(protocol).getClientSessionContext(),
- sessionContext);
- }
- }
- }
-
- public void test_SSLContextTest_TestSSLContext_create() {
- TestSSLContext testContext = TestSSLContext.create();
- assertNotNull(testContext);
- assertNotNull(testContext.clientKeyStore);
- assertNull(testContext.clientStorePassword);
- assertNotNull(testContext.serverKeyStore);
- assertEquals(StandardNames.IS_RI, testContext.serverStorePassword != null);
- assertNotNull(testContext.clientKeyManagers);
- assertNotNull(testContext.serverKeyManagers);
- if (testContext.clientKeyManagers.length == 0) {
- fail("No client KeyManagers");
- }
- if (testContext.serverKeyManagers.length == 0) {
- fail("No server KeyManagers");
- }
- assertNotNull(testContext.clientKeyManagers[0]);
- assertNotNull(testContext.serverKeyManagers[0]);
- assertNotNull(testContext.clientTrustManager);
- assertNotNull(testContext.serverTrustManager);
- assertNotNull(testContext.clientContext);
- assertNotNull(testContext.serverContext);
- assertNotNull(testContext.serverSocket);
- assertNotNull(testContext.host);
- assertTrue(testContext.port != 0);
- testContext.close();
- }
-
- public void test_SSLContext_SSLv3Unsupported() throws Exception {
- try {
- SSLContext context = SSLContext.getInstance("SSLv3");
- fail("SSLv3 should not be supported");
- } catch (NoSuchAlgorithmException expected) {
- }
- }
-
- private static void assertContentsInOrder(List<String> expected, String... actual) {
- if (expected.size() != actual.length) {
- fail("Unexpected length. Expected len <" + expected.size()
- + ">, actual len <" + actual.length + ">, expected <" + expected
- + ">, actual <" + Arrays.asList(actual) + ">");
- }
- if (!expected.equals(Arrays.asList(actual))) {
- fail("Unexpected element(s). Expected <" + expected
- + ">, actual <" + Arrays.asList(actual) + ">" );
- }
- }
-
- private static final void closeQuietly(Closeable socket) {
- if (socket != null) {
- try {
- socket.close();
- } catch (Exception ignored) {
- }
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
deleted file mode 100644
index eed6b11..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.X509ExtendedKeyManager;
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-
-public class SSLEngineTest extends TestCase {
-
- public void assertConnected(TestSSLEnginePair e) {
- assertConnected(e.client, e.server);
- }
-
- public void assertNotConnected(TestSSLEnginePair e) {
- assertNotConnected(e.client, e.server);
- }
-
- public void assertConnected(SSLEngine a, SSLEngine b) {
- assertTrue(connected(a, b));
- }
-
- public void assertNotConnected(SSLEngine a, SSLEngine b) {
- assertFalse(connected(a, b));
- }
-
- public boolean connected(SSLEngine a, SSLEngine b) {
- return (a.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
- && b.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
- && a.getSession() != null
- && b.getSession() != null
- && !a.isInboundDone()
- && !b.isInboundDone()
- && !a.isOutboundDone()
- && !b.isOutboundDone());
- }
-
- public void test_SSLEngine_defaultConfiguration() throws Exception {
- SSLConfigurationAsserts.assertSSLEngineDefaultConfiguration(
- TestSSLContext.create().clientContext.createSSLEngine());
- }
-
- public void test_SSLEngine_getSupportedCipherSuites_returnsCopies() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- assertNotSame(e.getSupportedCipherSuites(), e.getSupportedCipherSuites());
- c.close();
- }
-
- public void test_SSLEngine_getSupportedCipherSuites_connect() throws Exception {
- // note the rare usage of non-RSA keys
- TestKeyStore testKeyStore = new TestKeyStore.Builder()
- .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
- .aliasPrefix("rsa-dsa-ec")
- .ca(true)
- .build();
- test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, false);
- test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
- }
-
- // http://b/18554122
- public void test_SSLEngine_underflowsOnEmptyBuffersDuringHandshake() throws Exception {
- final SSLEngine sslEngine = SSLContext.getDefault().createSSLEngine();
- sslEngine.setUseClientMode(false);
- ByteBuffer input = ByteBuffer.allocate(1024);
- input.flip();
- ByteBuffer output = ByteBuffer.allocate(1024);
- sslEngine.beginHandshake();
- assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, sslEngine.getHandshakeStatus());
- SSLEngineResult result = sslEngine.unwrap(input, output);
- assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW, result.getStatus());
- assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
- }
-
- // http://b/18554122
- public void test_SSLEngine_underflowsOnEmptyBuffersAfterHandshake() throws Exception {
- // Note that create performs the handshake.
- final TestSSLEnginePair engines = TestSSLEnginePair.create(null /* hooks */);
- ByteBuffer input = ByteBuffer.allocate(1024);
- input.flip();
- ByteBuffer output = ByteBuffer.allocate(1024);
- assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW,
- engines.client.unwrap(input, output).getStatus());
- }
-
- private void test_SSLEngine_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
- boolean secureRenegotiation)
- throws Exception {
- KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
- new PSKKeyManagerProxy() {
- @Override
- protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
- return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
- }
- });
- TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
- testKeyStore, testKeyStore,
- new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager});
-
- // Create a TestSSLContext where the KeyManager returns wrong (randomly generated) private
- // keys, matching the algorithm and parameters of the correct keys.
- // I couldn't find a more elegant way to achieve this other than temporarily replacing the
- // first X509ExtendedKeyManager element of TestKeyStore.keyManagers while invoking
- // TestSSLContext.create.
- TestSSLContext cWithWrongPrivateKeys;
- {
- // Create a RandomPrivateKeyX509ExtendedKeyManager based on the first
- // X509ExtendedKeyManager in c.serverKeyManagers.
- KeyManager randomPrivateKeyX509ExtendedKeyManager = null;
- for (KeyManager keyManager : c.serverKeyManagers) {
- if (keyManager instanceof X509ExtendedKeyManager) {
- randomPrivateKeyX509ExtendedKeyManager =
- new RandomPrivateKeyX509ExtendedKeyManager((X509ExtendedKeyManager) keyManager);
- break;
- }
- }
- if (randomPrivateKeyX509ExtendedKeyManager == null) {
- fail("No X509ExtendedKeyManager in c.serverKeyManagers");
- }
-
- // Find the first X509ExtendedKeyManager in testKeyStore.keyManagers
- int replaceIndex = -1;
- for (int i = 0; i < testKeyStore.keyManagers.length; i++) {
- KeyManager keyManager = testKeyStore.keyManagers[i];
- if (keyManager instanceof X509ExtendedKeyManager) {
- replaceIndex = i;
- break;
- }
- }
- if (replaceIndex == -1) {
- fail("No X509ExtendedKeyManager in testKeyStore.keyManagers");
- }
-
- // Temporarily substitute the RandomPrivateKeyX509ExtendedKeyManager in place of the
- // original X509ExtendedKeyManager.
- KeyManager originalKeyManager = testKeyStore.keyManagers[replaceIndex];
- testKeyStore.keyManagers[replaceIndex] = randomPrivateKeyX509ExtendedKeyManager;
- cWithWrongPrivateKeys = TestSSLContext.create(testKeyStore, testKeyStore);
- testKeyStore.keyManagers[replaceIndex] = originalKeyManager;
- }
-
- // To catch all the errors.
- StringBuilder error = new StringBuilder();
-
- String[] cipherSuites = c.clientContext.createSSLEngine().getSupportedCipherSuites();
- for (String cipherSuite : cipherSuites) {
- try {
- // Skip cipher suites that are obsoleted.
- if (StandardNames.IS_RI && "TLSv1.2".equals(c.clientContext.getProtocol())
- && StandardNames.CIPHER_SUITES_OBSOLETE_TLS12.contains(cipherSuite)) {
- continue;
- }
- /*
- * Signaling Cipher Suite Values (SCSV) cannot be used on their own, but instead in
- * conjunction with other cipher suites.
- */
- if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
- || cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
- continue;
- }
- /*
- * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
- * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
- * #KRBRequire
- */
- if (cipherSuite.startsWith("TLS_KRB5_")) {
- continue;
- }
-
- final String[] cipherSuiteArray
- = (secureRenegotiation
- ? new String[] { cipherSuite,
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
- : new String[] { cipherSuite });
-
- // Check that handshake succeeds.
- TestSSLEnginePair pair = null;
- try {
- pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setEnabledCipherSuites(cipherSuiteArray);
- server.setEnabledCipherSuites(cipherSuiteArray);
- }
- });
- assertConnected(pair);
-
- boolean needsRecordSplit =
- "TLS".equalsIgnoreCase(c.clientContext.getProtocol())
- && cipherSuite.contains("_CBC_");
-
- assertSendsCorrectly("This is the client. Hello!".getBytes(UTF_8),
- pair.client, pair.server, needsRecordSplit);
- assertSendsCorrectly("This is the server. Hi!".getBytes(UTF_8),
- pair.server, pair.client, needsRecordSplit);
- } finally {
- if (pair != null) {
- pair.close();
- }
- }
-
- // Check that handshake fails when the server does not possess the private key
- // corresponding to the server's certificate. This is achieved by using SSLContext
- // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
- // the algorithm (and parameters) of the correct keys.
- boolean serverAuthenticatedUsingPublicKey = true;
- if (cipherSuite.contains("_anon_")) {
- serverAuthenticatedUsingPublicKey = false;
- } else if ((cipherSuite.startsWith("TLS_PSK_"))
- || (cipherSuite.startsWith("TLS_ECDHE_PSK_"))) {
- serverAuthenticatedUsingPublicKey = false;
- }
- if (serverAuthenticatedUsingPublicKey) {
- TestSSLEnginePair p = null;
- try {
- p = TestSSLEnginePair.create(
- cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setEnabledCipherSuites(cipherSuiteArray);
- server.setEnabledCipherSuites(cipherSuiteArray);
- }
- });
- assertNotConnected(p);
- } catch (IOException expected) {
- } finally {
- if (p != null) {
- p.close();
- }
- }
- }
- } catch (Exception e) {
- String message = ("Problem trying to connect cipher suite " + cipherSuite);
- System.out.println(message);
- e.printStackTrace();
- error.append(message);
- error.append('\n');
- }
- }
- c.close();
-
- if (error.length() > 0) {
- throw new Exception("One or more problems in "
- + "test_SSLEngine_getSupportedCipherSuites_connect:\n" + error);
- }
- }
-
- private static void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source,
- SSLEngine dest, boolean needsRecordSplit) throws SSLException {
- ByteBuffer sourceOut = ByteBuffer.wrap(sourceBytes);
- SSLSession sourceSession = source.getSession();
- ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
- SSLEngineResult sourceOutRes = source.wrap(sourceOut, sourceToDest);
- sourceToDest.flip();
-
- String sourceCipherSuite = source.getSession().getCipherSuite();
- assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
- assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
- sourceOutRes.getHandshakeStatus());
-
- SSLSession destSession = dest.getSession();
- ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
-
- int numUnwrapCalls = 0;
- while (destIn.position() != sourceOut.limit()) {
- SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
- assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
- destRes.getHandshakeStatus());
- if (needsRecordSplit && numUnwrapCalls == 0) {
- assertEquals(sourceCipherSuite, 1, destRes.bytesProduced());
- }
- numUnwrapCalls++;
- }
-
- destIn.flip();
- byte[] actual = new byte[destIn.remaining()];
- destIn.get(actual);
- assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
-
- if (needsRecordSplit) {
- assertEquals(sourceCipherSuite, 2, numUnwrapCalls);
- } else {
- assertEquals(sourceCipherSuite, 1, numUnwrapCalls);
- }
- }
-
- public void test_SSLEngine_getEnabledCipherSuites_returnsCopies() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- assertNotSame(e.getEnabledCipherSuites(), e.getEnabledCipherSuites());
- c.close();
- }
-
- public void test_SSLEngine_setEnabledCipherSuites_storesCopy() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- String[] array = new String[] {e.getEnabledCipherSuites()[0]};
- String originalFirstElement = array[0];
- e.setEnabledCipherSuites(array);
- array[0] = "Modified after having been set";
- assertEquals(originalFirstElement, e.getEnabledCipherSuites()[0]);
- }
-
- public void test_SSLEngine_setEnabledCipherSuites() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
-
- try {
- e.setEnabledCipherSuites(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- e.setEnabledCipherSuites(new String[1]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- e.setEnabledCipherSuites(new String[] { "Bogus" } );
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- e.setEnabledCipherSuites(new String[0]);
- e.setEnabledCipherSuites(e.getEnabledCipherSuites());
- e.setEnabledCipherSuites(e.getSupportedCipherSuites());
-
- // Check that setEnabledCipherSuites affects getEnabledCipherSuites
- String[] cipherSuites = new String[] { e.getSupportedCipherSuites()[0] };
- e.setEnabledCipherSuites(cipherSuites);
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
-
- c.close();
- }
-
- public void test_SSLEngine_getSupportedProtocols_returnsCopies() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- assertNotSame(e.getSupportedProtocols(), e.getSupportedProtocols());
- c.close();
- }
-
- public void test_SSLEngine_getEnabledProtocols_returnsCopies() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- assertNotSame(e.getEnabledProtocols(), e.getEnabledProtocols());
- c.close();
- }
-
- public void test_SSLEngine_setEnabledProtocols_storesCopy() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- String[] array = new String[] {e.getEnabledProtocols()[0]};
- String originalFirstElement = array[0];
- e.setEnabledProtocols(array);
- array[0] = "Modified after having been set";
- assertEquals(originalFirstElement, e.getEnabledProtocols()[0]);
- }
-
- public void test_SSLEngine_setEnabledProtocols() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
-
- try {
- e.setEnabledProtocols(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- e.setEnabledProtocols(new String[1]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- e.setEnabledProtocols(new String[] { "Bogus" } );
- fail();
- } catch (IllegalArgumentException expected) {
- }
- e.setEnabledProtocols(new String[0]);
- e.setEnabledProtocols(e.getEnabledProtocols());
- e.setEnabledProtocols(e.getSupportedProtocols());
-
- // Check that setEnabledProtocols affects getEnabledProtocols
- for (String protocol : e.getSupportedProtocols()) {
- if ("SSLv2Hello".equals(protocol)) {
- try {
- e.setEnabledProtocols(new String[] { protocol });
- fail("Should fail when SSLv2Hello is set by itself");
- } catch (IllegalArgumentException expected) {}
- } else {
- String[] protocols = new String[] { protocol };
- e.setEnabledProtocols(protocols);
- assertEquals(Arrays.deepToString(protocols),
- Arrays.deepToString(e.getEnabledProtocols()));
- }
- }
-
- c.close();
- }
-
- public void test_SSLEngine_getSession() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- SSLSession session = e.getSession();
- assertNotNull(session);
- assertFalse(session.isValid());
- c.close();
- }
-
- public void test_SSLEngine_beginHandshake() throws Exception {
- TestSSLContext c = TestSSLContext.create();
-
- try {
- c.clientContext.createSSLEngine().beginHandshake();
- fail();
- } catch (IllegalStateException expected) {
- }
- c.close();
-
- TestSSLEnginePair p = TestSSLEnginePair.create(null);
- assertConnected(p);
- p.close();
-
- }
-
- public void test_SSLEngine_beginHandshake_noKeyStore() throws Exception {
- TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
- SSLContext.getDefault(), SSLContext.getDefault());
- SSLEngine[] p = null;
- try {
- // TODO Fix KnownFailure AlertException "NO SERVER CERTIFICATE FOUND"
- // ServerHandshakeImpl.selectSuite should not select a suite without a required cert
- p = TestSSLEnginePair.connect(c, null);
- fail();
- } catch (SSLHandshakeException expected) {
- } finally {
- if (p != null) {
- TestSSLEnginePair.close(p);
- }
- }
- c.close();
- }
-
- public void test_SSLEngine_beginHandshake_noClientCertificate() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine[] engines = TestSSLEnginePair.connect(c, null);
- assertConnected(engines[0], engines[1]);
- c.close();
- TestSSLEnginePair.close(engines);
- }
-
- public void test_SSLEngine_getUseClientMode() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- assertFalse(c.clientContext.createSSLEngine().getUseClientMode());
- assertFalse(c.clientContext.createSSLEngine(null, -1).getUseClientMode());
- c.close();
- }
-
- public void test_SSLEngine_setUseClientMode() throws Exception {
- boolean[] finished;
- TestSSLEnginePair p = null;
-
- // client is client, server is server
- finished = new boolean[2];
- p = test_SSLEngine_setUseClientMode(true, false, finished);
- assertConnected(p);
- assertTrue(finished[0]);
- assertTrue(finished[1]);
- p.close();
-
- // client is server, server is client
- finished = new boolean[2];
- p = test_SSLEngine_setUseClientMode(false, true, finished);
- assertConnected(p);
- assertTrue(finished[0]);
- assertTrue(finished[1]);
- p.close();
-
- // both are client
- /*
- * Our implementation throws an SSLHandshakeException, but RI just
- * stalls forever
- */
- p = null;
- try {
- p = test_SSLEngine_setUseClientMode(true, true, null);
- assertNotConnected(p);
- assertTrue(StandardNames.IS_RI);
- } catch (SSLHandshakeException maybeExpected) {
- assertFalse(StandardNames.IS_RI);
- } finally {
- if (p != null) {
- p.close();
- }
-
- }
-
- p = test_SSLEngine_setUseClientMode(false, false, null);
- // both are server
- assertNotConnected(p);
- p.close();
- }
-
- public void test_SSLEngine_setUseClientMode_afterHandshake() throws Exception {
-
- // can't set after handshake
- TestSSLEnginePair pair = TestSSLEnginePair.create(null);
- try {
- pair.server.setUseClientMode(false);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- pair.client.setUseClientMode(false);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- pair.close();
- }
-
- private TestSSLEnginePair test_SSLEngine_setUseClientMode(final boolean clientClientMode,
- final boolean serverClientMode,
- final boolean[] finished)
- throws Exception {
- TestSSLContext c;
- if (!clientClientMode && serverClientMode) {
- c = TestSSLContext.create(TestKeyStore.getServer(), TestKeyStore.getClient());
- } else {
- c = TestSSLContext.create();
- }
-
- return TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setUseClientMode(clientClientMode);
- server.setUseClientMode(serverClientMode);
- }
- }, finished);
- }
-
- public void test_SSLEngine_clientAuth() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
-
- assertFalse(e.getWantClientAuth());
- assertFalse(e.getNeedClientAuth());
-
- // confirm turning one on by itself
- e.setWantClientAuth(true);
- assertTrue(e.getWantClientAuth());
- assertFalse(e.getNeedClientAuth());
-
- // confirm turning setting on toggles the other
- e.setNeedClientAuth(true);
- assertFalse(e.getWantClientAuth());
- assertTrue(e.getNeedClientAuth());
-
- // confirm toggling back
- e.setWantClientAuth(true);
- assertTrue(e.getWantClientAuth());
- assertFalse(e.getNeedClientAuth());
-
- // TODO Fix KnownFailure "init - invalid private key"
- TestSSLContext clientAuthContext
- = TestSSLContext.create(TestKeyStore.getClientCertificate(),
- TestKeyStore.getServer());
- TestSSLEnginePair p = TestSSLEnginePair.create(clientAuthContext,
- new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- server.setWantClientAuth(true);
- }
- });
- assertConnected(p);
- assertNotNull(p.client.getSession().getLocalCertificates());
- TestKeyStore.assertChainLength(p.client.getSession().getLocalCertificates());
- TestSSLContext.assertClientCertificateChain(clientAuthContext.clientTrustManager,
- p.client.getSession().getLocalCertificates());
- clientAuthContext.close();
- c.close();
- p.close();
- }
-
- /**
- * http://code.google.com/p/android/issues/detail?id=31903
- * This test case directly tests the fix for the issue.
- */
- public void test_SSLEngine_clientAuthWantedNoClientCert() throws Exception {
- TestSSLContext clientAuthContext
- = TestSSLContext.create(TestKeyStore.getClient(),
- TestKeyStore.getServer());
- TestSSLEnginePair p = TestSSLEnginePair.create(clientAuthContext,
- new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- server.setWantClientAuth(true);
- }
- });
- assertConnected(p);
- clientAuthContext.close();
- p.close();
- }
-
- /**
- * http://code.google.com/p/android/issues/detail?id=31903
- * This test case verifies that if the server requires a client cert
- * (setNeedClientAuth) but the client does not provide one SSL connection
- * establishment will fail
- */
- public void test_SSLEngine_clientAuthNeededNoClientCert() throws Exception {
- boolean handshakeExceptionCaught = false;
- TestSSLContext clientAuthContext
- = TestSSLContext.create(TestKeyStore.getClient(),
- TestKeyStore.getServer());
- TestSSLEnginePair p = null;
- try {
- p = TestSSLEnginePair.create(clientAuthContext,
- new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- server.setNeedClientAuth(true);
- }
- });
- fail();
- } catch (SSLHandshakeException expected) {
- } finally {
- clientAuthContext.close();
- if (p != null) {
- p.close();
- }
- }
- }
-
- public void test_SSLEngine_endpointVerification_Success() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- TestSSLEnginePair p = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- SSLParameters p = client.getSSLParameters();
- p.setEndpointIdentificationAlgorithm("HTTPS");
- client.setSSLParameters(p);
- }
- });
- assertConnected(p);
- c.close();
- }
-
- public void test_SSLEngine_getEnableSessionCreation() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- assertTrue(e.getEnableSessionCreation());
- c.close();
- TestSSLEnginePair.close(new SSLEngine[] { e });
- }
-
- public void test_SSLEngine_setEnableSessionCreation_server() throws Exception {
- TestSSLEnginePair p = null;
- try {
- p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- server.setEnableSessionCreation(false);
- }
- });
- // For some reason, the RI doesn't throw an SSLException.
- assertTrue(StandardNames.IS_RI);
- assertNotConnected(p);
- } catch (SSLException maybeExpected) {
- assertFalse(StandardNames.IS_RI);
- } finally {
- if (p != null) {
- p.close();
- }
- }
- }
-
- public void test_SSLEngine_setEnableSessionCreation_client() throws Exception {
- TestSSLEnginePair p = null;
- try {
- p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setEnableSessionCreation(false);
- }
- });
- fail();
- } catch (SSLException expected) {
- } finally {
- if (p != null) {
- p.close();
- }
- }
- }
-
- public void test_SSLEngine_getSSLParameters() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
-
- SSLParameters p = e.getSSLParameters();
- assertNotNull(p);
-
- String[] cipherSuites = p.getCipherSuites();
- assertNotSame(cipherSuites, e.getEnabledCipherSuites());
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
-
- String[] protocols = p.getProtocols();
- assertNotSame(protocols, e.getEnabledProtocols());
- assertEquals(Arrays.asList(protocols), Arrays.asList(e.getEnabledProtocols()));
-
- assertEquals(p.getWantClientAuth(), e.getWantClientAuth());
- assertEquals(p.getNeedClientAuth(), e.getNeedClientAuth());
-
- c.close();
- }
-
- public void test_SSLEngine_setSSLParameters() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLEngine e = c.clientContext.createSSLEngine();
- String[] defaultCipherSuites = e.getEnabledCipherSuites();
- String[] defaultProtocols = e.getEnabledProtocols();
- String[] supportedCipherSuites = e.getSupportedCipherSuites();
- String[] supportedProtocols = e.getSupportedProtocols();
-
- {
- SSLParameters p = new SSLParameters();
- e.setSSLParameters(p);
- assertEquals(Arrays.asList(defaultCipherSuites),
- Arrays.asList(e.getEnabledCipherSuites()));
- assertEquals(Arrays.asList(defaultProtocols),
- Arrays.asList(e.getEnabledProtocols()));
- }
-
- {
- SSLParameters p = new SSLParameters(supportedCipherSuites,
- supportedProtocols);
- e.setSSLParameters(p);
- assertEquals(Arrays.asList(supportedCipherSuites),
- Arrays.asList(e.getEnabledCipherSuites()));
- assertEquals(Arrays.asList(supportedProtocols),
- Arrays.asList(e.getEnabledProtocols()));
- }
- {
- SSLParameters p = new SSLParameters();
-
- p.setNeedClientAuth(true);
- assertFalse(e.getNeedClientAuth());
- assertFalse(e.getWantClientAuth());
- e.setSSLParameters(p);
- assertTrue(e.getNeedClientAuth());
- assertFalse(e.getWantClientAuth());
-
- p.setWantClientAuth(true);
- assertTrue(e.getNeedClientAuth());
- assertFalse(e.getWantClientAuth());
- e.setSSLParameters(p);
- assertFalse(e.getNeedClientAuth());
- assertTrue(e.getWantClientAuth());
-
- p.setWantClientAuth(false);
- assertFalse(e.getNeedClientAuth());
- assertTrue(e.getWantClientAuth());
- e.setSSLParameters(p);
- assertFalse(e.getNeedClientAuth());
- assertFalse(e.getWantClientAuth());
- }
- c.close();
- }
-
- public void test_TestSSLEnginePair_create() throws Exception {
- TestSSLEnginePair test = TestSSLEnginePair.create(null);
- assertNotNull(test.c);
- assertNotNull(test.server);
- assertNotNull(test.client);
- assertConnected(test);
- test.close();
- }
-
- private final int NUM_STRESS_ITERATIONS = 1000;
-
- public void test_SSLEngine_Multiple_Thread_Success() throws Exception {
- try (final TestSSLEnginePair pair = TestSSLEnginePair.create()) {
- assertConnected(pair);
-
- final CountDownLatch startUpSync = new CountDownLatch(2);
- ExecutorService executor = Executors.newFixedThreadPool(2);
- Future<Void> client = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- startUpSync.countDown();
-
- for (int i = 0; i < NUM_STRESS_ITERATIONS; i++) {
- assertSendsCorrectly("This is the client. Hello!".getBytes(UTF_8),
- pair.client, pair.server, false);
- }
-
- return null;
- }
- });
- Future<Void> server = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- startUpSync.countDown();
-
- for (int i = 0; i < NUM_STRESS_ITERATIONS; i++) {
- assertSendsCorrectly("This is the server. Hi!".getBytes(UTF_8),
- pair.server, pair.client, false);
- }
-
- return null;
- }
- });
- executor.shutdown();
- client.get();
- server.get();
- }
- }
-
- public void test_SSLEngine_CloseOutbound() throws Exception {
- try (final TestSSLEnginePair pair = TestSSLEnginePair.create()) {
- assertConnected(pair);
-
- pair.client.closeOutbound();
- ByteBuffer clientOut = ByteBuffer.allocate(pair.client.getSession().getPacketBufferSize());
- SSLEngineResult res = pair.client.wrap(ByteBuffer.wrap(new byte[0]), clientOut);
- assertEquals(Status.CLOSED, res.getStatus());
- assertEquals(HandshakeStatus.NOT_HANDSHAKING, res.getHandshakeStatus());
-
- clientOut.flip();
- ByteBuffer serverIn = ByteBuffer.allocate(pair.server.getSession().getApplicationBufferSize());
- res = pair.server.unwrap(clientOut, serverIn);
- assertEquals(Status.CLOSED, res.getStatus());
- assertEquals(HandshakeStatus.NEED_WRAP, res.getHandshakeStatus());
-
- ByteBuffer serverOut = ByteBuffer.allocate(pair.server.getSession().getPacketBufferSize());
- res = pair.server.wrap(ByteBuffer.wrap(new byte[0]), serverOut);
- assertEquals(Status.CLOSED, res.getStatus());
- assertEquals(HandshakeStatus.NOT_HANDSHAKING, res.getHandshakeStatus());
-
- serverOut.flip();
- ByteBuffer clientIn = ByteBuffer.allocate(pair.client.getSession().getApplicationBufferSize());
- res = pair.client.unwrap(serverOut, clientIn);
- assertEquals(Status.CLOSED, res.getStatus());
- assertEquals(HandshakeStatus.NOT_HANDSHAKING, res.getHandshakeStatus());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
deleted file mode 100644
index 03d697e..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import javax.net.ssl.SNIHostName;
-import javax.net.ssl.SNIMatcher;
-import javax.net.ssl.SNIServerName;
-import javax.net.ssl.SSLParameters;
-import junit.framework.TestCase;
-
-public class SSLParametersTest extends TestCase {
-
- public void test_SSLParameters_emptyConstructor() {
- SSLParameters p = new SSLParameters();
- assertNull(p.getCipherSuites());
- assertNull(p.getProtocols());
- assertFalse(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
- }
-
- public void test_SSLParameters_cipherSuitesConstructor() {
- String[] cipherSuites = new String[] { "foo", null, "bar" };
- SSLParameters p = new SSLParameters(cipherSuites);
- assertNotNull(p.getCipherSuites());
- assertNotSame(cipherSuites, p.getCipherSuites());
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
- assertNull(p.getProtocols());
- assertFalse(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
- }
-
- public void test_SSLParameters_cpherSuitesProtocolsConstructor() {
- String[] cipherSuites = new String[] { "foo", null, "bar" };
- String[] protocols = new String[] { "baz", null, "qux" };
- SSLParameters p = new SSLParameters(cipherSuites, protocols);
- assertNotNull(p.getCipherSuites());
- assertNotNull(p.getProtocols());
- assertNotSame(cipherSuites, p.getCipherSuites());
- assertNotSame(protocols, p.getProtocols());
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
- assertEquals(Arrays.asList(protocols), Arrays.asList(p.getProtocols()));
- assertFalse(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
- }
-
- public void test_SSLParameters_CipherSuites() {
- SSLParameters p = new SSLParameters();
- assertNull(p.getCipherSuites());
-
- // confirm clone on input
- String[] cipherSuites = new String[] { "fnord" };
- String[] copy = cipherSuites.clone();
- p.setCipherSuites(copy);
- copy[0] = null;
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
-
- // confirm clone on output
- assertNotSame(p.getCipherSuites(), p.getCipherSuites());
- }
-
- public void test_SSLParameters_Protocols() {
- SSLParameters p = new SSLParameters();
- assertNull(p.getProtocols());
-
- // confirm clone on input
- String[] protocols = new String[] { "fnord" };
- String[] copy = protocols.clone();
- p.setProtocols(copy);
- copy[0] = null;
- assertEquals(Arrays.asList(protocols), Arrays.asList(p.getProtocols()));
-
- // confirm clone on output
- assertNotSame(p.getProtocols(), p.getProtocols());
- }
-
- public void test_SSLParameters_ClientAuth() {
- SSLParameters p = new SSLParameters();
- assertFalse(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
-
- // confirm turning one on by itself
- p.setWantClientAuth(true);
- assertTrue(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
-
- // confirm turning setting on toggles the other
- p.setNeedClientAuth(true);
- assertFalse(p.getWantClientAuth());
- assertTrue(p.getNeedClientAuth());
-
- // confirm toggling back
- p.setWantClientAuth(true);
- assertTrue(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
- }
-
- public void test_SSLParameters_setServerNames_duplicatedNameThrows() throws Exception {
- SSLParameters p = new SSLParameters();
- ArrayList<SNIServerName> dupeNames = new ArrayList<SNIServerName>();
- dupeNames.add((SNIServerName) new SNIHostName("www.example.com"));
- dupeNames.add((SNIServerName) new SNIHostName("www.example.com"));
- try {
- p.setServerNames(dupeNames);
- fail("Should throw IllegalArgumentException when names are duplicated");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void test_SSLParameters_setServerNames_setNull_getNull() throws Exception {
- SSLParameters p = new SSLParameters();
- p.setServerNames(Collections.singletonList(
- (SNIServerName) new SNIHostName("www.example.com")));
- assertNotNull(p.getServerNames());
- p.setServerNames(null);
- assertNull(p.getServerNames());
- }
-
- public void test_SSLParameters_setServerNames_setEmpty_getEmpty() throws Exception {
- SSLParameters p = new SSLParameters();
- p.setServerNames(new ArrayList<SNIServerName>());
- Collection<SNIServerName> actual = p.getServerNames();
- assertNotNull(actual);
- assertEquals(0, actual.size());
- }
-
- public void test_SSLParameters_getServerNames_unmodifiable() throws Exception {
- SSLParameters p = new SSLParameters();
- p.setServerNames(Collections.singletonList(
- (SNIServerName) new SNIHostName("www.example.com")));
- Collection<SNIServerName> actual = p.getServerNames();
- try {
- actual.add((SNIServerName) new SNIHostName("www.foo.com"));
- fail("Should not allow modifications to the list");
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- public void test_SSLParameters_setSNIMatchers_duplicatedNameThrows() throws Exception {
- SSLParameters p = new SSLParameters();
- ArrayList<SNIMatcher> dupeMatchers = new ArrayList<SNIMatcher>();
- dupeMatchers.add(SNIHostName.createSNIMatcher("www\\.example\\.com"));
- dupeMatchers.add(SNIHostName.createSNIMatcher("www\\.example\\.com"));
- try {
- p.setSNIMatchers(dupeMatchers);
- fail("Should throw IllegalArgumentException when matchers are duplicated");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void test_SSLParameters_setSNIMatchers_setNull_getNull() throws Exception {
- SSLParameters p = new SSLParameters();
- p.setSNIMatchers(Collections.singletonList(
- SNIHostName.createSNIMatcher("www\\.example\\.com")));
- assertNotNull(p.getSNIMatchers());
- p.setSNIMatchers(null);
- assertNull(p.getSNIMatchers());
- }
-
- public void test_SSLParameters_setSNIMatchers_setEmpty_getEmpty() throws Exception {
- SSLParameters p = new SSLParameters();
- p.setSNIMatchers(Collections.singletonList(
- SNIHostName.createSNIMatcher("www\\.example\\.com")));
- assertEquals(1, p.getSNIMatchers().size());
- p.setSNIMatchers(Collections.<SNIMatcher>emptyList());
- Collection<SNIMatcher> actual = p.getSNIMatchers();
- assertNotNull(actual);
- assertEquals(0, actual.size());
- }
-
- public void test_SSLParameters_getSNIMatchers_unmodifiable() throws Exception {
- SSLParameters p = new SSLParameters();
- p.setSNIMatchers(Collections.singletonList(
- SNIHostName.createSNIMatcher("www\\.example\\.com")));
- Collection<SNIMatcher> actual = p.getSNIMatchers();
- try {
- actual.add(SNIHostName.createSNIMatcher("www\\.google\\.com"));
- fail("Should not allow modification of list");
- } catch (UnsupportedOperationException expected) {
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
deleted file mode 100644
index cda1fb8..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2013 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.javax.net.ssl;
-
-import javax.net.ssl.SSLServerSocketFactory;
-import junit.framework.TestCase;
-
-public class SSLServerSocketFactoryTest extends TestCase {
-
- public void testDefaultConfiguration() throws Exception {
- SSLConfigurationAsserts.assertSSLServerSocketFactoryDefaultConfiguration(
- (SSLServerSocketFactory) SSLServerSocketFactory.getDefault());
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
index 04f9252..b69ecc7 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
@@ -17,53 +17,10 @@
package libcore.javax.net.ssl;
import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
import junit.framework.TestCase;
-import java.util.Arrays;
public class SSLServerSocketTest extends TestCase {
- public void testDefaultConfiguration() throws Exception {
- SSLConfigurationAsserts.assertSSLServerSocketDefaultConfiguration(
- (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket());
- }
-
- public void testSetEnabledCipherSuitesAffectsGetter() throws Exception {
- SSLServerSocket socket =
- (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
- String[] cipherSuites = new String[] {socket.getSupportedCipherSuites()[0]};
- socket.setEnabledCipherSuites(cipherSuites);
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(socket.getEnabledCipherSuites()));
- }
-
- public void testSetEnabledCipherSuitesStoresCopy() throws Exception {
- SSLServerSocket socket =
- (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
- String[] array = new String[] {socket.getEnabledCipherSuites()[0]};
- String originalFirstElement = array[0];
- socket.setEnabledCipherSuites(array);
- array[0] = "Modified after having been set";
- assertEquals(originalFirstElement, socket.getEnabledCipherSuites()[0]);
- }
-
- public void testSetEnabledProtocolsAffectsGetter() throws Exception {
- SSLServerSocket socket =
- (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
- String[] protocols = new String[] {socket.getSupportedProtocols()[0]};
- socket.setEnabledProtocols(protocols);
- assertEquals(Arrays.asList(protocols), Arrays.asList(socket.getEnabledProtocols()));
- }
-
- public void testSetEnabledProtocolsStoresCopy() throws Exception {
- SSLServerSocket socket =
- (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
- String[] array = new String[] {socket.getEnabledProtocols()[0]};
- String originalFirstElement = array[0];
- socket.setEnabledProtocols(array);
- array[0] = "Modified after having been set";
- assertEquals(originalFirstElement, socket.getEnabledProtocols()[0]);
- }
-
// We modified the toString() of SSLServerSocket, and it's based on the output
// of ServerSocket.toString(), so we want to make sure that a change in
// ServerSocket.toString() doesn't cause us to output nonsense.
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSessionContextTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSessionContextTest.java
deleted file mode 100644
index d75dc23..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSessionContextTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSocket;
-import junit.framework.TestCase;
-
-public class SSLSessionContextTest extends TestCase {
-
- public static final void assertSSLSessionContextSize(int expected, TestSSLContext c) {
- assertSSLSessionContextSize(expected,
- c.clientContext.getClientSessionContext(),
- c.serverContext.getServerSessionContext());
- assertSSLSessionContextSize(0,
- c.serverContext.getClientSessionContext(),
- c.clientContext.getServerSessionContext());
- }
-
- public static final void assertSSLSessionContextSize(int expected,
- SSLSessionContext client,
- SSLSessionContext server) {
- assertSSLSessionContextSize(expected, client, false);
- assertSSLSessionContextSize(expected, server, true);
- }
-
- public static final void assertSSLSessionContextSize(int expected,
- SSLSessionContext s,
- boolean server) {
- int size = Collections.list(s.getIds()).size();
- if (server && TestSSLContext.sslServerSocketSupportsSessionTickets()) {
- assertEquals(0, size);
- } else {
- assertEquals(expected, size);
- }
- }
-
- public void test_SSLSessionContext_getIds() {
- TestSSLContext c = TestSSLContext.create();
- assertSSLSessionContextSize(0, c);
- c.close();
-
- TestSSLSocketPair s = TestSSLSocketPair.create();
- assertSSLSessionContextSize(1, s.c);
- Enumeration clientIds = s.c.clientContext.getClientSessionContext().getIds();
- Enumeration serverIds = s.c.serverContext.getServerSessionContext().getIds();
- byte[] clientId = (byte[]) clientIds.nextElement();
- assertEquals(32, clientId.length);
- if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
- assertFalse(serverIds.hasMoreElements());
- } else {
- byte[] serverId = (byte[]) serverIds.nextElement();
- assertEquals(32, serverId.length);
- assertTrue(Arrays.equals(clientId, serverId));
- }
- s.close();
- }
-
- public void test_SSLSessionContext_getSession() {
- TestSSLContext c = TestSSLContext.create();
- try {
- c.clientContext.getClientSessionContext().getSession(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(c.clientContext.getClientSessionContext().getSession(new byte[0]));
- assertNull(c.clientContext.getClientSessionContext().getSession(new byte[1]));
- try {
- c.serverContext.getServerSessionContext().getSession(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(c.serverContext.getServerSessionContext().getSession(new byte[0]));
- assertNull(c.serverContext.getServerSessionContext().getSession(new byte[1]));
- c.close();
-
- TestSSLSocketPair s = TestSSLSocketPair.create();
- SSLSessionContext client = s.c.clientContext.getClientSessionContext();
- SSLSessionContext server = s.c.serverContext.getServerSessionContext();
- byte[] clientId = (byte[]) client.getIds().nextElement();
- assertNotNull(client.getSession(clientId));
- assertTrue(Arrays.equals(clientId, client.getSession(clientId).getId()));
- if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
- assertFalse(server.getIds().hasMoreElements());
- } else {
- byte[] serverId = (byte[]) server.getIds().nextElement();
- assertNotNull(server.getSession(serverId));
- assertTrue(Arrays.equals(serverId, server.getSession(serverId).getId()));
- }
- s.close();
- }
-
- public void test_SSLSessionContext_getSessionCacheSize() {
- TestSSLContext c = TestSSLContext.create();
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE,
- c.clientContext.getClientSessionContext().getSessionCacheSize());
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE,
- c.serverContext.getServerSessionContext().getSessionCacheSize());
- c.close();
-
- TestSSLSocketPair s = TestSSLSocketPair.create();
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE,
- s.c.clientContext.getClientSessionContext().getSessionCacheSize());
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE,
- s.c.serverContext.getServerSessionContext().getSessionCacheSize());
- s.close();
- }
-
- public void test_SSLSessionContext_setSessionCacheSize_noConnect() {
- TestSSLContext c = TestSSLContext.create();
- assertNoConnectSetSessionCacheSizeBehavior(
- TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE,
- c.clientContext.getClientSessionContext());
- assertNoConnectSetSessionCacheSizeBehavior(
- TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE,
- c.serverContext.getServerSessionContext());
- c.close();
- }
-
- private static void assertNoConnectSetSessionCacheSizeBehavior(int expectedDefault,
- SSLSessionContext s) {
- try {
- s.setSessionCacheSize(-1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- assertEquals(expectedDefault, s.getSessionCacheSize());
- s.setSessionCacheSize(1);
- assertEquals(1, s.getSessionCacheSize());
- }
-
- public void test_SSLSessionContext_setSessionCacheSize_oneConnect() {
- TestSSLSocketPair s = TestSSLSocketPair.create();
- SSLSessionContext client = s.c.clientContext.getClientSessionContext();
- SSLSessionContext server = s.c.serverContext.getServerSessionContext();
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE,
- client.getSessionCacheSize());
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE,
- server.getSessionCacheSize());
- assertSSLSessionContextSize(1, s.c);
- s.close();
- }
-
- public void test_SSLSessionContext_setSessionCacheSize_dynamic() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLSessionContext client = c.clientContext.getClientSessionContext();
- SSLSessionContext server = c.serverContext.getServerSessionContext();
-
- String[] supportedCipherSuites = c.serverSocket.getSupportedCipherSuites();
- c.serverSocket.setEnabledCipherSuites(supportedCipherSuites);
- LinkedList<String> uniqueCipherSuites
- = new LinkedList(Arrays.asList(supportedCipherSuites));
- // only use RSA cipher suites which will work with our TrustProvider
- Iterator<String> i = uniqueCipherSuites.iterator();
- while (i.hasNext()) {
- String cipherSuite = i.next();
-
- // Certificate key length too long for export ciphers
- if (cipherSuite.startsWith("SSL_RSA_EXPORT_")) {
- i.remove();
- continue;
- }
-
- if (cipherSuite.startsWith("SSL_RSA_")) {
- continue;
- }
- if (cipherSuite.startsWith("TLS_RSA_")) {
- continue;
- }
- if (cipherSuite.startsWith("TLS_DHE_RSA_")) {
- continue;
- }
- if (cipherSuite.startsWith("SSL_DHE_RSA_")) {
- continue;
- }
- i.remove();
- }
-
- /*
- * having more than 3 uniqueCipherSuites is a test
- * requirement, not a requirement of the interface or
- * implementation. It simply allows us to make sure that we
- * will not get a cached session ID since we'll have to
- * renegotiate a new session due to the new cipher suite
- * requirement. even this test only really needs three if it
- * reused the unique cipher suites every time it resets the
- * session cache.
- */
- assertTrue(uniqueCipherSuites.size() >= 3);
- String cipherSuite1 = uniqueCipherSuites.get(0);
- String cipherSuite2 = uniqueCipherSuites.get(1);
- String cipherSuite3 = uniqueCipherSuites.get(2);
-
- List<SSLSocket[]> toClose = new ArrayList<SSLSocket[]>();
- toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }, null));
- assertSSLSessionContextSize(1, c);
- toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }, null));
- assertSSLSessionContextSize(2, c);
- toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }, null));
- assertSSLSessionContextSize(3, c);
-
- client.setSessionCacheSize(1);
- server.setSessionCacheSize(1);
- assertEquals(1, client.getSessionCacheSize());
- assertEquals(1, server.getSessionCacheSize());
- assertSSLSessionContextSize(1, c);
- toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }, null));
- assertSSLSessionContextSize(1, c);
-
- client.setSessionCacheSize(2);
- server.setSessionCacheSize(2);
- toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }, null));
- assertSSLSessionContextSize(2, c);
- toClose.add(TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }, null));
- assertSSLSessionContextSize(2, c);
-
- for (SSLSocket[] pair : toClose) {
- for (SSLSocket s : pair) {
- s.close();
- }
- }
- c.close();
- }
-
- public void test_SSLSessionContext_getSessionTimeout() {
- TestSSLContext c = TestSSLContext.create();
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT,
- c.clientContext.getClientSessionContext().getSessionTimeout());
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT,
- c.serverContext.getServerSessionContext().getSessionTimeout());
- c.close();
-
- TestSSLSocketPair s = TestSSLSocketPair.create();
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT,
- s.c.clientContext.getClientSessionContext().getSessionTimeout());
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT,
- s.c.serverContext.getServerSessionContext().getSessionTimeout());
- s.close();
- }
-
- public void test_SSLSessionContext_setSessionTimeout() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT,
- c.clientContext.getClientSessionContext().getSessionTimeout());
- assertEquals(TestSSLContext.EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT,
- c.serverContext.getServerSessionContext().getSessionTimeout());
- c.clientContext.getClientSessionContext().setSessionTimeout(0);
- c.serverContext.getServerSessionContext().setSessionTimeout(0);
- assertEquals(0, c.clientContext.getClientSessionContext().getSessionTimeout());
- assertEquals(0, c.serverContext.getServerSessionContext().getSessionTimeout());
-
- try {
- c.clientContext.getClientSessionContext().setSessionTimeout(-1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- c.serverContext.getServerSessionContext().setSessionTimeout(-1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- c.close();
-
- TestSSLSocketPair s = TestSSLSocketPair.create();
- assertSSLSessionContextSize(1, s.c);
- Thread.sleep(1 * 1000);
- s.c.clientContext.getClientSessionContext().setSessionTimeout(1);
- s.c.serverContext.getServerSessionContext().setSessionTimeout(1);
- assertSSLSessionContextSize(0, s.c);
- s.close();
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
deleted file mode 100644
index f58211d..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.util.Arrays;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import javax.net.ServerSocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-
-
-public class SSLSessionTest extends TestCase {
-
- public void test_SSLSocket_TestSSLSessions_create() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNotNull(s.invalid);
- assertFalse(s.invalid.isValid());
- assertTrue(s.server.isValid());
- assertTrue(s.client.isValid());
- s.close();
- }
-
- public void test_SSLSession_getApplicationBufferSize() {
- TestSSLSessions s = TestSSLSessions.create();
- assertTrue(s.invalid.getApplicationBufferSize() > 0);
- assertTrue(s.server.getApplicationBufferSize() > 0);
- assertTrue(s.client.getApplicationBufferSize() > 0);
- s.close();
- }
-
- public void test_SSLSession_getCipherSuite() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNotNull(s.invalid.getCipherSuite());
- assertEquals(StandardNames.CIPHER_SUITE_INVALID, s.invalid.getCipherSuite());
- assertNotNull(s.server.getCipherSuite());
- assertNotNull(s.client.getCipherSuite());
- assertEquals(s.server.getCipherSuite(),
- s.client.getCipherSuite());
- StandardNames.assertValidCipherSuites(new String[] {s.server.getCipherSuite()});
- s.close();
- }
-
- public void test_SSLSession_getCreationTime() {
- // We use OpenSSL, which only returns times accurate to the nearest second.
- // NativeCrypto just multiplies by 1000, which looks like truncation, which
- // would make it appear as if the OpenSSL side of things was created before
- // we called it.
- long t0 = System.currentTimeMillis() / 1000;
- TestSSLSessions s = TestSSLSessions.create();
- long t1 = System.currentTimeMillis() / 1000;
-
- assertTrue(s.invalid.getCreationTime() > 0);
-
- long sTime = s.server.getCreationTime() / 1000;
- assertTrue(sTime + " >= " + t0, sTime >= t0);
- assertTrue(sTime + " <= " + t1, sTime <= t1);
-
- long cTime = s.client.getCreationTime() / 1000;
- assertTrue(cTime + " >= " + t0, cTime >= t0);
- assertTrue(cTime + " <= " + t1, cTime <= t1);
-
- s.close();
- }
-
- public void test_SSLSession_getId() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNotNull(s.invalid.getId());
- assertNotNull(s.server.getId());
- assertNotNull(s.client.getId());
- assertEquals(0, s.invalid.getId().length);
- if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
- assertEquals(0, s.server.getId().length);
- } else {
- assertEquals(32, s.server.getId().length);
- assertTrue(Arrays.equals(s.server.getId(), s.client.getId()));
- }
- assertEquals(32, s.client.getId().length);
- s.close();
- }
-
- public void test_SSLSession_getLastAccessedTime() {
- TestSSLSessions s = TestSSLSessions.create();
- assertTrue(s.invalid.getLastAccessedTime() > 0);
- assertTrue(s.server.getLastAccessedTime() > 0);
- assertTrue(s.client.getLastAccessedTime() > 0);
- assertTrue("s.server.getLastAccessedTime()=" + s.server.getLastAccessedTime() + " " +
- "s.client.getLastAccessedTime()=" + s.client.getLastAccessedTime(),
- Math.abs(s.server.getLastAccessedTime()
- - s.client.getLastAccessedTime()) <= 1 * 1000);
- assertTrue(s.server.getLastAccessedTime() >=
- s.server.getCreationTime());
- assertTrue(s.client.getLastAccessedTime() >=
- s.client.getCreationTime());
- s.close();
- }
-
- public void test_SSLSession_getLocalCertificates() throws Exception {
- TestSSLSessions s = TestSSLSessions.create();
- assertNull(s.invalid.getLocalCertificates());
- assertNull(s.client.getLocalCertificates());
- assertNotNull(s.server.getLocalCertificates());
- TestKeyStore.assertChainLength(s.server.getLocalCertificates());
- TestSSLContext.assertServerCertificateChain(s.s.c.serverTrustManager,
- s.server.getLocalCertificates());
- TestSSLContext.assertCertificateInKeyStore(s.server.getLocalCertificates()[0],
- s.s.c.serverKeyStore);
- s.close();
- }
-
- public void test_SSLSession_getLocalPrincipal() throws Exception {
- TestSSLSessions s = TestSSLSessions.create();
- assertNull(s.invalid.getLocalPrincipal());
- assertNull(s.client.getLocalPrincipal());
- assertNotNull(s.server.getLocalPrincipal());
- assertNotNull(s.server.getLocalPrincipal().getName());
- TestSSLContext.assertCertificateInKeyStore(s.server.getLocalPrincipal(),
- s.s.c.serverKeyStore);
- s.close();
- }
-
- public void test_SSLSession_getPacketBufferSize() {
- TestSSLSessions s = TestSSLSessions.create();
- assertTrue(s.invalid.getPacketBufferSize() > 0);
- assertTrue(s.server.getPacketBufferSize() > 0);
- assertTrue(s.client.getPacketBufferSize() > 0);
- s.close();
- }
-
- public void test_SSLSession_getPeerCertificateChain() throws Exception {
- TestSSLSessions s = TestSSLSessions.create();
- try {
- s.invalid.getPeerCertificateChain();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- assertNotNull(s.client.getPeerCertificates());
- TestKeyStore.assertChainLength(s.client.getPeerCertificateChain());
- try {
- assertNull(s.server.getPeerCertificateChain());
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- s.close();
- }
-
- public void test_SSLSession_getPeerCertificates() throws Exception {
- TestSSLSessions s = TestSSLSessions.create();
- try {
- s.invalid.getPeerCertificates();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- assertNotNull(s.client.getPeerCertificates());
- TestKeyStore.assertChainLength(s.client.getPeerCertificates());
- TestSSLContext.assertServerCertificateChain(s.s.c.serverTrustManager,
- s.client.getPeerCertificates());
- TestSSLContext.assertCertificateInKeyStore(s.client.getPeerCertificates()[0],
- s.s.c.serverKeyStore);
- try {
- s.server.getPeerCertificates();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- s.close();
- }
-
- public void test_SSLSession_getPeerHost() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNull(s.invalid.getPeerHost());
- assertNotNull(s.server.getPeerHost());
- assertNotNull(s.client.getPeerHost());
- s.close();
- }
-
- public void test_SSLSession_getPeerPort() {
- TestSSLSessions s = TestSSLSessions.create();
- assertEquals(-1, s.invalid.getPeerPort());
- assertTrue(s.server.getPeerPort() > 0);
- assertEquals(s.s.c.port, s.client.getPeerPort());
- s.close();
- }
-
- public void test_SSLSession_getPeerPrincipal() throws Exception {
- TestSSLSessions s = TestSSLSessions.create();
- try {
- s.invalid.getPeerPrincipal();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- try {
- s.server.getPeerPrincipal();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- assertNotNull(s.client.getPeerPrincipal());
- assertNotNull(s.client.getPeerPrincipal().getName());
- TestSSLContext.assertCertificateInKeyStore(s.client.getPeerPrincipal(),
- s.s.c.serverKeyStore);
- s.close();
- }
-
- public void test_SSLSession_getProtocol() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNotNull(s.invalid.getProtocol());
- assertEquals("NONE", s.invalid.getProtocol());
- assertNotNull(s.server.getProtocol());
- assertNotNull(s.client.getProtocol());
- assertEquals(s.server.getProtocol(),
- s.client.getProtocol());
- assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(s.server.getProtocol()));
- s.close();
- }
-
- public void test_SSLSession_getSessionContext() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNull(s.invalid.getSessionContext());
- assertNotNull(s.server.getSessionContext());
- assertNotNull(s.client.getSessionContext());
- assertEquals(s.s.c.serverContext.getServerSessionContext(),
- s.server.getSessionContext());
- assertEquals(s.s.c.clientContext.getClientSessionContext(),
- s.client.getSessionContext());
- assertNotSame(s.server.getSessionContext(),
- s.client.getSessionContext());
- s.close();
- }
-
- public void test_SSLSession_getValue() {
- TestSSLSessions s = TestSSLSessions.create();
- try {
- s.invalid.getValue(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- assertNull(s.invalid.getValue("BOGUS"));
- s.close();
- }
-
- public void test_SSLSession_getValueNames() {
- TestSSLSessions s = TestSSLSessions.create();
- assertNotNull(s.invalid.getValueNames());
- assertEquals(0, s.invalid.getValueNames().length);
- s.close();
- }
-
- public void test_SSLSession_invalidate() {
- TestSSLSessions s = TestSSLSessions.create();
-
- assertFalse(s.invalid.isValid());
- s.invalid.invalidate();
- assertFalse(s.invalid.isValid());
- assertNull(s.invalid.getSessionContext());
-
- assertTrue(s.server.isValid());
- s.server.invalidate();
- assertFalse(s.server.isValid());
- assertNull(s.server.getSessionContext());
-
- assertTrue(s.client.isValid());
- s.client.invalidate();
- assertFalse(s.client.isValid());
- assertNull(s.client.getSessionContext());
-
- s.close();
- }
-
- public void test_SSLSession_isValid() {
- TestSSLSessions s = TestSSLSessions.create();
- assertFalse(s.invalid.isValid());
- assertTrue(s.server.isValid());
- assertTrue(s.client.isValid());
- s.close();
- }
-
- public void test_SSLSession_putValue() {
- TestSSLSessions s = TestSSLSessions.create();
- String key = "KEY";
- String value = "VALUE";
- assertNull(s.invalid.getValue(key));
- assertEquals(0, s.invalid.getValueNames().length);
- s.invalid.putValue(key, value);
- assertSame(value, s.invalid.getValue(key));
- assertEquals(1, s.invalid.getValueNames().length);
- assertEquals(key, s.invalid.getValueNames()[0]);
- s.close();
- }
-
- public void test_SSLSession_removeValue() {
- TestSSLSessions s = TestSSLSessions.create();
- String key = "KEY";
- String value = "VALUE";
- s.invalid.putValue(key, value);
- assertEquals(1, s.invalid.getValueNames().length);
- assertEquals(key, s.invalid.getValueNames()[0]);
- s.invalid.removeValue(key);
- assertNull(s.invalid.getValue(key));
- assertEquals(0, s.invalid.getValueNames().length);
- s.close();
- }
-
- private static String alterOriginalHostName(InetAddress inetAddress, String originalHostName)
- throws Exception {
- Method getHolder = InetAddress.class.getDeclaredMethod("holder");
- getHolder.setAccessible(true);
-
- Field originalHostNameField = Class.forName("java.net.InetAddress$InetAddressHolder")
- .getDeclaredField("originalHostName");
- originalHostNameField.setAccessible(true);
-
- Object holder = getHolder.invoke(inetAddress);
- String oldValue = (String)originalHostNameField.get(holder);
- originalHostNameField.set(holder, originalHostName);
- return oldValue;
- }
-
- // http://b/35942385
- public void test_SSLSession_getPeerHostFromInetAddress() throws Exception {
- InetAddress inetAddress = InetAddress.getByName("localhost");
- String oldOriginalHostName = alterOriginalHostName(inetAddress, "foobar");
- try {
- final TestSSLContext c = TestSSLContext.create();
- final SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
- InetAddress.getByName("localhost"), c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
-
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(() -> {server.startHandshake(); return null;});
- executor.shutdown();
- client.startHandshake();
-
- SSLSession sslSession = client.getSession();
- assertEquals("foobar", sslSession.getPeerHost());
-
- future.get();
- client.close();
- server.close();
- c.close();
- } finally {
- // Restore the original value (InetAddress objects are cached).
- alterOriginalHostName(inetAddress, oldOriginalHostName);
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
index ebf72f0..8fe329c 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
@@ -46,12 +46,6 @@
public class SSLSocketFactoryTest extends TestCase {
private static final String SSL_PROPERTY = "ssl.SocketFactory.provider";
- public void test_SSLSocketFactory_getDefault() {
- SocketFactory sf = SSLSocketFactory.getDefault();
- assertNotNull(sf);
- assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
- }
-
public static class FakeSSLSocketProvider extends Provider {
public FakeSSLSocketProvider() {
super("FakeSSLSocketProvider", 1.0, "Testing provider");
@@ -210,47 +204,6 @@
return origProvider;
}
- public void test_SSLSocketFactory_defaultConfiguration() throws Exception {
- SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(
- (SSLSocketFactory) SSLSocketFactory.getDefault());
- }
-
- public void test_SSLSocketFactory_getDefaultCipherSuitesReturnsCopies() {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- assertNotSame(sf.getDefaultCipherSuites(), sf.getDefaultCipherSuites());
- }
-
- public void test_SSLSocketFactory_getSupportedCipherSuitesReturnsCopies() {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- assertNotSame(sf.getSupportedCipherSuites(), sf.getSupportedCipherSuites());
- }
-
- public void test_SSLSocketFactory_createSocket() throws Exception {
- try {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- Socket s = sf.createSocket(null, null, -1, false);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- Socket ssl = sf.createSocket(new Socket(), null, -1, false);
- fail();
- } catch (SocketException expected) {
- }
-
- ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0);
- InetSocketAddress sa = (InetSocketAddress) ss.getLocalSocketAddress();
- InetAddress host = sa.getAddress();
- int port = sa.getPort();
- Socket s = new Socket(host, port);
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- Socket ssl = sf.createSocket(s, null, -1, false);
- assertNotNull(ssl);
- assertTrue(SSLSocket.class.isAssignableFrom(ssl.getClass()));
- }
-
public void test_SSLSocketFactory_createSocket_withConsumedInputStream()
throws Exception {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 7141a39..fe5e1ae 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -16,2685 +16,14 @@
package libcore.javax.net.ssl;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.ByteArrayInputStream;
-import java.io.Closeable;
-import java.io.DataInputStream;
-import java.io.EOFException;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.lang.reflect.Method;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.Key;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.SignatureSpi;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.RSAKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ServerSocketFactory;
-import javax.net.SocketFactory;
-import javax.net.ssl.ExtendedSSLSession;
-import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SNIHostName;
-import javax.net.ssl.SNIMatcher;
-import javax.net.ssl.SNIServerName;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLProtocolException;
-import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.StandardConstants;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-import libcore.tlswire.handshake.CipherSuite;
-import libcore.tlswire.handshake.ClientHello;
-import libcore.tlswire.handshake.CompressionMethod;
-import libcore.tlswire.handshake.EllipticCurve;
-import libcore.tlswire.handshake.EllipticCurvesHelloExtension;
-import libcore.tlswire.handshake.HandshakeMessage;
-import libcore.tlswire.handshake.HelloExtension;
-import libcore.tlswire.handshake.ServerNameHelloExtension;
-import libcore.tlswire.record.TlsProtocols;
-import libcore.tlswire.record.TlsRecord;
-import libcore.tlswire.util.TlsProtocolVersion;
-import tests.net.DelegatingSSLSocketFactory;
-import tests.util.ForEachRunner;
-import tests.util.Pair;
public class SSLSocketTest extends TestCase {
- public void test_SSLSocket_defaultConfiguration() throws Exception {
- SSLConfigurationAsserts.assertSSLSocketDefaultConfiguration(
- (SSLSocket) SSLSocketFactory.getDefault().createSocket());
- }
-
- public void test_SSLSocket_getSupportedCipherSuites_returnsCopies() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- assertNotSame(ssl.getSupportedCipherSuites(), ssl.getSupportedCipherSuites());
- }
-
- public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
- // note the rare usage of non-RSA keys
- TestKeyStore testKeyStore = new TestKeyStore.Builder()
- .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
- .aliasPrefix("rsa-dsa-ec")
- .ca(true)
- .build();
- StringBuilder error = new StringBuilder();
- test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore, error);
- if (error.length() > 0) {
- throw new Exception("One or more problems in "
- + "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error);
- }
- }
- private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
- StringBuilder error)
- throws Exception {
-
- String clientToServerString = "this is sent from the client to the server...";
- String serverToClientString = "... and this from the server to the client";
- byte[] clientToServer = clientToServerString.getBytes(UTF_8);
- byte[] serverToClient = serverToClientString.getBytes(UTF_8);
-
- KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
- new PSKKeyManagerProxy() {
- @Override
- protected SecretKey getKey(String identityHint, String identity, Socket socket) {
- return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
- }
- });
- TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
- testKeyStore, testKeyStore,
- new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager});
-
- String[] cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
-
- for (String cipherSuite : cipherSuites) {
- boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
- try {
- /*
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
- * its own, but instead in conjunction with other
- * cipher suites.
- */
- if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
- continue;
- }
- /*
- * Similarly with the TLS_FALLBACK_SCSV suite, it is not
- * a selectable suite, but is used in conjunction with
- * other cipher suites.
- */
- if (cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
- continue;
- }
- /*
- * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
- * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
- * #KRBRequire
- */
- if (cipherSuite.startsWith("TLS_KRB5_")) {
- continue;
- }
-
- String[] clientCipherSuiteArray = new String[] {
- cipherSuite,
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION };
- String[] serverCipherSuiteArray = clientCipherSuiteArray;
- SSLSocket[] pair = TestSSLSocketPair.connect(c,
- clientCipherSuiteArray,
- serverCipherSuiteArray);
-
- SSLSocket server = pair[0];
- SSLSocket client = pair[1];
-
- // Check that the client can read the message sent by the server
- server.getOutputStream().write(serverToClient);
- byte[] clientFromServer = new byte[serverToClient.length];
- readFully(client.getInputStream(), clientFromServer);
- assertEquals(serverToClientString, new String(clientFromServer));
-
- // Check that the server can read the message sent by the client
- client.getOutputStream().write(clientToServer);
- byte[] serverFromClient = new byte[clientToServer.length];
- readFully(server.getInputStream(), serverFromClient);
- assertEquals(clientToServerString, new String(serverFromClient));
-
- // Check that the server and the client cannot read anything else
- // (reads should time out)
- server.setSoTimeout(10);
- try {
- server.getInputStream().read();
- fail();
- } catch (IOException expected) {}
- client.setSoTimeout(10);
- try {
- client.getInputStream().read();
- fail();
- } catch (IOException expected) {}
-
- client.close();
- server.close();
- assertFalse(errorExpected);
- } catch (Exception maybeExpected) {
- if (!errorExpected) {
- String message = ("Problem trying to connect cipher suite " + cipherSuite);
- System.out.println(message);
- maybeExpected.printStackTrace();
- error.append(message);
- error.append('\n');
- }
- }
- }
- c.close();
- }
-
- public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites());
- }
-
- public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] array = new String[] {ssl.getEnabledCipherSuites()[0]};
- String originalFirstElement = array[0];
- ssl.setEnabledCipherSuites(array);
- array[0] = "Modified after having been set";
- assertEquals(originalFirstElement, ssl.getEnabledCipherSuites()[0]);
- }
-
- public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
-
- try {
- ssl.setEnabledCipherSuites(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- ssl.setEnabledCipherSuites(new String[1]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- ssl.setEnabledCipherSuites(new String[0]);
- ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
- ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
-
- // Check that setEnabledCipherSuites affects getEnabledCipherSuites
- String[] cipherSuites = new String[] { ssl.getSupportedCipherSuites()[0] };
- ssl.setEnabledCipherSuites(cipherSuites);
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
- }
-
- public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- assertNotSame(ssl.getSupportedProtocols(), ssl.getSupportedProtocols());
- }
-
- public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols());
- }
-
- public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] array = new String[] {ssl.getEnabledProtocols()[0]};
- String originalFirstElement = array[0];
- ssl.setEnabledProtocols(array);
- array[0] = "Modified after having been set";
- assertEquals(originalFirstElement, ssl.getEnabledProtocols()[0]);
- }
-
- public void test_SSLSocket_setEnabledProtocols() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
-
- try {
- ssl.setEnabledProtocols(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- ssl.setEnabledProtocols(new String[1]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- ssl.setEnabledProtocols(new String[] { "Bogus" } );
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.setEnabledProtocols(new String[0]);
- ssl.setEnabledProtocols(ssl.getEnabledProtocols());
- ssl.setEnabledProtocols(ssl.getSupportedProtocols());
-
- // Check that setEnabledProtocols affects getEnabledProtocols
- for (String protocol : ssl.getSupportedProtocols()) {
- if ("SSLv2Hello".equals(protocol)) {
- try {
- ssl.setEnabledProtocols(new String[] { protocol });
- fail("Should fail when SSLv2Hello is set by itself");
- } catch (IllegalArgumentException expected) {}
- } else {
- String[] protocols = new String[] { protocol };
- ssl.setEnabledProtocols(protocols);
- assertEquals(Arrays.deepToString(protocols),
- Arrays.deepToString(ssl.getEnabledProtocols()));
- }
- }
- }
-
- /**
- * Tests that when the client has a hole in their supported protocol list, the
- * lower span of contiguous protocols is used in practice.
- */
- public void test_SSLSocket_noncontiguousProtocols_useLower() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLContext serverContext = c.serverContext;
- SSLContext clientContext = c.clientContext;
- SSLSocket client = (SSLSocket)
- clientContext.getSocketFactory().createSocket(c.host, c.port);
- client.setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1"});
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- server.setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1.1", "TLSv1"});
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
-
- assertEquals("TLSv1", client.getSession().getProtocol());
-
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- /**
- * Tests that protocol negotiation succeeds when the highest-supported protocol
- * for both client and server isn't supported by the other.
- */
- public void test_SSLSocket_noncontiguousProtocols_canNegotiate() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLContext serverContext = c.serverContext;
- SSLContext clientContext = c.clientContext;
- SSLSocket client = (SSLSocket)
- clientContext.getSocketFactory().createSocket(c.host, c.port);
- client.setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1"});
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- server.setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1"});
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
-
- assertEquals("TLSv1", client.getSession().getProtocol());
-
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_getSession() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- SSLSession session = ssl.getSession();
- assertNotNull(session);
- assertFalse(session.isValid());
- }
-
- public void test_SSLSocket_getHandshakeSession() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- SSLSession session = ssl.getHandshakeSession();
- assertNull(session);
- }
-
- public void test_SSLSocket_startHandshake() throws Exception {
- final TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- assertNotNull(server.getSession());
- assertNull(server.getHandshakeSession());
- try {
- server.getSession().getPeerCertificates();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- Certificate[] localCertificates = server.getSession().getLocalCertificates();
- assertNotNull(localCertificates);
- TestKeyStore.assertChainLength(localCertificates);
- assertNotNull(localCertificates[0]);
- TestSSLContext.assertServerCertificateChain(c.serverTrustManager,
- localCertificates);
- TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
- c.serverKeyStore);
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
- assertNotNull(client.getSession());
- assertNull(client.getSession().getLocalCertificates());
- Certificate[] peerCertificates = client.getSession().getPeerCertificates();
- assertNotNull(peerCertificates);
- TestKeyStore.assertChainLength(peerCertificates);
- assertNotNull(peerCertificates[0]);
- TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
- peerCertificates);
- TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- private static final class SSLServerSessionIdCallable implements Callable<byte[]> {
- private final SSLSocket server;
- private SSLServerSessionIdCallable(SSLSocket server) {
- this.server = server;
- }
- @Override public byte[] call() throws Exception {
- server.startHandshake();
- assertNotNull(server.getSession());
- assertNotNull(server.getSession().getId());
- return server.getSession().getId();
- }
- }
-
- public void test_SSLSocket_confirmSessionReuse() throws Exception {
- final TestSSLContext c = TestSSLContext.create();
- final ExecutorService executor = Executors.newSingleThreadExecutor();
-
- final SSLSocket client1 = (SSLSocket) c.clientContext.getSocketFactory()
- .createSocket(c.host.getHostName(), c.port);
- final SSLSocket server1 = (SSLSocket) c.serverSocket.accept();
- final Future<byte[]> future1 = executor.submit(new SSLServerSessionIdCallable(server1));
- client1.startHandshake();
- assertNotNull(client1.getSession());
- assertNotNull(client1.getSession().getId());
- final byte[] clientSessionId1 = client1.getSession().getId();
- final byte[] serverSessionId1 = future1.get();
- assertTrue(Arrays.equals(clientSessionId1, serverSessionId1));
- client1.close();
- server1.close();
-
- final SSLSocket client2 = (SSLSocket) c.clientContext.getSocketFactory()
- .createSocket(c.host.getHostName(), c.port);
- final SSLSocket server2 = (SSLSocket) c.serverSocket.accept();
- final Future<byte[]> future2 = executor.submit(new SSLServerSessionIdCallable(server2));
- client2.startHandshake();
- assertNotNull(client2.getSession());
- assertNotNull(client2.getSession().getId());
- final byte[] clientSessionId2 = client2.getSession().getId();
- final byte[] serverSessionId2 = future2.get();
- assertTrue(Arrays.equals(clientSessionId2, serverSessionId2));
- client2.close();
- server2.close();
-
- assertTrue(Arrays.equals(clientSessionId1, clientSessionId2));
-
- executor.shutdown();
- c.close();
- }
-
- public void test_SSLSocket_NoEnabledCipherSuites_Failure() throws Exception {
- TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
- SSLContext.getDefault(), SSLContext.getDefault());
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- client.setEnabledCipherSuites(new String[0]);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- try {
- server.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- return null;
- }
- });
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- future.get();
- server.close();
- client.close();
- c.close();
- }
-
- public void test_SSLSocket_startHandshake_noKeyStore() throws Exception {
- TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
- SSLContext.getDefault(), SSLContext.getDefault());
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- return null;
- }
- });
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- future.get();
- server.close();
- client.close();
- c.close();
- }
-
- public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLContext serverContext = c.serverContext;
- SSLContext clientContext = c.clientContext;
- SSLSocket client = (SSLSocket)
- clientContext.getSocketFactory().createSocket(c.host, c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_HandshakeCompletedListener() throws Exception {
- final TestSSLContext c = TestSSLContext.create();
- final SSLSocket client = (SSLSocket)
- c.clientContext.getSocketFactory().createSocket(c.host, c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- final boolean[] handshakeCompletedListenerCalled = new boolean[1];
- client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
- @Override
- public void handshakeCompleted(HandshakeCompletedEvent event) {
- try {
- SSLSession session = event.getSession();
- String cipherSuite = event.getCipherSuite();
- Certificate[] localCertificates = event.getLocalCertificates();
- Certificate[] peerCertificates = event.getPeerCertificates();
- javax.security.cert.X509Certificate[] peerCertificateChain
- = event.getPeerCertificateChain();
- Principal peerPrincipal = event.getPeerPrincipal();
- Principal localPrincipal = event.getLocalPrincipal();
- Socket socket = event.getSocket();
-
- if (false) {
- System.out.println("Session=" + session);
- System.out.println("CipherSuite=" + cipherSuite);
- System.out.println("LocalCertificates="
- + Arrays.toString(localCertificates));
- System.out.println("PeerCertificates="
- + Arrays.toString(peerCertificates));
- System.out.println("PeerCertificateChain="
- + Arrays.toString(peerCertificateChain));
- System.out.println("PeerPrincipal=" + peerPrincipal);
- System.out.println("LocalPrincipal=" + localPrincipal);
- System.out.println("Socket=" + socket);
- }
-
- assertNotNull(session);
- byte[] id = session.getId();
- assertNotNull(id);
- assertEquals(32, id.length);
- assertNotNull(c.clientContext.getClientSessionContext().getSession(id));
-
- assertNotNull(cipherSuite);
- assertTrue(Arrays.asList(
- client.getEnabledCipherSuites()).contains(cipherSuite));
- assertTrue(Arrays.asList(
- c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
-
- assertNull(localCertificates);
-
- assertNotNull(peerCertificates);
- TestKeyStore.assertChainLength(peerCertificates);
- assertNotNull(peerCertificates[0]);
- TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
- peerCertificates);
- TestSSLContext.assertCertificateInKeyStore(peerCertificates[0],
- c.serverKeyStore);
-
- assertNotNull(peerCertificateChain);
- TestKeyStore.assertChainLength(peerCertificateChain);
- assertNotNull(peerCertificateChain[0]);
- TestSSLContext.assertCertificateInKeyStore(
- peerCertificateChain[0].getSubjectDN(), c.serverKeyStore);
-
- assertNotNull(peerPrincipal);
- TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore);
-
- assertNull(localPrincipal);
-
- assertNotNull(socket);
- assertSame(client, socket);
-
- assertTrue(socket instanceof SSLSocket);
- assertNull(((SSLSocket) socket).getHandshakeSession());
-
- synchronized (handshakeCompletedListenerCalled) {
- handshakeCompletedListenerCalled[0] = true;
- handshakeCompletedListenerCalled.notify();
- }
- handshakeCompletedListenerCalled[0] = true;
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- });
- client.startHandshake();
- future.get();
- if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
- assertNotNull(c.serverContext.getServerSessionContext().getSession(
- client.getSession().getId()));
- }
- synchronized (handshakeCompletedListenerCalled) {
- while (!handshakeCompletedListenerCalled[0]) {
- handshakeCompletedListenerCalled.wait();
- }
- }
- client.close();
- server.close();
- c.close();
- }
-
- private static final class TestUncaughtExceptionHandler implements UncaughtExceptionHandler {
- Throwable actualException;
- @Override public void uncaughtException(Thread thread, Throwable ex) {
- assertNull(actualException);
- actualException = ex;
- }
- }
-
- public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception {
- final Thread self = Thread.currentThread();
- final UncaughtExceptionHandler original = self.getUncaughtExceptionHandler();
-
- final RuntimeException expectedException = new RuntimeException("expected");
- final TestUncaughtExceptionHandler test = new TestUncaughtExceptionHandler();
- self.setUncaughtExceptionHandler(test);
-
- final TestSSLContext c = TestSSLContext.create();
- final SSLSocket client = (SSLSocket)
- c.clientContext.getSocketFactory().createSocket(c.host, c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
- @Override
- public void handshakeCompleted(HandshakeCompletedEvent event) {
- throw expectedException;
- }
- });
- client.startHandshake();
- future.get();
- client.close();
- server.close();
- c.close();
-
- assertSame(expectedException, test.actualException);
- self.setUncaughtExceptionHandler(original);
- }
-
- public void test_SSLSocket_getUseClientMode() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- SSLSocket server = (SSLSocket) c.serverSocket.accept();
- assertTrue(client.getUseClientMode());
- assertFalse(server.getUseClientMode());
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_setUseClientMode() throws Exception {
- // client is client, server is server
- test_SSLSocket_setUseClientMode(true, false);
- // client is server, server is client
- test_SSLSocket_setUseClientMode(true, false);
- // both are client
- try {
- test_SSLSocket_setUseClientMode(true, true);
- fail();
- } catch (SSLProtocolException expected) {
- assertTrue(StandardNames.IS_RI);
- } catch (SSLHandshakeException expected) {
- assertFalse(StandardNames.IS_RI);
- }
-
- // both are server
- try {
- test_SSLSocket_setUseClientMode(false, false);
- fail();
- } catch (SocketTimeoutException|SSLHandshakeException expected) {
- }
- }
-
- private void test_SSLSocket_setUseClientMode(final boolean clientClientMode,
- final boolean serverClientMode)
- throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
-
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<IOException> future = executor.submit(new Callable<IOException>() {
- @Override public IOException call() throws Exception {
- try {
- if (!serverClientMode) {
- server.setSoTimeout(1 * 1000);
- }
- server.setUseClientMode(serverClientMode);
- server.startHandshake();
- return null;
- } catch (SSLHandshakeException e) {
- return e;
- } catch (SocketTimeoutException e) {
- return e;
- }
- }
- });
- executor.shutdown();
- if (!clientClientMode) {
- client.setSoTimeout(1 * 1000);
- }
- client.setUseClientMode(clientClientMode);
- client.startHandshake();
- IOException ioe = future.get();
- if (ioe != null) {
- throw ioe;
- }
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
-
- // can't set after handshake
- TestSSLSocketPair pair = TestSSLSocketPair.create();
- try {
- pair.server.setUseClientMode(false);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- pair.client.setUseClientMode(false);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void test_SSLSocket_untrustedServer() throws Exception {
- TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCA2(),
- TestKeyStore.getServer());
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- return null;
- }
- });
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- assertTrue(expected.getCause() instanceof CertificateException);
- }
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_clientAuth() throws Exception {
- TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCertificate(),
- TestKeyStore.getServer());
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- assertFalse(server.getWantClientAuth());
- assertFalse(server.getNeedClientAuth());
-
- // confirm turning one on by itself
- server.setWantClientAuth(true);
- assertTrue(server.getWantClientAuth());
- assertFalse(server.getNeedClientAuth());
-
- // confirm turning setting on toggles the other
- server.setNeedClientAuth(true);
- assertFalse(server.getWantClientAuth());
- assertTrue(server.getNeedClientAuth());
-
- // confirm toggling back
- server.setWantClientAuth(true);
- assertTrue(server.getWantClientAuth());
- assertFalse(server.getNeedClientAuth());
-
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
- assertNotNull(client.getSession().getLocalCertificates());
- TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
- TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
- client.getSession().getLocalCertificates());
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_clientAuth_bogusAlias() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLContext clientContext = SSLContext.getInstance("TLS");
- X509KeyManager keyManager = new X509KeyManager() {
- @Override public String chooseClientAlias(String[] keyType,
- Principal[] issuers,
- Socket socket) {
- return "bogus";
- }
- @Override public String chooseServerAlias(String keyType,
- Principal[] issuers,
- Socket socket) {
- throw new AssertionError();
- }
- @Override public X509Certificate[] getCertificateChain(String alias) {
- // return null for "bogus" alias
- return null;
- }
- @Override public String[] getClientAliases(String keyType, Principal[] issuers) {
- throw new AssertionError();
- }
- @Override public String[] getServerAliases(String keyType, Principal[] issuers) {
- throw new AssertionError();
- }
- @Override public PrivateKey getPrivateKey(String alias) {
- // return null for "bogus" alias
- return null;
- }
- };
- clientContext.init(new KeyManager[] { keyManager },
- new TrustManager[] { c.clientTrustManager },
- null);
- SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.setNeedClientAuth(true);
- server.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- return null;
- }
- });
-
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- // before we would get a NullPointerException from passing
- // due to the null PrivateKey return by the X509KeyManager.
- }
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_clientAuth_OpaqueKey_RSA() throws Exception {
- run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientCertificate());
- }
-
- public void test_SSLSocket_clientAuth_OpaqueKey_EC_RSA() throws Exception {
- run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcRsaCertificate());
- }
-
- public void test_SSLSocket_clientAuth_OpaqueKey_EC_EC() throws Exception {
- run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcEcCertificate());
- }
-
- private void run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore keyStore) throws Exception {
- try {
- Security.insertProviderAt(new OpaqueProvider(), 1);
-
- final TestSSLContext c = TestSSLContext.create(keyStore, TestKeyStore.getServer());
- SSLContext clientContext = SSLContext.getInstance("TLS");
- final X509KeyManager delegateKeyManager = (X509KeyManager) c.clientKeyManagers[0];
- X509KeyManager keyManager = new X509KeyManager() {
- @Override
- public String chooseClientAlias(String[] keyType, Principal[] issuers,
- Socket socket) {
- return delegateKeyManager.chooseClientAlias(keyType, issuers, socket);
- }
-
- @Override
- public String chooseServerAlias(String keyType, Principal[] issuers,
- Socket socket) {
- return delegateKeyManager.chooseServerAlias(keyType, issuers, socket);
- }
-
- @Override
- public X509Certificate[] getCertificateChain(String alias) {
- return delegateKeyManager.getCertificateChain(alias);
- }
-
- @Override
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- return delegateKeyManager.getClientAliases(keyType, issuers);
- }
-
- @Override
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- return delegateKeyManager.getServerAliases(keyType, issuers);
- }
-
- @Override
- public PrivateKey getPrivateKey(String alias) {
- PrivateKey privKey = delegateKeyManager.getPrivateKey(alias);
- if (privKey instanceof RSAPrivateKey) {
- return new OpaqueDelegatingRSAPrivateKey((RSAPrivateKey) privKey);
- } else if (privKey instanceof ECPrivateKey) {
- return new OpaqueDelegatingECPrivateKey((ECPrivateKey) privKey);
- } else {
- return null;
- }
- }
- };
- clientContext.init(new KeyManager[] {
- keyManager
- }, new TrustManager[] {
- c.clientTrustManager
- }, null);
- SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- server.setNeedClientAuth(true);
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
- assertNotNull(client.getSession().getLocalCertificates());
- TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
- TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
- client.getSession().getLocalCertificates());
- future.get();
- client.close();
- server.close();
- c.close();
- } finally {
- Security.removeProvider(OpaqueProvider.NAME);
- }
- }
-
- @SuppressWarnings("serial")
- public static class OpaqueProvider extends Provider {
- public static final String NAME = "OpaqueProvider";
-
- public OpaqueProvider() {
- super(NAME, 1.0, "test provider");
-
- put("Signature.NONEwithRSA", OpaqueSignatureSpi.RSA.class.getName());
- put("Signature.NONEwithECDSA", OpaqueSignatureSpi.ECDSA.class.getName());
- put("Cipher.RSA/ECB/NoPadding", OpaqueCipherSpi.class.getName());
- }
- }
-
- protected static class OpaqueSignatureSpi extends SignatureSpi {
- private final String algorithm;
-
- private Signature delegate;
-
- protected OpaqueSignatureSpi(String algorithm) {
- this.algorithm = algorithm;
- }
-
- public final static class RSA extends OpaqueSignatureSpi {
- public RSA() {
- super("NONEwithRSA");
- }
- }
-
- public final static class ECDSA extends OpaqueSignatureSpi {
- public ECDSA() {
- super("NONEwithECDSA");
- }
- }
-
- @Override
- protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
- fail("Cannot verify");
- }
-
- @Override
- protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
- DelegatingPrivateKey opaqueKey = (DelegatingPrivateKey) privateKey;
- try {
- delegate = Signature.getInstance(algorithm);
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeyException(e);
- }
- delegate.initSign(opaqueKey.getDelegate());
- }
-
- @Override
- protected void engineUpdate(byte b) throws SignatureException {
- delegate.update(b);
- }
-
- @Override
- protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
- delegate.update(b, off, len);
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- return delegate.sign();
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- return delegate.verify(sigBytes);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- protected void engineSetParameter(String param, Object value)
- throws InvalidParameterException {
- delegate.setParameter(param, value);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- protected Object engineGetParameter(String param) throws InvalidParameterException {
- return delegate.getParameter(param);
- }
- }
-
- public static class OpaqueCipherSpi extends CipherSpi {
- private Cipher delegate;
-
- public OpaqueCipherSpi() {
- }
-
- @Override
- protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
- fail();
- }
-
- @Override
- protected void engineSetPadding(String padding) throws NoSuchPaddingException {
- fail();
- }
-
- @Override
- protected int engineGetBlockSize() {
- return delegate.getBlockSize();
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- return delegate.getOutputSize(inputLen);
- }
-
- @Override
- protected byte[] engineGetIV() {
- return delegate.getIV();
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- return delegate.getParameters();
- }
-
- @Override
- protected void engineInit(int opmode, Key key, SecureRandom random)
- throws InvalidKeyException {
- getCipher();
- delegate.init(opmode, key, random);
- }
-
- protected void getCipher() throws InvalidKeyException {
- try {
- delegate = Cipher.getInstance("RSA/ECB/NoPadding");
- } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- getCipher();
- delegate.init(opmode, key, params, random);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params,
- SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- getCipher();
- delegate.init(opmode, key, params, random);
- }
-
- @Override
- protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- return delegate.update(input, inputOffset, inputLen);
- }
-
- @Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- return delegate.update(input, inputOffset, inputLen, output, outputOffset);
- }
-
- @Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
- throws IllegalBlockSizeException, BadPaddingException {
- return delegate.update(input, inputOffset, inputLen);
- }
-
- @Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset)
- throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
- return delegate.doFinal(input, inputOffset, inputLen, output, outputOffset);
- }
- }
-
- private interface DelegatingPrivateKey {
- PrivateKey getDelegate();
- }
-
- @SuppressWarnings("serial")
- private static class OpaqueDelegatingECPrivateKey
- implements ECKey, PrivateKey, DelegatingPrivateKey {
- private final ECPrivateKey delegate;
-
- public OpaqueDelegatingECPrivateKey(ECPrivateKey delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public PrivateKey getDelegate() {
- return delegate;
- }
-
- @Override
- public String getAlgorithm() {
- return delegate.getAlgorithm();
- }
-
- @Override
- public String getFormat() {
- return null;
- }
-
- @Override
- public byte[] getEncoded() {
- return null;
- }
-
- @Override
- public ECParameterSpec getParams() {
- return delegate.getParams();
- }
- }
-
- @SuppressWarnings("serial")
- private static class OpaqueDelegatingRSAPrivateKey
- implements RSAKey, PrivateKey, DelegatingPrivateKey {
- private final RSAPrivateKey delegate;
-
- public OpaqueDelegatingRSAPrivateKey(RSAPrivateKey delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public String getAlgorithm() {
- return delegate.getAlgorithm();
- }
-
- @Override
- public String getFormat() {
- return null;
- }
-
- @Override
- public byte[] getEncoded() {
- return null;
- }
-
- @Override
- public BigInteger getModulus() {
- return delegate.getModulus();
- }
-
- @Override
- public PrivateKey getDelegate() {
- return delegate;
- }
- }
-
- public void test_SSLSocket_TrustManagerRuntimeException() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLContext clientContext = SSLContext.getInstance("TLS");
- X509TrustManager trustManager = new X509TrustManager() {
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- throw new AssertionError();
- }
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- throw new RuntimeException(); // throw a RuntimeException from custom TrustManager
- }
- @Override public X509Certificate[] getAcceptedIssuers() {
- throw new AssertionError();
- }
- };
- clientContext.init(null, new TrustManager[] { trustManager }, null);
- SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- return null;
- }
- });
-
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- // before we would get a RuntimeException from checkServerTrusted.
- }
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_getEnableSessionCreation() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- SSLSocket server = (SSLSocket) c.serverSocket.accept();
- assertTrue(client.getEnableSessionCreation());
- assertTrue(server.getEnableSessionCreation());
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_setEnableSessionCreation_server() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.setEnableSessionCreation(false);
- try {
- server.startHandshake();
- fail();
- } catch (SSLException expected) {
- }
- return null;
- }
- });
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLException expected) {
- }
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_setEnableSessionCreation_client() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
- c.port);
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.startHandshake();
- fail();
- } catch (SSLException expected) {
- }
- return null;
- }
- });
- executor.shutdown();
- client.setEnableSessionCreation(false);
- try {
- client.startHandshake();
- fail();
- } catch (SSLException expected) {
- }
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_getSSLParameters() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
-
- SSLParameters p = ssl.getSSLParameters();
- assertNotNull(p);
-
- String[] cipherSuites = p.getCipherSuites();
- assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
- assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
-
- String[] protocols = p.getProtocols();
- assertNotSame(protocols, ssl.getEnabledProtocols());
- assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
-
- assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
- assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
-
- assertNull(p.getEndpointIdentificationAlgorithm());
- p.setEndpointIdentificationAlgorithm(null);
- assertNull(p.getEndpointIdentificationAlgorithm());
- p.setEndpointIdentificationAlgorithm("HTTPS");
- assertEquals("HTTPS", p.getEndpointIdentificationAlgorithm());
- p.setEndpointIdentificationAlgorithm("FOO");
- assertEquals("FOO", p.getEndpointIdentificationAlgorithm());
- }
-
- public void test_SSLSocket_setSSLParameters() throws Exception {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
- String[] defaultProtocols = ssl.getEnabledProtocols();
- String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
- String[] supportedProtocols = ssl.getSupportedProtocols();
-
- {
- SSLParameters p = new SSLParameters();
- ssl.setSSLParameters(p);
- assertEquals(Arrays.asList(defaultCipherSuites),
- Arrays.asList(ssl.getEnabledCipherSuites()));
- assertEquals(Arrays.asList(defaultProtocols),
- Arrays.asList(ssl.getEnabledProtocols()));
- }
-
- {
- SSLParameters p = new SSLParameters(supportedCipherSuites,
- supportedProtocols);
- ssl.setSSLParameters(p);
- assertEquals(Arrays.asList(supportedCipherSuites),
- Arrays.asList(ssl.getEnabledCipherSuites()));
- assertEquals(Arrays.asList(supportedProtocols),
- Arrays.asList(ssl.getEnabledProtocols()));
- }
- {
- SSLParameters p = new SSLParameters();
-
- p.setNeedClientAuth(true);
- assertFalse(ssl.getNeedClientAuth());
- assertFalse(ssl.getWantClientAuth());
- ssl.setSSLParameters(p);
- assertTrue(ssl.getNeedClientAuth());
- assertFalse(ssl.getWantClientAuth());
-
- p.setWantClientAuth(true);
- assertTrue(ssl.getNeedClientAuth());
- assertFalse(ssl.getWantClientAuth());
- ssl.setSSLParameters(p);
- assertFalse(ssl.getNeedClientAuth());
- assertTrue(ssl.getWantClientAuth());
-
- p.setWantClientAuth(false);
- assertFalse(ssl.getNeedClientAuth());
- assertTrue(ssl.getWantClientAuth());
- ssl.setSSLParameters(p);
- assertFalse(ssl.getNeedClientAuth());
- assertFalse(ssl.getWantClientAuth());
- }
- }
-
- public void test_SSLSocket_close() throws Exception {
- TestSSLSocketPair pair = TestSSLSocketPair.create();
- SSLSocket server = pair.server;
- SSLSocket client = pair.client;
- assertFalse(server.isClosed());
- assertFalse(client.isClosed());
- InputStream input = client.getInputStream();
- OutputStream output = client.getOutputStream();
- server.close();
- client.close();
- assertTrue(server.isClosed());
- assertTrue(client.isClosed());
-
- // close after close is okay...
- server.close();
- client.close();
-
- // ...so are a lot of other operations...
- HandshakeCompletedListener l = new HandshakeCompletedListener () {
- @Override
- public void handshakeCompleted(HandshakeCompletedEvent e) {}
- };
- client.addHandshakeCompletedListener(l);
- assertNotNull(client.getEnabledCipherSuites());
- assertNotNull(client.getEnabledProtocols());
- client.getEnableSessionCreation();
- client.getNeedClientAuth();
- assertNotNull(client.getSession());
- assertNotNull(client.getSSLParameters());
- assertNotNull(client.getSupportedProtocols());
- client.getUseClientMode();
- client.getWantClientAuth();
- client.removeHandshakeCompletedListener(l);
- client.setEnabledCipherSuites(new String[0]);
- client.setEnabledProtocols(new String[0]);
- client.setEnableSessionCreation(false);
- client.setNeedClientAuth(false);
- client.setSSLParameters(client.getSSLParameters());
- client.setWantClientAuth(false);
-
- // ...but some operations are expected to give SocketException...
- try {
- client.startHandshake();
- fail();
- } catch (SocketException expected) {
- }
- try {
- client.getInputStream();
- fail();
- } catch (SocketException expected) {
- }
- try {
- client.getOutputStream();
- fail();
- } catch (SocketException expected) {
- }
- try {
- input.read();
- fail();
- } catch (SocketException expected) {
- }
- try {
- input.read(null, -1, -1);
- fail();
- } catch (NullPointerException expected) {
- assertTrue(StandardNames.IS_RI);
- } catch (SocketException expected) {
- assertFalse(StandardNames.IS_RI);
- }
- try {
- output.write(-1);
- fail();
- } catch (SocketException expected) {
- }
- try {
- output.write(null, -1, -1);
- fail();
- } catch (NullPointerException expected) {
- assertTrue(StandardNames.IS_RI);
- } catch (SocketException expected) {
- assertFalse(StandardNames.IS_RI);
- }
-
- // ... and one gives IllegalArgumentException
- try {
- client.setUseClientMode(false);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- pair.close();
- }
-
- /**
- * b/3350645 Test to confirm that an SSLSocket.close() performing
- * an SSL_shutdown does not throw an IOException if the peer
- * socket has been closed.
- */
- public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception {
- TestSSLContext c = TestSSLContext.create();
- final Socket underlying = new Socket(c.host, c.port);
- final SSLSocket wrapping = (SSLSocket)
- c.clientContext.getSocketFactory().createSocket(underlying,
- c.host.getHostName(),
- c.port,
- false);
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> clientFuture = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- wrapping.startHandshake();
- wrapping.getOutputStream().write(42);
- // close the underlying socket,
- // so that no SSL shutdown is sent
- underlying.close();
- wrapping.close();
- return null;
- }
- });
- executor.shutdown();
-
- SSLSocket server = (SSLSocket) c.serverSocket.accept();
- server.startHandshake();
- server.getInputStream().read();
- // wait for thread to finish so we know client is closed.
- clientFuture.get();
- // close should cause an SSL_shutdown which will fail
- // because the peer has closed, but it shouldn't throw.
- server.close();
- }
-
- public void test_SSLSocket_endpointIdentification_Success() throws Exception {
- final TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
- SSLParameters p = client.getSSLParameters();
- p.setEndpointIdentificationAlgorithm("HTTPS");
- client.connect(new InetSocketAddress(c.host, c.port));
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- assertNotNull(server.getSession());
- try {
- server.getSession().getPeerCertificates();
- fail();
- } catch (SSLPeerUnverifiedException expected) {
- }
- Certificate[] localCertificates = server.getSession().getLocalCertificates();
- assertNotNull(localCertificates);
- TestKeyStore.assertChainLength(localCertificates);
- assertNotNull(localCertificates[0]);
- TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
- c.serverKeyStore);
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
- assertNotNull(client.getSession());
- assertNull(client.getSession().getLocalCertificates());
- Certificate[] peerCertificates = client.getSession().getPeerCertificates();
- assertNotNull(peerCertificates);
- TestKeyStore.assertChainLength(peerCertificates);
- assertNotNull(peerCertificates[0]);
- TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_endpointIdentification_Failure() throws Exception {
- final TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
- SSLParameters p = client.getSSLParameters();
- p.setEndpointIdentificationAlgorithm("HTTPS");
- client.setSSLParameters(p);
- client.connect(c.getLoopbackAsHostname("unmatched.example.com", c.port));
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.startHandshake();
- fail("Should receive SSLHandshakeException as server");
- } catch (SSLHandshakeException expected) {
- }
- return null;
- }
- });
- executor.shutdown();
- try {
- client.startHandshake();
- fail("Should throw when hostname does not match expected");
- } catch (SSLHandshakeException expected) {
- } finally {
- try {
- future.get();
- } finally {
- client.close();
- server.close();
- c.close();
- }
- }
- }
-
- public void test_SSLSocket_setSoTimeout_basic() throws Exception {
- ServerSocket listening = new ServerSocket(0);
-
- Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
- assertEquals(0, underlying.getSoTimeout());
-
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- Socket wrapping = sf.createSocket(underlying, null, -1, false);
- assertEquals(0, wrapping.getSoTimeout());
-
- // setting wrapper sets underlying and ...
- int expectedTimeoutMillis = 1000; // 10 was too small because it was affected by rounding
- wrapping.setSoTimeout(expectedTimeoutMillis);
- // The kernel can round the requested value based on the HZ setting. We allow up to 10ms.
- assertTrue(Math.abs(expectedTimeoutMillis - wrapping.getSoTimeout()) <= 10);
- assertTrue(Math.abs(expectedTimeoutMillis - underlying.getSoTimeout()) <= 10);
-
- // ... getting wrapper inspects underlying
- underlying.setSoTimeout(0);
- assertEquals(0, wrapping.getSoTimeout());
- assertEquals(0, underlying.getSoTimeout());
- }
-
- public void test_SSLSocket_setSoTimeout_wrapper() throws Exception {
- if (StandardNames.IS_RI) {
- // RI cannot handle this case
- return;
- }
- ServerSocket listening = new ServerSocket(0);
-
- // setSoTimeout applies to read, not connect, so connect first
- Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
- Socket server = listening.accept();
-
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- Socket clientWrapping = sf.createSocket(underlying, null, -1, false);
-
- underlying.setSoTimeout(1);
- try {
- clientWrapping.getInputStream().read();
- fail();
- } catch (SocketTimeoutException expected) {
- }
-
- clientWrapping.close();
- server.close();
- underlying.close();
- listening.close();
- }
-
- public void test_SSLSocket_setSoWriteTimeout() throws Exception {
- if (StandardNames.IS_RI) {
- // RI does not support write timeout on sockets
- return;
- }
-
- final TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
-
- // Try to make the client SO_SNDBUF size as small as possible
- // (it can default to 512k or even megabytes). Note that
- // socket(7) says that the kernel will double the request to
- // leave room for its own book keeping and that the minimal
- // value will be 2048. Also note that tcp(7) says the value
- // needs to be set before connect(2).
- int sendBufferSize = 1024;
- client.setSendBufferSize(sendBufferSize);
- sendBufferSize = client.getSendBufferSize();
-
- // In jb-mr2 it was found that we need to also set SO_RCVBUF
- // to a minimal size or the write would not block. While
- // tcp(2) says the value has to be set before listen(2), it
- // seems fine to set it before accept(2).
- final int recvBufferSize = 128;
- c.serverSocket.setReceiveBufferSize(recvBufferSize);
-
- client.connect(new InetSocketAddress(c.host, c.port));
-
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- client.startHandshake();
-
- // Reflection is used so this can compile on the RI
- String expectedClassName = "com.android.org.conscrypt.Java8FileDescriptorSocket";
- Class<?> actualClass = client.getClass();
- assertEquals(expectedClassName, actualClass.getName());
- // The concrete class that Conscrypt returns has methods on it that have no
- // equivalent on the public API (like setSoWriteTimeout), so users have
- // previously used reflection to access those otherwise-inaccessible methods
- // on that class. The concrete class used to be named OpenSSLSocketImpl, so
- // check that OpenSSLSocketImpl is still in the class hierarchy so applications
- // that rely on getting that class back still work.
- Class<?> superClass = actualClass;
- do {
- superClass = superClass.getSuperclass();
- } while (superClass != Object.class && !superClass.getName().endsWith("OpenSSLSocketImpl"));
- assertEquals("com.android.org.conscrypt.OpenSSLSocketImpl", superClass.getName());
- Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout",
- new Class<?>[] { Integer.TYPE });
- setSoWriteTimeout.invoke(client, 1);
-
-
- try {
- // Add extra space to the write to exceed the send buffer
- // size and cause the write to block.
- final int extra = 1;
- client.getOutputStream().write(new byte[sendBufferSize + extra]);
- fail();
- } catch (SocketTimeoutException expected) {
- }
-
- future.get();
- client.close();
- server.close();
- c.close();
- }
-
- public void test_SSLSocket_reusedNpnSocket() throws Exception {
- if (StandardNames.IS_RI) {
- // RI does not support NPN/ALPN
- return;
- }
-
- byte[] npnProtocols = new byte[] {
- 8, 'h', 't', 't', 'p', '/', '1', '.', '1'
- };
-
- final TestSSLContext c = TestSSLContext.create();
- SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
-
- // Reflection is used so this can compile on the RI
- String expectedClassName = "com.android.org.conscrypt.Java8FileDescriptorSocket";
- Class<?> actualClass = client.getClass();
- assertEquals(expectedClassName, actualClass.getName());
- Method setNpnProtocols = actualClass.getMethod("setNpnProtocols", byte[].class);
-
- ExecutorService executor = Executors.newSingleThreadExecutor();
-
- // First connection with NPN set on client and server
- {
- setNpnProtocols.invoke(client, npnProtocols);
- client.connect(new InetSocketAddress(c.host, c.port));
-
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- assertEquals(expectedClassName, server.getClass().getName());
- setNpnProtocols.invoke(server, npnProtocols);
-
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- client.startHandshake();
-
- future.get();
- client.close();
- server.close();
- }
-
- // Second connection with client NPN already set on the SSL context, but
- // without server NPN set.
- {
- SSLServerSocket serverSocket = (SSLServerSocket) c.serverContext
- .getServerSocketFactory().createServerSocket(0);
- InetAddress host = InetAddress.getLocalHost();
- int port = serverSocket.getLocalPort();
-
- client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
- client.connect(new InetSocketAddress(host, port));
-
- final SSLSocket server = (SSLSocket) serverSocket.accept();
-
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- server.startHandshake();
- return null;
- }
- });
- client.startHandshake();
-
- future.get();
- client.close();
- server.close();
- serverSocket.close();
- }
-
- c.close();
- }
-
- public void test_SSLSocket_interrupt() throws Exception {
- test_SSLSocket_interrupt_case(true, true);
- test_SSLSocket_interrupt_case(true, false);
- test_SSLSocket_interrupt_case(false, true);
- test_SSLSocket_interrupt_case(false, false);
- }
-
- private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying)
- throws Exception {
-
- ServerSocket listening = new ServerSocket(0);
-
- Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
- Socket server = listening.accept();
-
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- Socket clientWrapping = sf.createSocket(underlying, null, -1, true);
-
- final Socket toRead = (readUnderlying) ? underlying : clientWrapping;
- final Socket toClose = (closeUnderlying) ? underlying : clientWrapping;
-
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- Thread.sleep(1 * 1000);
- toClose.close();
- return null;
- }
- });
- executor.shutdown();
- try {
- toRead.setSoTimeout(5 * 1000);
- toRead.getInputStream().read();
- fail();
- } catch (SocketTimeoutException e) {
- throw e;
- } catch (IOException expected) {
- }
- future.get();
-
- server.close();
- underlying.close();
- listening.close();
- }
-
- /**
- * b/7014266 Test to confirm that an SSLSocket.close() on one
- * thread will interrupt another thread blocked reading on the same
- * socket.
- */
- public void test_SSLSocket_interrupt_read() throws Exception {
- final int readingTimeoutMillis = 5000;
- TestSSLContext c = TestSSLContext.create();
- final Socket underlying = new Socket(c.host, c.port);
- final SSLSocket wrapping = (SSLSocket)
- c.clientContext.getSocketFactory().createSocket(underlying,
- c.host.getHostName(),
- c.port,
- false);
-
- // Create our own thread group so we can inspect the stack state later.
- final ThreadGroup clientGroup = new ThreadGroup("client");
- ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- return new Thread(clientGroup, r);
- }
- });
-
- Future<Void> clientFuture = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- wrapping.startHandshake();
- assertFalse(StandardNames.IS_RI);
- wrapping.setSoTimeout(readingTimeoutMillis);
- wrapping.getInputStream().read();
- fail();
- } catch (SocketException e) {
- // Conscrypt throws an exception complaining that the socket is closed
- // if it's interrupted by a close() in the middle of a read()
- assertTrue(e.getMessage().contains("closed"));
- } catch (Exception e) {
- if (!StandardNames.IS_RI) {
- throw e;
- }
- }
- return null;
- }
- });
- executor.shutdown();
-
- SSLSocket server = (SSLSocket) c.serverSocket.accept();
- server.startHandshake();
-
- /*
- * Wait for the client to at least be in the "read" method before
- * calling close()
- */
- Thread[] threads = new Thread[1];
- clientGroup.enumerate(threads);
- if (threads[0] != null) {
- boolean clientInRead = false;
- while (!clientInRead) {
- StackTraceElement[] elements = threads[0].getStackTrace();
- for (StackTraceElement element : elements) {
- if ("read".equals(element.getMethodName())) {
- // The client might be executing "read" but still not have reached the
- // point in which it's blocked reading. This is causing flakiness
- // (b/24367646). Delaying for a fraction of the timeout.
- Thread.sleep(1000);
- clientInRead = true;
- break;
- }
- }
- }
- }
-
- wrapping.close();
- clientFuture.get();
- server.close();
- }
-
- public void test_TestSSLSocketPair_create() {
- TestSSLSocketPair test = TestSSLSocketPair.create();
- assertNotNull(test.c);
- assertNotNull(test.server);
- assertNotNull(test.client);
- assertTrue(test.server.isConnected());
- assertTrue(test.client.isConnected());
- assertFalse(test.server.isClosed());
- assertFalse(test.client.isClosed());
- assertNotNull(test.server.getSession());
- assertNotNull(test.client.getSession());
- assertTrue(test.server.getSession().isValid());
- assertTrue(test.client.getSession().isValid());
- test.close();
- }
-
- public void test_SSLSocket_ClientHello_record_size() throws Exception {
- // This test checks the size of ClientHello of the default SSLSocket. TLS/SSL handshakes
- // with older/unpatched F5/BIG-IP appliances are known to stall and time out when
- // the fragment containing ClientHello is between 256 and 511 (inclusive) bytes long.
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
- SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
- sslSocketFactory = new DelegatingSSLSocketFactory(sslSocketFactory) {
- @Override
- protected SSLSocket configureSocket(SSLSocket socket) {
- // Enable SNI extension on the socket (this is typically enabled by default)
- // to increase the size of ClientHello.
- try {
- Method setHostname =
- socket.getClass().getMethod("setHostname", String.class);
- setHostname.invoke(socket, "sslsockettest.androidcts.google.com");
- } catch (NoSuchMethodException ignored) {
- } catch (Exception e) {
- throw new RuntimeException("Failed to enable SNI", e);
- }
-
- // Enable Session Tickets extension on the socket (this is typically enabled
- // by default) to increase the size of ClientHello.
- try {
- Method setUseSessionTickets =
- socket.getClass().getMethod(
- "setUseSessionTickets", boolean.class);
- setUseSessionTickets.invoke(socket, true);
- } catch (NoSuchMethodException ignored) {
- } catch (Exception e) {
- throw new RuntimeException("Failed to enable Session Tickets", e);
- }
- return socket;
- }
- };
-
- TlsRecord firstReceivedTlsRecord = captureTlsHandshakeFirstTlsRecord(sslSocketFactory);
- assertEquals("TLS record type", TlsProtocols.HANDSHAKE, firstReceivedTlsRecord.type);
- HandshakeMessage handshakeMessage = HandshakeMessage.read(
- new DataInputStream(new ByteArrayInputStream(firstReceivedTlsRecord.fragment)));
- assertEquals("HandshakeMessage type",
- HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
- int fragmentLength = firstReceivedTlsRecord.fragment.length;
- if ((fragmentLength >= 256) && (fragmentLength <= 511)) {
- fail("Fragment containing ClientHello is of dangerous length: "
- + fragmentLength + " bytes");
- }
- }
-
- public void test_SSLSocket_ClientHello_cipherSuites() throws Exception {
- ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
- @Override
- public void run(SSLSocketFactory sslSocketFactory) throws Exception {
- ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
- final String[] cipherSuites;
-
- // RFC 5746 allows you to send an empty "renegotiation_info" extension *or*
- // a special signaling cipher suite. The TLS API has no way to check or
- // indicate that a certain TLS extension should be used.
- HelloExtension renegotiationInfoExtension = clientHello.findExtensionByType(
- HelloExtension.TYPE_RENEGOTIATION_INFO);
- if (renegotiationInfoExtension != null &&
- renegotiationInfoExtension.data.length == 1 &&
- renegotiationInfoExtension.data[0] == 0) {
- cipherSuites = new String[clientHello.cipherSuites.size() + 1];
- cipherSuites[clientHello.cipherSuites.size()] =
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION;
- } else {
- cipherSuites = new String[clientHello.cipherSuites.size()];
- }
-
- for (int i = 0; i < clientHello.cipherSuites.size(); i++) {
- CipherSuite cipherSuite = clientHello.cipherSuites.get(i);
- cipherSuites[i] = cipherSuite.getAndroidName();
- }
- StandardNames.assertDefaultCipherSuites(cipherSuites);
- }
- }, getSSLSocketFactoriesToTest());
- }
-
- public void test_SSLSocket_ClientHello_supportedCurves() throws Exception {
- ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
- @Override
- public void run(SSLSocketFactory sslSocketFactory) throws Exception {
- ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
-
- EllipticCurvesHelloExtension ecExtension = (EllipticCurvesHelloExtension)
- clientHello.findExtensionByType(HelloExtension.TYPE_ELLIPTIC_CURVES);
- final String[] supportedCurves;
- if (ecExtension == null) {
- supportedCurves = new String[0];
- } else {
- assertTrue(ecExtension.wellFormed);
- supportedCurves = new String[ecExtension.supported.size()];
- for (int i = 0; i < ecExtension.supported.size(); i++) {
- EllipticCurve curve = ecExtension.supported.get(i);
- supportedCurves[i] = curve.toString();
- }
- }
-
- StandardNames.assertDefaultEllipticCurves(supportedCurves);
- }
- }, getSSLSocketFactoriesToTest());
- }
-
- public void test_SSLSocket_ClientHello_clientProtocolVersion() throws Exception {
- ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
- @Override
- public void run(SSLSocketFactory sslSocketFactory) throws Exception {
- ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
- assertEquals(TlsProtocolVersion.TLSv1_2, clientHello.clientVersion);
- }
- }, getSSLSocketFactoriesToTest());
- }
-
- public void test_SSLSocket_ClientHello_compressionMethods() throws Exception {
- ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
- @Override
- public void run(SSLSocketFactory sslSocketFactory) throws Exception {
- ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
- assertEquals(Arrays.asList(CompressionMethod.NULL), clientHello.compressionMethods);
- }
- }, getSSLSocketFactoriesToTest());
- }
-
- public void test_SSLSocket_ClientHello_SNI() throws Exception {
- ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
- @Override
- public void run(SSLSocketFactory sslSocketFactory) throws Exception {
- ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
- ServerNameHelloExtension sniExtension = (ServerNameHelloExtension)
- clientHello.findExtensionByType(HelloExtension.TYPE_SERVER_NAME);
- assertNotNull(sniExtension);
- assertEquals(Arrays.asList("localhost.localdomain"), sniExtension.hostnames);
- }
- }, getSSLSocketFactoriesToTest());
- }
-
- private List<Pair<String, SSLSocketFactory>> getSSLSocketFactoriesToTest()
- throws NoSuchAlgorithmException, KeyManagementException {
- List<Pair<String, SSLSocketFactory>> result =
- new ArrayList<Pair<String, SSLSocketFactory>>();
- result.add(Pair.of("default", (SSLSocketFactory) SSLSocketFactory.getDefault()));
- for (String sslContextProtocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(sslContextProtocol);
- if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(sslContextProtocol)) {
- continue;
- }
- sslContext.init(null, null, null);
- result.add(Pair.of(
- "SSLContext(\"" + sslContext.getProtocol() + "\")",
- sslContext.getSocketFactory()));
- }
- return result;
- }
-
- private ClientHello captureTlsHandshakeClientHello(SSLSocketFactory sslSocketFactory)
- throws Exception {
- TlsRecord record = captureTlsHandshakeFirstTlsRecord(sslSocketFactory);
- assertEquals("TLS record type", TlsProtocols.HANDSHAKE, record.type);
- ByteArrayInputStream fragmentIn = new ByteArrayInputStream(record.fragment);
- HandshakeMessage handshakeMessage = HandshakeMessage.read(new DataInputStream(fragmentIn));
- assertEquals("HandshakeMessage type",
- HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
- // Assert that the fragment does not contain any more messages
- assertEquals(0, fragmentIn.available());
-
- return (ClientHello) handshakeMessage;
- }
-
- private TlsRecord captureTlsHandshakeFirstTlsRecord(SSLSocketFactory sslSocketFactory)
- throws Exception {
- byte[] firstReceivedChunk = captureTlsHandshakeFirstTransmittedChunkBytes(sslSocketFactory);
- ByteArrayInputStream firstReceivedChunkIn = new ByteArrayInputStream(firstReceivedChunk);
- TlsRecord record = TlsRecord.read(new DataInputStream(firstReceivedChunkIn));
- // Assert that the chunk does not contain any more data
- assertEquals(0, firstReceivedChunkIn.available());
-
- return record;
- }
-
- private byte[] captureTlsHandshakeFirstTransmittedChunkBytes(
- final SSLSocketFactory sslSocketFactory) throws Exception {
- // Since there's no straightforward way to obtain a ClientHello from SSLSocket, this test
- // does the following:
- // 1. Creates a listening server socket (a plain one rather than a TLS/SSL one).
- // 2. Creates a client SSLSocket, which connects to the server socket and initiates the
- // TLS/SSL handshake.
- // 3. Makes the server socket accept an incoming connection on the server socket, and reads
- // the first chunk of data received. This chunk is assumed to be the ClientHello.
- // NOTE: Steps 2 and 3 run concurrently.
- ServerSocket listeningSocket = null;
- ExecutorService executorService = Executors.newFixedThreadPool(2);
-
- // Some Socket operations are not interruptible via Thread.interrupt for some reason. To
- // work around, we unblock these sockets using Socket.close.
- final Socket[] sockets = new Socket[2];
- try {
- // 1. Create the listening server socket.
- listeningSocket = ServerSocketFactory.getDefault().createServerSocket(0);
- final ServerSocket finalListeningSocket = listeningSocket;
- // 2. (in background) Wait for an incoming connection and read its first chunk.
- final Future<byte[]> readFirstReceivedChunkFuture =
- executorService.submit(new Callable<byte[]>() {
- @Override
- public byte[] call() throws Exception {
- Socket socket = finalListeningSocket.accept();
- sockets[1] = socket;
- try {
- byte[] buffer = new byte[64 * 1024];
- int bytesRead = socket.getInputStream().read(buffer);
- if (bytesRead == -1) {
- throw new EOFException("Failed to read anything");
- }
- return Arrays.copyOf(buffer, bytesRead);
- } finally {
- closeQuietly(socket);
- }
- }
- });
-
- // 3. Create a client socket, connect it to the server socket, and start the TLS/SSL
- // handshake.
- executorService.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- Socket client = new Socket();
- sockets[0] = client;
- try {
- client.connect(finalListeningSocket.getLocalSocketAddress());
- // Initiate the TLS/SSL handshake which is expected to fail as soon as the
- // server socket receives a ClientHello.
- try {
- SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
- client,
- "localhost.localdomain",
- finalListeningSocket.getLocalPort(),
- true);
- sslSocket.startHandshake();
- fail();
- return null;
- } catch (IOException expected) {}
- return null;
- } finally {
- closeQuietly(client);
- }
- }
- });
-
- // Wait for the ClientHello to arrive
- return readFirstReceivedChunkFuture.get(10, TimeUnit.SECONDS);
- } finally {
- executorService.shutdownNow();
- closeQuietly(listeningSocket);
- closeQuietly(sockets[0]);
- closeQuietly(sockets[1]);
- if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
- fail("Timed out while waiting for the test to shut down");
- }
- }
- }
-
- // http://b/18428603
- public void test_SSLSocket_getPortWithSNI() throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- SSLSocket client = null;
- try {
- client = (SSLSocket) context.clientContext.getSocketFactory().createSocket();
- client.connect(new InetSocketAddress(context.host, context.port));
- try {
- // This is crucial to reproducing issue 18428603.
- Method setHostname = client.getClass().getMethod("setHostname", String.class);
- setHostname.invoke(client, "sslsockettest.androidcts.google.com");
- } catch (NoSuchMethodException ignored) {
- }
-
- assertTrue(client.getPort() > 0);
- } finally {
- client.close();
- context.close();
- }
- }
-
- public void test_SSLSocket_SNIHostName() throws Exception {
- TestSSLContext c = TestSSLContext.create();
-
- final SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
- SSLParameters clientParams = client.getSSLParameters();
- clientParams.setServerNames(Collections.singletonList(
- (SNIServerName) new SNIHostName("www.example.com")));
- client.setSSLParameters(clientParams);
-
- SSLParameters serverParams = c.serverSocket.getSSLParameters();
- serverParams.setSNIMatchers(Collections.singletonList(
- SNIHostName.createSNIMatcher("www\\.example\\.com")));
- c.serverSocket.setSSLParameters(serverParams);
-
- client.connect(new InetSocketAddress(c.host, c.port));
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
-
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- client.startHandshake();
- return null;
- }
- });
- executor.shutdown();
- server.startHandshake();
-
- SSLSession serverSession = server.getSession();
- assertTrue(serverSession instanceof ExtendedSSLSession);
- ExtendedSSLSession extendedServerSession = (ExtendedSSLSession) serverSession;
- List<SNIServerName> requestedNames = extendedServerSession.getRequestedServerNames();
- assertNotNull(requestedNames);
- assertEquals(1, requestedNames.size());
- SNIServerName serverName = requestedNames.get(0);
- assertEquals(StandardConstants.SNI_HOST_NAME, serverName.getType());
- assertTrue(serverName instanceof SNIHostName);
- SNIHostName serverHostName = (SNIHostName) serverName;
- assertEquals("www.example.com", serverHostName.getAsciiName());
- }
-
- public void test_SSLSocket_sendsTlsFallbackScsv_Fallback_Success() throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- final SSLSocket client = (SSLSocket)
- context.clientContext.getSocketFactory().createSocket(context.host, context.port);
- final SSLSocket server = (SSLSocket) context.serverSocket.accept();
-
- final String[] serverCipherSuites = server.getEnabledCipherSuites();
- final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
- System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
- clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
-
- ExecutorService executor = Executors.newFixedThreadPool(2);
- Future<Void> s = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- server.setEnabledProtocols(new String[] { "TLSv1.2" });
- server.setEnabledCipherSuites(serverCipherSuites);
- server.startHandshake();
- return null;
- }
- });
- Future<Void> c = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- client.setEnabledProtocols(new String[] { "TLSv1.2" });
- client.setEnabledCipherSuites(clientCipherSuites);
- client.startHandshake();
- return null;
- }
- });
- executor.shutdown();
-
- s.get();
- c.get();
- client.close();
- server.close();
- context.close();
- }
-
- // Confirms that communication without the TLS_FALLBACK_SCSV cipher works as it always did.
- public void test_SSLSocket_sendsNoTlsFallbackScsv_Fallback_Success() throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- final SSLSocket client = (SSLSocket)
- context.clientContext.getSocketFactory().createSocket(context.host, context.port);
- final SSLSocket server = (SSLSocket) context.serverSocket.accept();
-
- // Confirm absence of TLS_FALLBACK_SCSV.
- assertFalse(Arrays.asList(client.getEnabledCipherSuites())
- .contains(StandardNames.CIPHER_SUITE_FALLBACK));
-
- ExecutorService executor = Executors.newFixedThreadPool(2);
- Future<Void> s = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- server.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1.1" });
- server.startHandshake();
- return null;
- }
- });
- Future<Void> c = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- client.setEnabledProtocols(new String[] { "TLSv1.1" });
- client.startHandshake();
- return null;
- }
- });
- executor.shutdown();
-
- s.get();
- c.get();
- client.close();
- server.close();
- context.close();
- }
-
- private static void assertInappropriateFallbackIsCause(Throwable cause) {
- assertTrue(cause.getMessage(), cause.getMessage().contains("inappropriate fallback")
- || cause.getMessage().contains("INAPPROPRIATE_FALLBACK"));
- }
-
- public void test_SSLSocket_sendsTlsFallbackScsv_InappropriateFallback_Failure() throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- final SSLSocket client = (SSLSocket)
- context.clientContext.getSocketFactory().createSocket(context.host, context.port);
- final SSLSocket server = (SSLSocket) context.serverSocket.accept();
-
- final String[] serverCipherSuites = server.getEnabledCipherSuites();
-
- // Add TLS_FALLBACK_SCSV
- final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
- System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
- clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
-
- ExecutorService executor = Executors.newFixedThreadPool(2);
- Future<Void> s = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- server.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1" });
- server.setEnabledCipherSuites(serverCipherSuites);
- try {
- server.startHandshake();
- fail("Should result in inappropriate fallback");
- } catch (SSLHandshakeException expected) {
- Throwable cause = expected.getCause();
- assertEquals(SSLProtocolException.class, cause.getClass());
- assertInappropriateFallbackIsCause(cause);
- }
- return null;
- }
- });
- Future<Void> c = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- client.setEnabledProtocols(new String[] { "TLSv1" });
- client.setEnabledCipherSuites(clientCipherSuites);
- try {
- client.startHandshake();
- fail("Should receive TLS alert inappropriate fallback");
- } catch (SSLHandshakeException expected) {
- Throwable cause = expected.getCause();
- assertEquals(SSLProtocolException.class, cause.getClass());
- assertInappropriateFallbackIsCause(cause);
- }
- return null;
- }
- });
- executor.shutdown();
-
- s.get();
- c.get();
- client.close();
- server.close();
- context.close();
- }
-
- public void test_SSLSocket_ClientGetsAlertDuringHandshake_HasGoodExceptionMessage()
- throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- final ServerSocket listener = ServerSocketFactory.getDefault().createServerSocket(0);
- final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
- context.host, listener.getLocalPort());
- final Socket server = listener.accept();
-
- ExecutorService executor = Executors.newFixedThreadPool(2);
- Future<Void> c = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- try {
- client.startHandshake();
- fail("Should receive handshake exception");
- } catch (SSLHandshakeException expected) {
- assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN"));
- assertFalse(expected.getMessage().contains("You should never see this."));
- }
- return null;
- }
- });
- Future<Void> s = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- // Wait until the client sends something.
- byte[] scratch = new byte[8192];
- server.getInputStream().read(scratch);
-
- // Write a bogus TLS alert:
- // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Protocol Version)
- server.getOutputStream().write(new byte[] {
- 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46
- });
-
- // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Close Notify)
- server.getOutputStream().write(new byte[] {
- 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00
- });
-
- return null;
- }
- });
-
-
- executor.shutdown();
- c.get(5, TimeUnit.SECONDS);
- s.get(5, TimeUnit.SECONDS);
- client.close();
- server.close();
- listener.close();
- context.close();
- }
-
- public void test_SSLSocket_ServerGetsAlertDuringHandshake_HasGoodExceptionMessage()
- throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- final Socket client = SocketFactory.getDefault().createSocket(context.host, context.port);
- final SSLSocket server = (SSLSocket) context.serverSocket.accept();
-
- ExecutorService executor = Executors.newFixedThreadPool(2);
- Future<Void> s = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- try {
- server.startHandshake();
- fail("Should receive handshake exception");
- } catch (SSLHandshakeException expected) {
- assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN"));
- assertFalse(expected.getMessage().contains("You should never see this."));
- }
- return null;
- }
- });
- Future<Void> c = executor.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- // Send bogus ClientHello:
- // TLSv1.2 Record Layer: Handshake Protocol: Client Hello
- client.getOutputStream().write(new byte[] {
- (byte) 0x16, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0xb9,
- (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xb5, (byte) 0x03,
- (byte) 0x03, (byte) 0x5a, (byte) 0x31, (byte) 0xba, (byte) 0x44,
- (byte) 0x24, (byte) 0xfd, (byte) 0xf0, (byte) 0x56, (byte) 0x46,
- (byte) 0xea, (byte) 0xee, (byte) 0x1c, (byte) 0x62, (byte) 0x8f,
- (byte) 0x18, (byte) 0x04, (byte) 0xbd, (byte) 0x1c, (byte) 0xbc,
- (byte) 0xbf, (byte) 0x6d, (byte) 0x84, (byte) 0x12, (byte) 0xe9,
- (byte) 0x94, (byte) 0xf5, (byte) 0x1c, (byte) 0x15, (byte) 0x3e,
- (byte) 0x79, (byte) 0x01, (byte) 0xe2, (byte) 0x00, (byte) 0x00,
- (byte) 0x28, (byte) 0xc0, (byte) 0x2b, (byte) 0xc0, (byte) 0x2c,
- (byte) 0xc0, (byte) 0x2f, (byte) 0xc0, (byte) 0x30, (byte) 0x00,
- (byte) 0x9e, (byte) 0x00, (byte) 0x9f, (byte) 0xc0, (byte) 0x09,
- (byte) 0xc0, (byte) 0x0a, (byte) 0xc0, (byte) 0x13, (byte) 0xc0,
- (byte) 0x14, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x39,
- (byte) 0xc0, (byte) 0x07, (byte) 0xc0, (byte) 0x11, (byte) 0x00,
- (byte) 0x9c, (byte) 0x00, (byte) 0x9d, (byte) 0x00, (byte) 0x2f,
- (byte) 0x00, (byte) 0x35, (byte) 0x00, (byte) 0x05, (byte) 0x00,
- (byte) 0xff, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x64,
- (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x04, (byte) 0x03,
- (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x0a,
- (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x32, (byte) 0x00,
- (byte) 0x0e, (byte) 0x00, (byte) 0x0d, (byte) 0x00, (byte) 0x19,
- (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x0c, (byte) 0x00,
- (byte) 0x18, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x0a,
- (byte) 0x00, (byte) 0x16, (byte) 0x00, (byte) 0x17, (byte) 0x00,
- (byte) 0x08, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x07,
- (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x15, (byte) 0x00,
- (byte) 0x04, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x12,
- (byte) 0x00, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x00,
- (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x0f,
- (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x11, (byte) 0x00,
- (byte) 0x0d, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x1e,
- (byte) 0x06, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x06,
- (byte) 0x03, (byte) 0x05, (byte) 0x01, (byte) 0x05, (byte) 0x02,
- (byte) 0x05, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x04,
- (byte) 0x02, (byte) 0x04, (byte) 0x03, (byte) 0x03, (byte) 0x01,
- (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x02,
- (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x03,
- });
-
- // Wait until the server sends something.
- byte[] scratch = new byte[8192];
- client.getInputStream().read(scratch);
-
- // Write a bogus TLS alert:
- // TLSv1.2 Record Layer: Alert (Level: Warning, Description:
- // Protocol Version)
- client.getOutputStream().write(new byte[] {
- 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46
- });
-
- // TLSv1.2 Record Layer: Alert (Level: Warning, Description:
- // Close Notify)
- client.getOutputStream().write(new byte[] {
- 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00
- });
-
- return null;
- }
- });
-
- executor.shutdown();
- c.get(5, TimeUnit.SECONDS);
- s.get(5, TimeUnit.SECONDS);
- client.close();
- server.close();
- context.close();
- }
-
- public void test_SSLSocket_SSLv3Unsupported() throws Exception {
- TestSSLContext context = TestSSLContext.create();
-
- final SSLSocket client = (SSLSocket)
- context.clientContext.getSocketFactory().createSocket();
-
- // For app compatibility, SSLv3 is stripped out when setting only.
- client.setEnabledProtocols(new String[] {"SSLv3"});
- assertEquals(0, client.getEnabledProtocols().length);
-
- try {
- client.setEnabledProtocols(new String[] {"SSL"});
- fail("SSLSocket should not support SSL protocol");
- } catch (IllegalArgumentException expected) {
- }
- }
-
// We modified the toString() of SSLSocket, and it's based on the output
// of Socket.toString(), so we want to make sure that a change in
// Socket.toString() doesn't cause us to output nonsense.
@@ -2751,28 +80,6 @@
}
}
- private static final void readFully(InputStream in, byte[] dst) throws IOException {
- int offset = 0;
- int byteCount = dst.length;
- while (byteCount > 0) {
- int bytesRead = in.read(dst, offset, byteCount);
- if (bytesRead < 0) {
- throw new EOFException();
- }
- offset += bytesRead;
- byteCount -= bytesRead;
- }
- }
-
- private static final void closeQuietly(Closeable socket) {
- if (socket != null) {
- try {
- socket.close();
- } catch (Exception ignored) {
- }
- }
- }
-
public static void main (String[] args) {
new SSLSocketTest().stress_test_TestSSLSocketPair_create();
}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java
deleted file mode 100644
index 37d0e07..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2010 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.javax.net.ssl;
-
-import com.android.org.bouncycastle.asn1.x509.KeyPurposeId;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStore;
-import java.security.Provider;
-import java.security.Security;
-import java.security.cert.CertificateException;
-import java.security.cert.PKIXBuilderParameters;
-import java.security.cert.PKIXParameters;
-import java.security.cert.X509CertSelector;
-import java.security.cert.X509Certificate;
-import java.util.Set;
-import javax.net.ssl.CertPathTrustManagerParameters;
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-
-public class TrustManagerFactoryTest extends TestCase {
-
- private static final String [] KEY_TYPES = new String[] { "RSA", "DSA", "EC", "EC_RSA" };
-
- private static TestKeyStore TEST_KEY_STORE;
-
- // note the rare usage of DSA keys here in addition to RSA
- private static TestKeyStore getTestKeyStore() throws Exception {
- if (TEST_KEY_STORE == null) {
- TEST_KEY_STORE = new TestKeyStore.Builder()
- .keyAlgorithms(KEY_TYPES)
- .aliasPrefix("rsa-dsa-ec")
- .build();
- }
- return TEST_KEY_STORE;
- }
-
- private static boolean supportsManagerFactoryParameters(String algorithm) {
- return (StandardNames.IS_RI && algorithm.equals("PKIX"));
- }
-
- public void test_TrustManagerFactory_getDefaultAlgorithm() throws Exception {
- String algorithm = TrustManagerFactory.getDefaultAlgorithm();
- assertEquals(StandardNames.TRUST_MANAGER_FACTORY_DEFAULT, algorithm);
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- test_TrustManagerFactory(tmf);
- }
-
- private static class UselessManagerFactoryParameters implements ManagerFactoryParameters {}
-
- private void test_TrustManagerFactory(TrustManagerFactory tmf)
- throws Exception {
- assertNotNull(tmf);
- assertNotNull(tmf.getAlgorithm());
- assertNotNull(tmf.getProvider());
-
- // before init
- try {
- tmf.getTrustManagers();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- // init with null ManagerFactoryParameters
- try {
- tmf.init((ManagerFactoryParameters) null);
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
-
- // init with useless ManagerFactoryParameters
- try {
- tmf.init(new UselessManagerFactoryParameters());
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
-
- // init with PKIXParameters ManagerFactoryParameters
- try {
- PKIXParameters pp = new PKIXParameters(getTestKeyStore().keyStore);
- CertPathTrustManagerParameters cptmp = new CertPathTrustManagerParameters(pp);
- tmf.init(cptmp);
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
-
- // init with PKIXBuilderParameters ManagerFactoryParameters
- X509CertSelector xcs = new X509CertSelector();
- PKIXBuilderParameters pbp = new PKIXBuilderParameters(getTestKeyStore().keyStore, xcs);
- CertPathTrustManagerParameters cptmp = new CertPathTrustManagerParameters(pbp);
- if (supportsManagerFactoryParameters(tmf.getAlgorithm())) {
- tmf.init(cptmp);
- test_TrustManagerFactory_getTrustManagers(tmf);
- } else {
- try {
- tmf.init(cptmp);
- fail();
- } catch (InvalidAlgorithmParameterException expected) {
- }
- }
-
- // init with null for default KeyStore
- tmf.init((KeyStore) null);
- test_TrustManagerFactory_getTrustManagers(tmf);
-
- // init with specific key store
- tmf.init(getTestKeyStore().keyStore);
- test_TrustManagerFactory_getTrustManagers(tmf);
- }
-
- private void test_TrustManagerFactory_getTrustManagers(TrustManagerFactory tmf)
- throws Exception {
- TrustManager[] trustManagers = tmf.getTrustManagers();
- assertNotNull(trustManagers);
- assertTrue(trustManagers.length > 0);
- for (TrustManager trustManager : trustManagers) {
- assertNotNull(trustManager);
- if (trustManager instanceof X509TrustManager) {
- test_X509TrustManager((X509TrustManager) trustManager);
- }
- }
- }
-
- private void test_X509TrustManager(X509TrustManager tm) throws Exception {
- for (String keyType : KEY_TYPES) {
- X509Certificate[] issuers = tm.getAcceptedIssuers();
- assertNotNull(issuers);
- assertTrue(issuers.length > 1);
- assertNotSame(issuers, tm.getAcceptedIssuers());
- boolean defaultTrustManager
- // RI de-duplicates certs from TrustedCertificateEntry and PrivateKeyEntry
- = issuers.length > (StandardNames.IS_RI ? 1 : 2) * KEY_TYPES.length;
-
- String keyAlgName = TestKeyStore.keyAlgorithm(keyType);
- String sigAlgName = TestKeyStore.signatureAlgorithm(keyType);
- PrivateKeyEntry pke = getTestKeyStore().getPrivateKey(keyAlgName, sigAlgName);
- X509Certificate[] chain = (X509Certificate[]) pke.getCertificateChain();
- if (defaultTrustManager) {
- try {
- tm.checkClientTrusted(chain, keyType);
- fail();
- } catch (CertificateException expected) {
- }
- try {
- tm.checkServerTrusted(chain, keyType);
- fail();
- } catch (CertificateException expected) {
- }
- } else {
- tm.checkClientTrusted(chain, keyType);
- tm.checkServerTrusted(chain, keyType);
- }
-
- }
- }
-
- public void test_TrustManagerFactory_getInstance() throws Exception {
- Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("TrustManagerFactory")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- assertEquals(algorithm, tmf.getAlgorithm());
- test_TrustManagerFactory(tmf);
- }
-
- {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm,
- provider);
- assertEquals(algorithm, tmf.getAlgorithm());
- assertEquals(provider, tmf.getProvider());
- test_TrustManagerFactory(tmf);
- }
-
- {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm,
- provider.getName());
- assertEquals(algorithm, tmf.getAlgorithm());
- assertEquals(provider, tmf.getProvider());
- test_TrustManagerFactory(tmf);
- }
- }
- }
- }
-
- public void test_TrustManagerFactory_intermediate() throws Exception {
- // chain should be server/intermediate/root
- PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain = (X509Certificate[])pke.getCertificateChain();
- assertEquals(3, chain.length);
-
- // keyStore should contain only the intermediate CA so we can
- // test proper validation even if there are extra certs after
- // the trusted one (in this case the original root is "extra")
- KeyStore keyStore = TestKeyStore.createKeyStore();
- keyStore.setCertificateEntry("alias", chain[1]);
-
- Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("TrustManagerFactory")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init(keyStore);
- TrustManager[] trustManagers = tmf.getTrustManagers();
- for (TrustManager trustManager : trustManagers) {
- if (!(trustManager instanceof X509TrustManager)) {
- continue;
- }
- X509TrustManager tm = (X509TrustManager) trustManager;
- tm.checkClientTrusted(chain, "RSA");
- tm.checkServerTrusted(chain, "RSA");
- }
- }
- }
- }
-
- public void test_TrustManagerFactory_keyOnly() throws Exception {
- // create a KeyStore containing only a private key with chain.
- // unlike PKIXParameters(KeyStore), the cert chain of the key should be trusted.
- KeyStore ks = TestKeyStore.createKeyStore();
- KeyStore.PrivateKeyEntry pke = getTestKeyStore().getPrivateKey("RSA", "RSA");
- ks.setKeyEntry("key", pke.getPrivateKey(), "pw".toCharArray(), pke.getCertificateChain());
-
- String algorithm = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init(ks);
- X509TrustManager trustManager = (X509TrustManager) tmf.getTrustManagers()[0];
- trustManager.checkServerTrusted((X509Certificate[]) pke.getCertificateChain(), "RSA");
- }
-
- public void test_TrustManagerFactory_extendedKeyUsage() throws Exception {
- // anyExtendedKeyUsage should work for client or server
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage, false, true, true);
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage, true, true, true);
-
- // critical clientAuth should work for client
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_clientAuth, false, true, false);
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_clientAuth, true, true, false);
-
- // critical serverAuth should work for server
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_serverAuth, false, false, true);
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_serverAuth, true, false, true);
-
- // codeSigning should not work
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_codeSigning, false, false, false);
- test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_codeSigning, true, false, false);
- }
-
- private void test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId keyPurposeId,
- boolean critical,
- boolean client,
- boolean server)
- throws Exception {
- String algorithm = "RSA";
- TestKeyStore intermediateCa = TestKeyStore.getIntermediateCa();
- TestKeyStore leaf = new TestKeyStore.Builder()
- .keyAlgorithms(new String[] { algorithm })
- .aliasPrefix("criticalCodeSigning")
- .signer(intermediateCa.getPrivateKey("RSA", "RSA"))
- .rootCa(intermediateCa.getRootCertificate("RSA"))
- .addExtendedKeyUsage(keyPurposeId, critical)
- .build();
- // leaf.dump("test_TrustManagerFactory_criticalCodeSigning");
- PrivateKeyEntry privateKeyEntry = leaf.getPrivateKey(algorithm, algorithm);
- X509Certificate[] chain = (X509Certificate[]) privateKeyEntry.getCertificateChain();
-
- TestKeyStore rootCa = TestKeyStore.getRootCa();
- X509TrustManager trustManager = (X509TrustManager) rootCa.trustManagers[0];
- try {
- trustManager.checkClientTrusted(chain, algorithm);
- assertTrue(client);
- } catch (Exception e) {
- assertFalse(client);
- }
- try {
- trustManager.checkServerTrusted(chain, algorithm);
- assertTrue(server);
- } catch (Exception e) {
- assertFalse(server);
- }
- }
-}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/X509KeyManagerTest.java b/luni/src/test/java/libcore/javax/net/ssl/X509KeyManagerTest.java
deleted file mode 100644
index a44edd0..0000000
--- a/luni/src/test/java/libcore/javax/net/ssl/X509KeyManagerTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2013 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.javax.net.ssl;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.X509KeyManager;
-
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class X509KeyManagerTest extends TestCase {
- /**
- * Tests whether the key manager will select the right key when the CA is of
- * one key type and the client is of a possibly different key type.
- *
- * <p>There was a bug where EC was being interpreted as EC_EC and only
- * accepting EC signatures when it should accept any signature type.
- */
- public void testChooseClientAlias_Combinations() throws Exception {
- test_ChooseClientAlias_KeyType("RSA", "RSA", "RSA", true);
- test_ChooseClientAlias_KeyType("RSA", "EC", "RSA", true);
- test_ChooseClientAlias_KeyType("RSA", "EC", "EC", false);
-
- test_ChooseClientAlias_KeyType("EC", "RSA", "EC_RSA", true);
- test_ChooseClientAlias_KeyType("EC", "EC", "EC_RSA", false);
-
- test_ChooseClientAlias_KeyType("EC", "EC", "EC_EC", true);
- test_ChooseClientAlias_KeyType("EC", "RSA", "EC_EC", false);
-
- test_ChooseClientAlias_KeyType("EC", "RSA", "RSA", false);
- }
-
- private void test_ChooseClientAlias_KeyType(String clientKeyType, String caKeyType,
- String selectedKeyType, boolean succeeds) throws Exception {
- TestKeyStore ca = new TestKeyStore.Builder()
- .keyAlgorithms(caKeyType)
- .build();
- TestKeyStore client = new TestKeyStore.Builder().keyAlgorithms(clientKeyType)
- .signer(ca.getPrivateKey(caKeyType, caKeyType))
- .build();
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
- .getDefaultAlgorithm());
- kmf.init(client.keyStore, client.keyPassword);
-
- String[] keyTypes = new String[] { selectedKeyType };
- KeyManager[] managers = kmf.getKeyManagers();
- for (KeyManager manager : managers) {
- if (manager instanceof X509KeyManager) {
- String alias = ((X509KeyManager) manager).chooseClientAlias(keyTypes, null, null);
- if (succeeds) {
- assertNotNull(alias);
- } else {
- assertNull(alias);
- }
- }
- }
- }
-}
diff --git a/luni/src/test/java/libcore/libcore/icu/TransliteratorTest.java b/luni/src/test/java/libcore/libcore/icu/TransliteratorTest.java
index fbfd73b..d1e1483 100644
--- a/luni/src/test/java/libcore/libcore/icu/TransliteratorTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/TransliteratorTest.java
@@ -71,7 +71,7 @@
// Use alternative transliteration variants.
t = Transliterator.getInstance("Greek-Latin/BGN");
- assertEquals("Kalēméra kósme!", t.transliterate(greek));
+ assertEquals("Kaliméra kósme!", t.transliterate(greek));
t = Transliterator.getInstance("Greek-Latin/UNGEGN");
assertEquals("Kali̱méra kósme!",t.transliterate(greek));
}
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 710d3be..7015521 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -158,7 +158,7 @@
"inet_pton(int,java.lang.String)",
"ioctlFlags(java.io.FileDescriptor,java.lang.String)",
"ioctlInetAddress(java.io.FileDescriptor,int,java.lang.String)",
- "ioctlInt(java.io.FileDescriptor,int,libcore.util.MutableInt)",
+ "ioctlInt(java.io.FileDescriptor,int,android.system.Int32Ref)",
"ioctlMTU(java.io.FileDescriptor,java.lang.String)",
"isatty(java.io.FileDescriptor)",
"kill(int,int)",
@@ -197,7 +197,7 @@
"umask(int)",
"uname()",
"unsetenv(java.lang.String)",
- "waitpid(int,libcore.util.MutableInt,int)" );
+ "waitpid(int,android.system.Int32Ref,int)");
Set<String> methodsNotRequiredBlockGuardCheckSet = new HashSet<>(
methodsNotRequireBlockGuardChecks);
diff --git a/luni/src/test/java/libcore/libcore/io/OsTest.java b/luni/src/test/java/libcore/libcore/io/OsTest.java
index 5d3616c..bc15df0 100644
--- a/luni/src/test/java/libcore/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/OsTest.java
@@ -54,7 +54,6 @@
import libcore.io.IoBridge;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import libcore.util.MutableLong;
import static android.system.OsConstants.*;
import static libcore.libcore.io.OsTest.SendFileImpl.ANDROID_SYSTEM_OS_INT64_REF;
@@ -839,7 +838,7 @@
public void test_sendfile_errno() throws Exception {
try {
// FileDescriptor.out is not open for input, will cause EBADF
- MutableLong offset = new MutableLong(10);
+ Int64Ref offset = new Int64Ref(10);
Libcore.os.sendfile(FileDescriptor.out, FileDescriptor.out, offset, 10);
fail();
} catch(ErrnoException expected) {
@@ -901,8 +900,7 @@
break;
}
case LIBCORE_OS: {
- libcore.util.MutableLong offset = (startOffset == null) ? null :
- new libcore.util.MutableLong(startOffset);
+ Int64Ref offset = (startOffset == null) ? null : new Int64Ref(startOffset);
libcore.io.Libcore.os.sendfile(outFd, inFd, offset, maxBytes);
assertEquals(expectedEndOffset, offset == null ? null : offset.value);
break;
diff --git a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
index 76e6336..f9ff9df 100644
--- a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
+++ b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
@@ -87,4 +87,7 @@
assertEquals("video/ogg", MimeUtils.guessMimeTypeFromExtension("ogv"));
}
+ public void test_70851634() {
+ assertEquals("application/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
+ }
}
diff --git a/luni/src/test/java/libcore/libcore/util/CountryTimeZonesTest.java b/luni/src/test/java/libcore/libcore/util/CountryTimeZonesTest.java
new file mode 100644
index 0000000..d507c6f
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/util/CountryTimeZonesTest.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.libcore.util;
+
+import org.junit.Test;
+
+import android.icu.util.TimeZone;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import libcore.util.CountryTimeZones;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class CountryTimeZonesTest {
+
+ private static final int HOUR_MILLIS = 60 * 60 * 1000;
+
+ private static final String INVALID_TZ_ID = "Moon/Tranquility_Base";
+
+ // Zones used in the tests. NEW_YORK_TZ and LONDON_TZ chosen because they never overlap but both
+ // have DST.
+ private static final TimeZone NEW_YORK_TZ = TimeZone.getTimeZone("America/New_York");
+ private static final TimeZone LONDON_TZ = TimeZone.getTimeZone("Europe/London");
+ // A zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for WHEN_DST.
+ private static final TimeZone REYKJAVIK_TZ = TimeZone.getTimeZone("Atlantic/Reykjavik");
+ // Another zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for
+ // WHEN_DST.
+ private static final TimeZone UTC_TZ = TimeZone.getTimeZone("Etc/UTC");
+
+ // 22nd July 2017, 13:14:15 UTC (DST time in all the timezones used in these tests that observe
+ // DST).
+ private static final long WHEN_DST = 1500729255000L;
+ // 22nd January 2018, 13:14:15 UTC (non-DST time in all timezones used in these tests).
+ private static final long WHEN_NO_DST = 1516626855000L;
+
+ private static final int LONDON_DST_OFFSET_MILLIS = HOUR_MILLIS;
+ private static final int LONDON_NO_DST_OFFSET_MILLIS = 0;
+
+ private static final int NEW_YORK_DST_OFFSET_MILLIS = -4 * HOUR_MILLIS;
+ private static final int NEW_YORK_NO_DST_OFFSET_MILLIS = -5 * HOUR_MILLIS;
+
+ @Test
+ public void createValidated() throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+ assertEquals("gb", countryTimeZones.getCountryIso());
+ assertEquals("Europe/London", countryTimeZones.getDefaultTimeZoneId());
+ assertZoneEquals(zone("Europe/London"), countryTimeZones.getDefaultTimeZone());
+ assertEquals(list("Europe/London"), countryTimeZones.getTimeZoneIds());
+ assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
+ }
+
+ @Test
+ public void createValidated_nullDefault() throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "gb", null, list("Europe/London"), "test");
+ assertNull(countryTimeZones.getDefaultTimeZoneId());
+ }
+
+ @Test
+ public void createValidated_invalidDefault() throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "gb", INVALID_TZ_ID, list("Europe/London", INVALID_TZ_ID),
+ "test");
+ assertNull(countryTimeZones.getDefaultTimeZoneId());
+ assertEquals(list("Europe/London"), countryTimeZones.getTimeZoneIds());
+ assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
+ }
+
+ @Test
+ public void createValidated_unknownTimeZoneIdIgnored() throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Unknown_Id", "Europe/London"), "test");
+ assertEquals(list("Europe/London"), countryTimeZones.getTimeZoneIds());
+ assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
+ }
+
+ @Test
+ public void structuresAreImmutable() throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+
+ assertImmutableTimeZone(countryTimeZones.getDefaultTimeZone());
+
+ List<TimeZone> tzList = countryTimeZones.getIcuTimeZones();
+ assertEquals(1, tzList.size());
+ assertImmutableList(tzList);
+ assertImmutableTimeZone(tzList.get(0));
+
+ List<String> tzIdList = countryTimeZones.getTimeZoneIds();
+ assertEquals(1, tzIdList.size());
+ assertImmutableList(tzIdList);
+ }
+
+ @Test
+ public void lookupByOffsetWithBias_oneCandidate() throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+
+ // The three parameters match the configured zone: offset, isDst and when.
+ assertZoneEquals(LONDON_TZ,
+ countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+ true /* isDst */, WHEN_DST, null /* bias */));
+ assertZoneEquals(LONDON_TZ,
+ countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+ false /* isDst */, WHEN_NO_DST, null /* bias */));
+
+ // Some lookup failure cases where the offset, isDst and when do not match the configured
+ // zone.
+ TimeZone noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch1);
+
+ TimeZone noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch2);
+
+ TimeZone noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch3);
+
+ TimeZone noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch4);
+
+ TimeZone noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch5);
+
+ TimeZone noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch6);
+
+ // Some bias cases below.
+
+ // The bias is irrelevant here: it matches what would be returned anyway.
+ assertZoneEquals(LONDON_TZ,
+ countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+ true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+ assertZoneEquals(LONDON_TZ,
+ countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+ false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+ // A sample of a non-matching case with bias.
+ assertNull(countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+ true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+ // The bias should be ignored: it doesn't match any of the country's zones.
+ assertZoneEquals(LONDON_TZ,
+ countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+ true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+
+ // The bias should still be ignored even though it matches the offset information given:
+ // it doesn't match any of the country's configured zones.
+ assertNull(countryTimeZones.lookupByOffsetWithBias(NEW_YORK_DST_OFFSET_MILLIS,
+ true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+ }
+
+ @Test
+ public void lookupByOffsetWithBias_multipleNonOverlappingCandidates()
+ throws Exception {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list("America/New_York", "Europe/London"), "test");
+
+ // The three parameters match the configured zone: offset, isDst and when.
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(
+ LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
+ assertZoneEquals(NEW_YORK_TZ, countryTimeZones.lookupByOffsetWithBias(
+ NEW_YORK_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+ assertZoneEquals(NEW_YORK_TZ, countryTimeZones.lookupByOffsetWithBias(
+ NEW_YORK_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
+
+ // Some lookup failure cases where the offset, isDst and when do not match the configured
+ // zone. This is a sample, not complete.
+ TimeZone noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch1);
+
+ TimeZone noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch2);
+
+ TimeZone noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
+ NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch3);
+
+ TimeZone noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
+ NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch4);
+
+ TimeZone noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch5);
+
+ TimeZone noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
+ LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch6);
+
+ // Some bias cases below.
+
+ // The bias is irrelevant here: it matches what would be returned anyway.
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(
+ LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+ // A sample of a non-matching case with bias.
+ assertNull(countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+ // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+ // should not be considered a match.
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+ }
+
+ // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
+ // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
+ @Test
+ public void lookupByOffsetWithBias_multipleOverlappingCandidates() throws Exception {
+ // Three zones that have the same offset for some of the year. Europe/London changes
+ // offset WHEN_DST, the others do not.
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list("Atlantic/Reykjavik", "Europe/London", "Etc/UTC"),
+ "test");
+
+ // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
+ final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
+ // This is the DST offset for LONDON_TZ.
+ final int dstOffset = LONDON_DST_OFFSET_MILLIS;
+
+ // The three parameters match the configured zone: offset, isDst and when.
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(dstOffset,
+ true /* isDst */, WHEN_DST, null /* bias */));
+ assertZoneEquals(REYKJAVIK_TZ, countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ false /* isDst */, WHEN_NO_DST, null /* bias */));
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(dstOffset,
+ true /* isDst */, WHEN_DST, null /* bias */));
+ assertZoneEquals(REYKJAVIK_TZ, countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ false /* isDst */, WHEN_NO_DST, null /* bias */));
+ assertZoneEquals(REYKJAVIK_TZ, countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ false /* isDst */, WHEN_DST, null /* bias */));
+
+ // Some lookup failure cases where the offset, isDst and when do not match the configured
+ // zones.
+ TimeZone noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
+ true /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch1);
+
+ TimeZone noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ true /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch2);
+
+ TimeZone noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ true /* isDst */, WHEN_NO_DST, null /* bias */);
+ assertNull(noDstMatch3);
+
+ TimeZone noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
+ false /* isDst */, WHEN_DST, null /* bias */);
+ assertNull(noDstMatch4);
+
+
+ // Some bias cases below.
+
+ // The bias is relevant here: it overrides what would be returned naturally.
+ assertZoneEquals(REYKJAVIK_TZ, countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ false /* isDst */, WHEN_NO_DST, null /* bias */));
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+ assertZoneEquals(UTC_TZ, countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+ false /* isDst */, WHEN_NO_DST, UTC_TZ /* bias */));
+
+ // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+ // should not be considered a match.
+ assertZoneEquals(LONDON_TZ, countryTimeZones.lookupByOffsetWithBias(
+ LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, REYKJAVIK_TZ /* bias */));
+ }
+
+ @Test
+ public void isDefaultOkForCountryTimeZoneDetection_noZones() {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list(), "test");
+ assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+ assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+ }
+
+ @Test
+ public void isDefaultOkForCountryTimeZoneDetection_oneZone() {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list("Europe/London"), "test");
+ assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+ assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+ }
+
+ @Test
+ public void isDefaultOkForCountryTimeZoneDetection_twoZones_overlap() {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list("Europe/London", "Etc/UTC"), "test");
+ // Europe/London is the same as UTC in the Winter, so all the zones have the same offset
+ // in Winter, but not in Summer.
+ assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+ assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+ }
+
+ @Test
+ public void isDefaultOkForCountryTimeZoneDetection_twoZones_noOverlap() {
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list("Europe/London", "America/New_York"), "test");
+ // The zones have different offsets all year, so it would never be ok to use the default
+ // zone for the country of "xx".
+ assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+ assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+ }
+
+ @Test
+ public void hasUtcZone_singleZone() {
+ // The country has a single zone. Europe/London uses UTC in Winter.
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/London", list("Europe/London"), "test");
+ assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+ assertTrue(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+ }
+
+ @Test
+ public void hasUtcZone_multipleZonesWithUtc() {
+ // The country has multiple zones. Europe/London uses UTC in Winter.
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "America/Los_Angeles",
+ list("America/Los_Angeles", "America/New_York", "Europe/London"), "test");
+ assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+ assertTrue(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+ }
+
+ @Test
+ public void hasUtcZone_multipleZonesWithoutUtc() {
+ // The country has multiple zones, none of which use UTC.
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", "Europe/Paris",
+ list("America/Los_Angeles", "America/New_York", "Europe/Paris"), "test");
+ assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+ assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+ }
+
+ @Test
+ public void hasUtcZone_emptyZones() {
+ // The country has no valid zones.
+ CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+ "xx", INVALID_TZ_ID, list(INVALID_TZ_ID), "test");
+ assertTrue(countryTimeZones.getTimeZoneIds().isEmpty());
+ assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+ assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+ }
+
+ private void assertImmutableTimeZone(TimeZone timeZone) {
+ try {
+ timeZone.setRawOffset(1000);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ private static <X> void assertImmutableList(List<X> list) {
+ try {
+ list.add(null);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ private static void assertZoneEquals(TimeZone expected, TimeZone actual) {
+ // TimeZone.equals() only checks the ID, but that's ok for these tests.
+ assertEquals(expected, actual);
+ }
+
+ private static void assertZonesEqual(List<TimeZone> expected, List<TimeZone> actual) {
+ // TimeZone.equals() only checks the ID, but that's ok for these tests.
+ assertEquals(expected, actual);
+ }
+
+ private static <X> List<X> list(X... values) {
+ return Arrays.asList(values);
+ }
+
+ private static TimeZone zone(String id) {
+ return TimeZone.getTimeZone(id);
+ }
+
+ private static List<TimeZone> zones(String... ids) {
+ return Arrays.stream(ids).map(TimeZone::getTimeZone).collect(Collectors.toList());
+ }
+}
diff --git a/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java b/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
index 8d83953..c23f8bb 100644
--- a/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
+++ b/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
@@ -31,20 +31,18 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
-
+import libcore.util.CountryTimeZones;
import libcore.util.TimeZoneFinder;
import libcore.util.ZoneInfoDB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class TimeZoneFinderTest {
@@ -109,13 +107,18 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n";
+ CountryTimeZones expectedCountryTimeZones1 = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+
String validXml2 = "<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
- + " <country code=\"gb\" default=\"Europe/London\">\n"
+ + " <country code=\"gb\" default=\"Europe/Paris\">\n"
+ " <id>Europe/Paris</id>\n"
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n";
+ CountryTimeZones expectedCountryTimeZones2 = CountryTimeZones.createValidated(
+ "gb", "Europe/Paris", list("Europe/Paris"), "test");
String invalidXml = "<foo></foo>\n";
checkValidateThrowsParserException(invalidXml);
@@ -128,36 +131,30 @@
TimeZoneFinder file1ThenFile2 =
TimeZoneFinder.createInstanceWithFallback(validFile1, validFile2);
assertEquals("2017c", file1ThenFile2.getIanaVersion());
- assertEquals(list("Europe/London"), file1ThenFile2.lookupTimeZoneIdsByCountry("gb"));
- assertZonesEqual(zones("Europe/London"), file1ThenFile2.lookupTimeZonesByCountry("gb"));
+ assertEquals(expectedCountryTimeZones1, file1ThenFile2.lookupCountryTimeZones("gb"));
TimeZoneFinder missingFileThenFile1 =
TimeZoneFinder.createInstanceWithFallback(missingFile, validFile1);
assertEquals("2017c", missingFileThenFile1.getIanaVersion());
- assertEquals(list("Europe/London"), missingFileThenFile1.lookupTimeZoneIdsByCountry("gb"));
- assertZonesEqual(zones("Europe/London"),
- missingFileThenFile1.lookupTimeZonesByCountry("gb"));
+ assertEquals(expectedCountryTimeZones1, missingFileThenFile1.lookupCountryTimeZones("gb"));
TimeZoneFinder file2ThenFile1 =
TimeZoneFinder.createInstanceWithFallback(validFile2, validFile1);
assertEquals("2017b", file2ThenFile1.getIanaVersion());
- assertEquals(list("Europe/Paris"), file2ThenFile1.lookupTimeZoneIdsByCountry("gb"));
- assertZonesEqual(zones("Europe/Paris"), file2ThenFile1.lookupTimeZonesByCountry("gb"));
+ assertEquals(expectedCountryTimeZones2, file2ThenFile1.lookupCountryTimeZones("gb"));
// We assume the file has been validated so an invalid file is not checked ahead of time.
// We will find out when we look something up.
TimeZoneFinder invalidThenValid =
TimeZoneFinder.createInstanceWithFallback(invalidFile, validFile1);
assertNull(invalidThenValid.getIanaVersion());
- assertNull(invalidThenValid.lookupTimeZoneIdsByCountry("gb"));
- assertNull(invalidThenValid.lookupTimeZonesByCountry("gb"));
+ assertNull(invalidThenValid.lookupCountryTimeZones("gb"));
// This is not a normal case: It would imply a define shipped without a file in /system!
TimeZoneFinder missingFiles =
TimeZoneFinder.createInstanceWithFallback(missingFile, missingFile);
assertNull(missingFiles.getIanaVersion());
- assertNull(missingFiles.lookupTimeZoneIdsByCountry("gb"));
- assertNull(missingFiles.lookupTimeZonesByCountry("gb"));
+ assertNull(missingFiles.lookupCountryTimeZones("gb"));
}
@Test
@@ -185,6 +182,9 @@
@Test
public void xmlParsing_unexpectedComments() throws Exception {
+ CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+
TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
+ " <country code=\"gb\" default=\"Europe/London\">\n"
@@ -193,7 +193,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
// This is a crazy comment, but also helps prove that TEXT nodes are coalesced by the
// parser.
@@ -204,11 +204,14 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
}
@Test
public void xmlParsing_unexpectedElementsIgnored() throws Exception {
+ CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+
String unexpectedElement = "<unexpected-element>\n<a /></unexpected-element>\n";
TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " " + unexpectedElement
@@ -218,8 +221,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
@@ -229,8 +231,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
@@ -240,21 +241,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
-
- finder = validate("<timezones ianaversion=\"2017b\">\n"
- + " <countryzones>\n"
- + " <country code=\"gb\" default=\"Europe/London\">\n"
- + " <id>Europe/London</id>\n"
- + " " + unexpectedElement
- + " <id>Europe/Paris</id>\n"
- + " </country>\n"
- + " </countryzones>\n"
- + "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London", "Europe/Paris"),
- finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
@@ -264,8 +251,7 @@
+ " " + unexpectedElement
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
// This test is important because it ensures we can extend the format in future with
// more information.
@@ -277,12 +263,27 @@
+ " </countryzones>\n"
+ " " + unexpectedElement
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+ expectedCountryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London", "Europe/Paris"), "test");
+ finder = validate("<timezones ianaversion=\"2017b\">\n"
+ + " <countryzones>\n"
+ + " <country code=\"gb\" default=\"Europe/London\">\n"
+ + " <id>Europe/London</id>\n"
+ + " " + unexpectedElement
+ + " <id>Europe/Paris</id>\n"
+ + " </country>\n"
+ + " </countryzones>\n"
+ + "</timezones>\n");
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
}
@Test
public void xmlParsing_unexpectedTextIgnored() throws Exception {
+ CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
+
String unexpectedText = "unexpected-text";
TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " " + unexpectedText
@@ -292,8 +293,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
@@ -303,8 +303,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
@@ -314,9 +313,10 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+ expectedCountryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London", "Europe/Paris"), "test");
finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
+ " <country code=\"gb\" default=\"Europe/London\">\n"
@@ -326,9 +326,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
- assertEquals(list("Europe/London", "Europe/Paris"),
- finder.lookupTimeZoneIdsByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
}
@Test
@@ -374,6 +372,8 @@
@Test
public void xmlParsing_unknownTimeZoneIdIgnored() throws Exception {
+ CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+ "gb", "Europe/London", list("Europe/London"), "test");
TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+ " <countryzones>\n"
+ " <country code=\"gb\" default=\"Europe/London\">\n"
@@ -382,8 +382,7 @@
+ " </country>\n"
+ " </countryzones>\n"
+ "</timezones>\n");
- assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
- assertZonesEqual(zones("Europe/London"), finder.lookupTimeZonesByCountry("gb"));
+ assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
}
@Test
@@ -820,53 +819,6 @@
assertEquals(expectedIanaVersion, finder.getIanaVersion());
}
- @Test
- public void createValidatedCountryTimeZones_filtersBadIds() throws Exception {
- String countryIso = "iso";
- String knownTimeZoneId1 = "Europe/London";
- String knownTimeZoneId2 = "America/Los_Angeles";
- String knownTimeZoneId3 = "America/New_York";
- String unknownTimeZoneId = "Moon/Tranquility_Base";
-
- List<String> countryZoneIds = list(
- knownTimeZoneId1, knownTimeZoneId2, unknownTimeZoneId, knownTimeZoneId3);
- TimeZoneFinder.CountryTimeZones countryTimeZones =
- TimeZoneFinder.createValidatedCountryTimeZones(countryIso, knownTimeZoneId1,
- countryZoneIds, "debugInfoIgnored");
-
- assertEquals(countryIso, countryTimeZones.getCountryIso());
-
- assertEquals(knownTimeZoneId1, countryTimeZones.getDefaultTimeZoneId());
- assertEquals(knownTimeZoneId1, countryTimeZones.getDefaultTimeZoneId());
-
- // Validation should have filtered the unknown ID.
- String[] expectedTimeZoneIds = { knownTimeZoneId1, knownTimeZoneId2, knownTimeZoneId3 };
- assertEquals(list(expectedTimeZoneIds), countryTimeZones.getTimeZoneIds());
- List<TimeZone> timeZones = countryTimeZones.getTimeZones();
- for (int i = 0; i < timeZones.size(); i++) {
- TimeZone timeZone = timeZones.get(i);
- assertEquals(expectedTimeZoneIds[i], timeZone.getID());
- assertTrue(timeZone.isFrozen());
- }
- }
-
- @Test
- public void createValidatedCountryTimeZones_filtersBadDefaultId() throws Exception {
- String countryIso = "iso";
- String unknownTimeZoneId = "Moon/Tranquility_Base";
-
- List<String> countryZoneIds = list(unknownTimeZoneId);
- TimeZoneFinder.CountryTimeZones countryTimeZones =
- TimeZoneFinder.createValidatedCountryTimeZones(countryIso, unknownTimeZoneId,
- countryZoneIds, "debugInfoIgnored");
-
- assertEquals(countryIso, countryTimeZones.getCountryIso());
-
- assertNull(countryTimeZones.getDefaultTimeZoneId());
- assertEquals(Collections.emptyList(), countryTimeZones.getTimeZoneIds());
- assertEquals(Collections.emptyList(), countryTimeZones.getTimeZones());
- }
-
private void assertImmutableTimeZone(TimeZone timeZone) {
try {
timeZone.setRawOffset(1000);
@@ -888,11 +840,6 @@
assertEquals(expected, actual);
}
- private static void assertZonesEqual(List<TimeZone> expected, List<TimeZone> actual) {
- // TimeZone.equals() only checks the ID, but that's ok for these tests.
- assertEquals(expected, actual);
- }
-
private static void checkValidateThrowsParserException(String xml) throws Exception {
try {
validate(xml);
@@ -916,10 +863,6 @@
.collect(Collectors.toList());
}
- private static List<TimeZone> zones(String... ids) {
- return Arrays.stream(ids).map(TimeZone::getTimeZone).collect(Collectors.toList());
- }
-
private String createFile(String fileContent) throws IOException {
Path filePath = Files.createTempFile(testDir, null, null);
Files.write(filePath, fileContent.getBytes(StandardCharsets.UTF_8));
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index e37a84a..c4bed67 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -27,8 +27,6 @@
"luni/src/main/java/android/system/StructTimespec.java",
"luni/src/main/java/android/system/StructUcred.java",
"luni/src/main/java/android/system/StructUtsname.java",
- "luni/src/main/java/libcore/util/MutableInt.java",
- "luni/src/main/java/libcore/util/MutableLong.java",
"dalvik/src/main/java/dalvik/annotation/AnnotationDefault.java",
"dalvik/src/main/java/dalvik/annotation/EnclosingClass.java",
"dalvik/src/main/java/dalvik/annotation/EnclosingMethod.java",
@@ -301,6 +299,7 @@
"luni/src/main/java/libcore/util/EmptyArray.java",
"luni/src/main/java/libcore/util/BasicLruCache.java",
"luni/src/main/java/libcore/util/CollectionUtils.java",
+ "luni/src/main/java/libcore/util/CountryTimeZones.java",
"luni/src/main/java/libcore/util/EmptyArray.java",
"luni/src/main/java/libcore/util/NativeAllocationRegistry.java",
"luni/src/main/java/libcore/util/NonNull.java",
diff --git a/ojluni/src/main/java/java/io/CharArrayReader.java b/ojluni/src/main/java/java/io/CharArrayReader.java
index 2190be3..4140976 100644
--- a/ojluni/src/main/java/java/io/CharArrayReader.java
+++ b/ojluni/src/main/java/java/io/CharArrayReader.java
@@ -130,11 +130,12 @@
if (pos >= count) {
return -1;
}
-
+ // BEGIN Android-changed: Backport of OpenJDK 9b132 fix to avoid integer overflow.
int avail = count - pos;
if (len > avail) {
len = avail;
}
+ // END Android-changed: Backport of OpenJDK 9b132 fix to avoid integer overflow.
if (len <= 0) {
return 0;
}
@@ -159,11 +160,12 @@
public long skip(long n) throws IOException {
synchronized (lock) {
ensureOpen();
-
+ // BEGIN Android-changed: Backport of OpenJDK 9b132 fix to avoid integer overflow.
long avail = count - pos;
if (n > avail) {
n = avail;
}
+ // END Android-changed: Backport of OpenJDK 9b132 fix to avoid integer overflow.
if (n < 0) {
return 0;
}
diff --git a/ojluni/src/main/java/java/io/StringBufferInputStream.java b/ojluni/src/main/java/java/io/StringBufferInputStream.java
index f47eebc..90c5d4d 100644
--- a/ojluni/src/main/java/java/io/StringBufferInputStream.java
+++ b/ojluni/src/main/java/java/io/StringBufferInputStream.java
@@ -118,11 +118,12 @@
if (pos >= count) {
return -1;
}
-
+ // BEGIN Android-changed: Backport of OpenJDK 9b132 fix to avoid integer overflow.
int avail = count - pos;
if (len > avail) {
len = avail;
}
+ // END Android-changed: Backport of OpenJDK 9b132 fix to avoid integer overflow.
if (len <= 0) {
return 0;
}
diff --git a/ojluni/src/main/java/java/lang/Runtime.java b/ojluni/src/main/java/java/lang/Runtime.java
index 3d52814..acc75b0 100644
--- a/ojluni/src/main/java/java/lang/Runtime.java
+++ b/ojluni/src/main/java/java/lang/Runtime.java
@@ -909,7 +909,7 @@
if (absolutePath == null) {
throw new NullPointerException("absolutePath == null");
}
- String error = doLoad(absolutePath, loader);
+ String error = nativeLoad(absolutePath, loader);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
@@ -923,7 +923,7 @@
if (filename == null) {
throw new NullPointerException("filename == null");
}
- String error = doLoad(filename, fromClass.getClassLoader());
+ String error = nativeLoad(filename, fromClass.getClassLoader());
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
@@ -1011,7 +1011,7 @@
throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
System.mapLibraryName(libraryName) + "\"");
}
- String error = doLoad(filename, loader);
+ String error = nativeLoad(filename, loader);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
@@ -1026,7 +1026,7 @@
candidates.add(candidate);
if (IoUtils.canOpenReadOnly(candidate)) {
- String error = doLoad(candidate, loader);
+ String error = nativeLoad(candidate, loader);
if (error == null) {
return; // We successfully loaded the library. Job done.
}
@@ -1067,42 +1067,8 @@
}
return paths;
}
- private String doLoad(String name, ClassLoader loader) {
- // Android apps are forked from the zygote, so they can't have a custom LD_LIBRARY_PATH,
- // which means that by default an app's shared library directory isn't on LD_LIBRARY_PATH.
- // The PathClassLoader set up by frameworks/base knows the appropriate path, so we can load
- // libraries with no dependencies just fine, but an app that has multiple libraries that
- // depend on each other needed to load them in most-dependent-first order.
-
- // We added API to Android's dynamic linker so we can update the library path used for
- // the currently-running process. We pull the desired path out of the ClassLoader here
- // and pass it to nativeLoad so that it can call the private dynamic linker API.
-
- // We didn't just change frameworks/base to update the LD_LIBRARY_PATH once at the
- // beginning because multiple apks can run in the same process and third party code can
- // use its own BaseDexClassLoader.
-
- // We didn't just add a dlopen_with_custom_LD_LIBRARY_PATH call because we wanted any
- // dlopen(3) calls made from a .so's JNI_OnLoad to work too.
-
- // So, find out what the native library search path is for the ClassLoader in question...
- String librarySearchPath = null;
- if (loader != null && loader instanceof BaseDexClassLoader) {
- BaseDexClassLoader dexClassLoader = (BaseDexClassLoader) loader;
- librarySearchPath = dexClassLoader.getLdLibraryPath();
- }
- // nativeLoad should be synchronized so there's only one LD_LIBRARY_PATH in use regardless
- // of how many ClassLoaders are in the system, but dalvik doesn't support synchronized
- // internal natives.
- synchronized (this) {
- return nativeLoad(name, loader, librarySearchPath);
- }
- }
-
- // TODO: should be synchronized, but dalvik doesn't support synchronized internal natives.
- private static native String nativeLoad(String filename, ClassLoader loader,
- String librarySearchPath);
+ private static native String nativeLoad(String filename, ClassLoader loader);
/**
* Creates a localized version of an input stream. This method takes
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index 0419ede..d462033 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -1941,7 +1941,7 @@
*
* @hide
*/
- // @VisibleForTesting (would be private if not for tests)
+ // @VisibleForTesting (would be package-private if not for tests)
public final void dispatchUncaughtException(Throwable e) {
Thread.UncaughtExceptionHandler initialUeh =
Thread.getUncaughtExceptionPreHandler();
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index 7f51a61..e4a8d0f 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -38,43 +38,47 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(byte) </code><i>put</i><code>} methods that read and write
- * single bytes; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(byte) <i>put</i>} methods that read and write
+ * single bytes; </p></li>
*
- * <li><p> Relative {@link #get(byte[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of bytes from this buffer
- * into an array; </p></li>
+ * <li><p> Relative {@link #get(byte[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of bytes from this buffer
+ * into an array; </p></li>
*
- * <li><p> Relative {@link #put(byte[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of bytes from a
- * byte array or some other byte
- * buffer into this buffer; </p></li>
- *
- * <li><p> Absolute and relative {@link #getChar() </code><i>get</i><code>}
- * and {@link #putChar(char) </code><i>put</i><code>} methods that read and
- * write values of other primitive types, translating them to and from
- * sequences of bytes in a particular byte order; </p></li>
- *
- * <li><p> Methods for creating <i><a href="#views">view buffers</a></i>,
- * which allow a byte buffer to be viewed as a buffer containing values of
- * some other primitive type; and </p></li>
+ * <li><p> Relative {@link #put(byte[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of bytes from a
+ * byte array or some other byte
+ * buffer into this buffer; </p></li>
*
*
+ * <li><p> Absolute and relative {@link #getChar() <i>get</i>}
+ * and {@link #putChar(char) <i>put</i>} methods that read and
+ * write values of other primitive types, translating them to and from
+ * sequences of bytes in a particular byte order; </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} a byte buffer. </p></li>
+ * <li><p> Methods for creating <i><a href="#views">view buffers</a></i>,
+ * which allow a byte buffer to be viewed as a buffer containing values of
+ * some other primitive type; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a byte buffer. </p></li>
*
* </ul>
*
* <p> Byte buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
- * content, or by {@link #wrap(byte[]) </code><i>wrapping</i><code>} an
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, or by {@link #wrap(byte[]) <i>wrapping</i>} an
* existing byte array into a buffer.
*
- * <a name="direct">
- * <h4> Direct <i>vs.</i> non-direct buffers </h4>
+ *
+ *
+ * <a name="direct"></a>
+ * <h2> Direct <i>vs.</i> non-direct buffers </h2>
*
* <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>. Given a
* direct byte buffer, the Java virtual machine will make a best effort to
@@ -95,7 +99,7 @@
* buffers only when they yield a measureable gain in program performance.
*
* <p> A direct byte buffer may also be created by {@link
- * java.nio.channels.FileChannel#map </code>mapping<code>} a region of a file
+ * java.nio.channels.FileChannel#map mapping} a region of a file
* directly into memory. An implementation of the Java platform may optionally
* support the creation of direct byte buffers from native code via JNI. If an
* instance of one of these kinds of buffers refers to an inaccessible region
@@ -107,8 +111,9 @@
* invoking its {@link #isDirect isDirect} method. This method is provided so
* that explicit buffer management can be done in performance-critical code.
*
- * <a name="bin">
- * <h4> Access to binary data </h4>
+ *
+ * <a name="bin"></a>
+ * <h2> Access to binary data </h2>
*
* <p> This class defines methods for reading and writing values of all other
* primitive types, except <tt>boolean</tt>. Primitive values are translated
@@ -127,14 +132,14 @@
* float {@link #getFloat()}
* float {@link #getFloat(int) getFloat(int index)}
* void {@link #putFloat(float) putFloat(float f)}
- * void {@link #putFloat(int, float) putFloat(int index, float f)}</pre></blockquote>
+ * void {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote>
*
* <p> Corresponding methods are defined for the types <tt>char</tt>,
* <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>. The index
* parameters of the absolute <i>get</i> and <i>put</i> methods are in terms of
* bytes rather than of the type being read or written.
*
- * <a name="views">
+ * <a name="views"></a>
*
* <p> For access to homogeneous binary data, that is, sequences of values of
* the same type, this class defines methods that can create <i>views</i> of a
@@ -153,27 +158,31 @@
*
* <ul>
*
- * <li><p> A view buffer is indexed not in terms of bytes but rather in terms
- * of the type-specific size of its values; </p></li>
+ * <li><p> A view buffer is indexed not in terms of bytes but rather in terms
+ * of the type-specific size of its values; </p></li>
*
- * <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i>
- * methods that can transfer contiguous sequences of values between a buffer
- * and an array or some other buffer of the same type; and </p></li>
+ * <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i>
+ * methods that can transfer contiguous sequences of values between a buffer
+ * and an array or some other buffer of the same type; and </p></li>
*
- * <li><p> A view buffer is potentially much more efficient because it will
- * be direct if, and only if, its backing byte buffer is direct. </p></li>
+ * <li><p> A view buffer is potentially much more efficient because it will
+ * be direct if, and only if, its backing byte buffer is direct. </p></li>
*
* </ul>
*
* <p> The byte order of a view buffer is fixed to be that of its byte buffer
* at the time that the view is created. </p>
*
- * <h4> Invocation chaining </h4>
+*
+*
+ *
+ * <h2> Invocation chaining </h2>
*
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
*
+ *
* The sequence of statements
*
* <blockquote><pre>
@@ -186,14 +195,17 @@
* <blockquote><pre>
* bb.putInt(0xCAFEBABE).putShort(3).putShort(45);</pre></blockquote>
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class ByteBuffer
- extends Buffer
- implements Comparable<ByteBuffer> {
+ extends Buffer
+ implements Comparable<ByteBuffer>
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -207,7 +219,8 @@
// backing array, and array offset
//
ByteBuffer(int mark, int pos, int lim, int cap, // package-private
- byte[] hb, int offset) {
+ byte[] hb, int offset)
+ {
super(mark, pos, lim, cap, 0);
this.hb = hb;
this.offset = offset;
@@ -226,11 +239,15 @@
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
* initialized to zero. Whether or not it has a
- * {@link #hasArray </code>backing array<code>} is unspecified.
+ * {@link #hasArray backing array} is unspecified.
*
- * @param capacity The new buffer's capacity, in bytes
- * @return The new byte buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in bytes
+ *
+ * @return The new byte buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static ByteBuffer allocateDirect(int capacity) {
if (capacity < 0) {
@@ -247,13 +264,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in bytes
- * @return The new byte buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in bytes
+ *
+ * @return The new byte buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
@@ -269,24 +289,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new byte buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new byte buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static ByteBuffer wrap(byte[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -301,12 +329,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new byte buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new byte buffer
*/
public static ByteBuffer wrap(byte[] array) {
return wrap(array, 0, array.length);
@@ -328,7 +358,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new byte buffer
+ * @return The new byte buffer
*/
public abstract ByteBuffer slice();
@@ -345,7 +375,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new byte buffer
+ * @return The new byte buffer
*/
public abstract ByteBuffer duplicate();
@@ -365,7 +395,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only byte buffer
+ * @return The new, read-only byte buffer
*/
public abstract ByteBuffer asReadOnlyBuffer();
@@ -374,11 +404,12 @@
/**
* Relative <i>get</i> method. Reads the byte at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The byte at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The byte at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract byte get();
@@ -388,22 +419,31 @@
* <p> Writes the given byte into this buffer at the current
* position, and then increments the position. </p>
*
- * @param b The byte to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param b
+ * The byte to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer put(byte b);
/**
* Absolute <i>get</i> method. Reads the byte at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the byte will be read
- * @return The byte at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the byte will be read
+ *
+ * @return The byte at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract byte get(int index);
@@ -413,12 +453,20 @@
* <p> Writes the given byte into this buffer at the given
* index. </p>
*
- * @param index The index at which the byte will be written
- * @param b The byte value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the byte will be written
+ *
+ * @param b
+ * The byte value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer put(int index, byte b);
@@ -444,26 +492,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient bytes in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which bytes are to be written
- * @param offset The offset within the array of the first byte to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of bytes to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> bytes
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which bytes are to be written
+ *
+ * @param offset
+ * The offset within the array of the first byte to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of bytes to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> bytes
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public ByteBuffer get(byte[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -485,9 +543,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> bytes
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> bytes
+ * remaining in this buffer
*/
public ByteBuffer get(byte[] dst) {
return get(dst, 0, dst.length);
@@ -519,15 +582,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which bytes are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining bytes in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which bytes are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining bytes in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public ByteBuffer put(ByteBuffer src) {
if (!isAccessible()) {
@@ -593,25 +664,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which bytes are to be read
- * @param offset The offset within the array of the first byte to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of bytes to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which bytes are to be read
+ *
+ * @param offset
+ * The offset within the array of the first byte to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of bytes to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public ByteBuffer put(byte[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -634,9 +717,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final ByteBuffer put(byte[] src) {
return put(src, 0, src.length);
@@ -653,11 +743,11 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
- return (hb != null) && !isReadOnly();
+ return (hb != null) && !isReadOnly;
}
/**
@@ -671,9 +761,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final byte[] array() {
if (hb == null)
@@ -694,10 +788,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -725,37 +823,42 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- *
+
*
* <p> Invoke this method after writing data from a buffer in case the
* write was incomplete. The following loop, for example, copies bytes
* from one channel to another via the buffer <tt>buf</tt>:
*
- * <blockquote><pre>
- * buf.clear(); // Prepare buffer for use
- * while (in.read(buf) >= 0 || buf.position != 0) {
- * buf.flip();
- * out.write(buf);
- * buf.compact(); // In case of partial write
+ * <blockquote><pre>{@code
+ * buf.clear(); // Prepare buffer for use
+ * while (in.read(buf) >= 0 || buf.position != 0) {
+ * buf.flip();
+ * out.write(buf);
+ * buf.compact(); // In case of partial write
+ * }
* }</pre></blockquote>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer compact();
/**
- * Tells whether or not this byte buffer is direct. </p>
+ * Tells whether or not this byte buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
/**
- * Returns a string summarizing the state of this buffer. </p>
+ * Returns a string summarizing the state of this buffer.
*
- * @return A summary string
+ * @return A summary string
*/
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -782,13 +885,13 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
int p = position();
for (int i = limit() - 1; i >= p; i--)
- h = 31 * h + (int) get(i);
+ h = 31 * h + (int)get(i);
return h;
}
@@ -797,38 +900,33 @@
*
* <p> Two byte buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
- *
- *
- *
- *
- *
- *
- *
- * </p></li>
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * </p></li>
*
* </ol>
*
* <p> A byte buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof ByteBuffer))
return false;
- ByteBuffer that = (ByteBuffer) ob;
+ ByteBuffer that = (ByteBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -860,13 +958,13 @@
*
*
* Pairs of {@code byte} elements are compared as if by invoking
- * {@link Byte#compare(byte, byte)}.
- *
+ * {@link Byte#compare(byte,byte)}.
+
*
* <p> A byte buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(ByteBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -892,9 +990,9 @@
boolean bigEndian // package-private
- = true;
+ = true;
boolean nativeByteOrder // package-private
- = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);
+ = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);
/**
* Retrieves this buffer's byte order.
@@ -904,31 +1002,32 @@
* a newly-created byte buffer is always {@link ByteOrder#BIG_ENDIAN
* BIG_ENDIAN}. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public final ByteOrder order() {
return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
}
/**
- * Modifies this buffer's byte order. </p>
+ * Modifies this buffer's byte order.
*
- * @param bo The new byte order,
- * either {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
- * or {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}
- * @return This buffer
+ * @param bo
+ * The new byte order,
+ * either {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
+ * or {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}
+ *
+ * @return This buffer
*/
public final ByteBuffer order(ByteOrder bo) {
bigEndian = (bo == ByteOrder.BIG_ENDIAN);
nativeByteOrder =
- (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
+ (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
return this;
}
// Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
//
abstract byte _get(int i); // package-private
-
abstract void _put(int i, byte b); // package-private
@@ -939,9 +1038,11 @@
* composing them into a char value according to the current byte order,
* and then increments the position by two. </p>
*
- * @return The char value at the buffer's current position
- * @throws BufferUnderflowException If there are fewer than two bytes
- * remaining in this buffer
+ * @return The char value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
*/
public abstract char getChar();
@@ -953,11 +1054,17 @@
* current byte order, into this buffer at the current position, and then
* increments the position by two. </p>
*
- * @param value The char value to be written
- * @return This buffer
- * @throws BufferOverflowException If there are fewer than two bytes
- * remaining in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param value
+ * The char value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putChar(char value);
@@ -967,11 +1074,15 @@
* <p> Reads two bytes at the given index, composing them into a
* char value according to the current byte order. </p>
*
- * @param index The index from which the bytes will be read
- * @return The char value at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus one
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The char value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
*/
public abstract char getChar(int index);
@@ -990,13 +1101,21 @@
* <p> Writes two bytes containing the given char value, in the
* current byte order, into this buffer at the given index. </p>
*
- * @param index The index at which the bytes will be written
- * @param value The char value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus one
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The char value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putChar(int index, char value);
@@ -1022,7 +1141,7 @@
* if, and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return A new char buffer
+ * @return A new char buffer
*/
public abstract CharBuffer asCharBuffer();
@@ -1034,9 +1153,11 @@
* composing them into a short value according to the current byte order,
* and then increments the position by two. </p>
*
- * @return The short value at the buffer's current position
- * @throws BufferUnderflowException If there are fewer than two bytes
- * remaining in this buffer
+ * @return The short value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
*/
public abstract short getShort();
@@ -1048,11 +1169,17 @@
* current byte order, into this buffer at the current position, and then
* increments the position by two. </p>
*
- * @param value The short value to be written
- * @return This buffer
- * @throws BufferOverflowException If there are fewer than two bytes
- * remaining in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param value
+ * The short value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putShort(short value);
@@ -1062,11 +1189,15 @@
* <p> Reads two bytes at the given index, composing them into a
* short value according to the current byte order. </p>
*
- * @param index The index from which the bytes will be read
- * @return The short value at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus one
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The short value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
*/
public abstract short getShort(int index);
@@ -1085,13 +1216,21 @@
* <p> Writes two bytes containing the given short value, in the
* current byte order, into this buffer at the given index. </p>
*
- * @param index The index at which the bytes will be written
- * @param value The short value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus one
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The short value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putShort(int index, short value);
@@ -1117,7 +1256,7 @@
* if, and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return A new short buffer
+ * @return A new short buffer
*/
public abstract ShortBuffer asShortBuffer();
@@ -1129,9 +1268,11 @@
* composing them into an int value according to the current byte order,
* and then increments the position by four. </p>
*
- * @return The int value at the buffer's current position
- * @throws BufferUnderflowException If there are fewer than four bytes
- * remaining in this buffer
+ * @return The int value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
*/
public abstract int getInt();
@@ -1143,11 +1284,17 @@
* current byte order, into this buffer at the current position, and then
* increments the position by four. </p>
*
- * @param value The int value to be written
- * @return This buffer
- * @throws BufferOverflowException If there are fewer than four bytes
- * remaining in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param value
+ * The int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putInt(int value);
@@ -1157,11 +1304,15 @@
* <p> Reads four bytes at the given index, composing them into a
* int value according to the current byte order. </p>
*
- * @param index The index from which the bytes will be read
- * @return The int value at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus three
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The int value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
*/
public abstract int getInt(int index);
@@ -1180,13 +1331,21 @@
* <p> Writes four bytes containing the given int value, in the
* current byte order, into this buffer at the given index. </p>
*
- * @param index The index at which the bytes will be written
- * @param value The int value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus three
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putInt(int index, int value);
@@ -1212,7 +1371,7 @@
* if, and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return A new int buffer
+ * @return A new int buffer
*/
public abstract IntBuffer asIntBuffer();
@@ -1224,9 +1383,11 @@
* composing them into a long value according to the current byte order,
* and then increments the position by eight. </p>
*
- * @return The long value at the buffer's current position
- * @throws BufferUnderflowException If there are fewer than eight bytes
- * remaining in this buffer
+ * @return The long value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
*/
public abstract long getLong();
@@ -1238,11 +1399,17 @@
* current byte order, into this buffer at the current position, and then
* increments the position by eight. </p>
*
- * @param value The long value to be written
- * @return This buffer
- * @throws BufferOverflowException If there are fewer than eight bytes
- * remaining in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param value
+ * The long value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putLong(long value);
@@ -1252,11 +1419,15 @@
* <p> Reads eight bytes at the given index, composing them into a
* long value according to the current byte order. </p>
*
- * @param index The index from which the bytes will be read
- * @return The long value at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus seven
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The long value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
*/
public abstract long getLong(int index);
@@ -1275,13 +1446,21 @@
* <p> Writes eight bytes containing the given long value, in the
* current byte order, into this buffer at the given index. </p>
*
- * @param index The index at which the bytes will be written
- * @param value The long value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus seven
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The long value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putLong(int index, long value);
@@ -1307,7 +1486,7 @@
* if, and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return A new long buffer
+ * @return A new long buffer
*/
public abstract LongBuffer asLongBuffer();
@@ -1319,9 +1498,11 @@
* composing them into a float value according to the current byte order,
* and then increments the position by four. </p>
*
- * @return The float value at the buffer's current position
- * @throws BufferUnderflowException If there are fewer than four bytes
- * remaining in this buffer
+ * @return The float value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
*/
public abstract float getFloat();
@@ -1333,11 +1514,17 @@
* current byte order, into this buffer at the current position, and then
* increments the position by four. </p>
*
- * @param value The float value to be written
- * @return This buffer
- * @throws BufferOverflowException If there are fewer than four bytes
- * remaining in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param value
+ * The float value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putFloat(float value);
@@ -1347,11 +1534,15 @@
* <p> Reads four bytes at the given index, composing them into a
* float value according to the current byte order. </p>
*
- * @param index The index from which the bytes will be read
- * @return The float value at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus three
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The float value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
*/
public abstract float getFloat(int index);
@@ -1370,13 +1561,21 @@
* <p> Writes four bytes containing the given float value, in the
* current byte order, into this buffer at the given index. </p>
*
- * @param index The index at which the bytes will be written
- * @param value The float value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus three
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The float value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putFloat(int index, float value);
@@ -1402,7 +1601,7 @@
* if, and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return A new float buffer
+ * @return A new float buffer
*/
public abstract FloatBuffer asFloatBuffer();
@@ -1414,9 +1613,11 @@
* composing them into a double value according to the current byte order,
* and then increments the position by eight. </p>
*
- * @return The double value at the buffer's current position
- * @throws BufferUnderflowException If there are fewer than eight bytes
- * remaining in this buffer
+ * @return The double value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
*/
public abstract double getDouble();
@@ -1428,11 +1629,17 @@
* current byte order, into this buffer at the current position, and then
* increments the position by eight. </p>
*
- * @param value The double value to be written
- * @return This buffer
- * @throws BufferOverflowException If there are fewer than eight bytes
- * remaining in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param value
+ * The double value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putDouble(double value);
@@ -1442,11 +1649,15 @@
* <p> Reads eight bytes at the given index, composing them into a
* double value according to the current byte order. </p>
*
- * @param index The index from which the bytes will be read
- * @return The double value at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus seven
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The double value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
*/
public abstract double getDouble(int index);
@@ -1465,13 +1676,21 @@
* <p> Writes eight bytes containing the given double value, in the
* current byte order, into this buffer at the given index. </p>
*
- * @param index The index at which the bytes will be written
- * @param value The double value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit,
- * minus seven
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The double value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ByteBuffer putDouble(int index, double value);
@@ -1497,7 +1716,7 @@
* if, and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return A new double buffer
+ * @return A new double buffer
*/
public abstract DoubleBuffer asDoubleBuffer();
diff --git a/ojluni/src/main/java/java/nio/CharBuffer.java b/ojluni/src/main/java/java/nio/CharBuffer.java
index 65eb2db..61265d7 100644
--- a/ojluni/src/main/java/java/nio/CharBuffer.java
+++ b/ojluni/src/main/java/java/nio/CharBuffer.java
@@ -43,31 +43,37 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(char) </code><i>put</i><code>} methods that read and write
- * single chars; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(char) <i>put</i>} methods that read and write
+ * single chars; </p></li>
*
- * <li><p> Relative {@link #get(char[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of chars from this buffer
- * into an array; and</p></li>
+ * <li><p> Relative {@link #get(char[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of chars from this buffer
+ * into an array; and</p></li>
*
- * <li><p> Relative {@link #put(char[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of chars from a
- * char array, a string, or some other char
- * buffer into this buffer; and </p></li>
+ * <li><p> Relative {@link #put(char[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of chars from a
+ * char array, a string, or some other char
+ * buffer into this buffer; and </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} a char buffer. </p></li>
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a char buffer. </p></li>
*
* </ul>
*
* <p> Char buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
- * content, by {@link #wrap(char[]) </code><i>wrapping</i><code>} an existing
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(char[]) <i>wrapping</i>} an existing
* char array or string into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
+ *
+*
+ *
* <p> Like a byte buffer, a char buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
* char buffer created via the <tt>wrap</tt> methods of this class will
@@ -76,11 +82,15 @@
* a char buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
+*
+ *
* <p> This class implements the {@link CharSequence} interface so that
* character buffers may be used wherever character sequences are accepted, for
* example in the regular-expression package <tt>{@link java.util.regex}</tt>.
* </p>
*
+ *
+ *
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
@@ -99,14 +109,17 @@
* <blockquote><pre>
* cb.put("text/").put(subtype).put("; charset=").put(enc);</pre></blockquote>
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class CharBuffer
- extends Buffer
- implements Comparable<CharBuffer>, Appendable, CharSequence, Readable {
+ extends Buffer
+ implements Comparable<CharBuffer>, Appendable, CharSequence, Readable
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -120,7 +133,8 @@
// backing array, and array offset
//
CharBuffer(int mark, int pos, int lim, int cap, // package-private
- char[] hb, int offset) {
+ char[] hb, int offset)
+ {
super(mark, pos, lim, cap, 1);
this.hb = hb;
this.offset = offset;
@@ -138,13 +152,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in chars
- * @return The new char buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in chars
+ *
+ * @return The new char buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static CharBuffer allocate(int capacity) {
if (capacity < 0)
@@ -160,24 +177,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new char buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new char buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static CharBuffer wrap(char[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapCharBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -192,12 +217,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new char buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new char buffer
*/
public static CharBuffer wrap(char[] array) {
return wrap(array, 0, array.length);
@@ -212,9 +239,9 @@
*
* @param target the buffer to read characters into
* @return The number of characters added to the buffer, or
- * -1 if this source of characters is at its end
- * @throws IOException if an I/O error occurs
- * @throws NullPointerException if target is null
+ * -1 if this source of characters is at its end
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if target is null
* @throws ReadOnlyBufferException if target is a read only buffer
* @since 1.5
*/
@@ -246,19 +273,26 @@
* <tt>csq.length()</tt>, its position will be <tt>start</tt>, its limit
* will be <tt>end</tt>, and its mark will be undefined. </p>
*
- * @param csq The character sequence from which the new character buffer is to
- * be created
- * @param start The index of the first character to be used;
- * must be non-negative and no larger than <tt>csq.length()</tt>.
- * The new buffer's position will be set to this value.
- * @param end The index of the character following the last character to be
- * used; must be no smaller than <tt>start</tt> and no larger
- * than <tt>csq.length()</tt>.
- * The new buffer's limit will be set to this value.
- * @return The new character buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>start</tt> and
- * <tt>end</tt>
- * parameters do not hold
+ * @param csq
+ * The character sequence from which the new character buffer is to
+ * be created
+ *
+ * @param start
+ * The index of the first character to be used;
+ * must be non-negative and no larger than <tt>csq.length()</tt>.
+ * The new buffer's position will be set to this value.
+ *
+ * @param end
+ * The index of the character following the last character to be
+ * used; must be no smaller than <tt>start</tt> and no larger
+ * than <tt>csq.length()</tt>.
+ * The new buffer's limit will be set to this value.
+ *
+ * @return The new character buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>start</tt> and <tt>end</tt>
+ * parameters do not hold
*/
public static CharBuffer wrap(CharSequence csq, int start, int end) {
try {
@@ -276,9 +310,11 @@
* <tt>csq.length()</tt>, its position will be zero, and its mark will be
* undefined. </p>
*
- * @param csq The character sequence from which the new character buffer is to
- * be created
- * @return The new character buffer
+ * @param csq
+ * The character sequence from which the new character buffer is to
+ * be created
+ *
+ * @return The new character buffer
*/
public static CharBuffer wrap(CharSequence csq) {
return wrap(csq, 0, csq.length());
@@ -300,7 +336,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new char buffer
+ * @return The new char buffer
*/
public abstract CharBuffer slice();
@@ -317,7 +353,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new char buffer
+ * @return The new char buffer
*/
public abstract CharBuffer duplicate();
@@ -337,7 +373,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only char buffer
+ * @return The new, read-only char buffer
*/
public abstract CharBuffer asReadOnlyBuffer();
@@ -346,11 +382,12 @@
/**
* Relative <i>get</i> method. Reads the char at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The char at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The char at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract char get();
@@ -360,22 +397,31 @@
* <p> Writes the given char into this buffer at the current
* position, and then increments the position. </p>
*
- * @param c The char to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param c
+ * The char to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract CharBuffer put(char c);
/**
* Absolute <i>get</i> method. Reads the char at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the char will be read
- * @return The char at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the char will be read
+ *
+ * @return The char at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract char get(int index);
@@ -396,12 +442,20 @@
* <p> Writes the given char into this buffer at the given
* index. </p>
*
- * @param index The index at which the char will be written
- * @param c The char value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the char will be written
+ *
+ * @param c
+ * The char value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract CharBuffer put(int index, char c);
@@ -427,26 +481,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient chars in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which chars are to be written
- * @param offset The offset within the array of the first char to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of chars to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> chars
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which chars are to be written
+ *
+ * @param offset
+ * The offset within the array of the first char to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of chars to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> chars
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public CharBuffer get(char[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -502,15 +566,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which chars are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining chars in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which chars are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining chars in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public CharBuffer put(CharBuffer src) {
if (src == this)
@@ -542,25 +614,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which chars are to be read
- * @param offset The offset within the array of the first char to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of chars to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which chars are to be read
+ *
+ * @param offset
+ * The offset within the array of the first char to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of chars to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public CharBuffer put(char[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -583,9 +667,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final CharBuffer put(char[] src) {
return put(src, 0, src.length);
@@ -612,26 +703,38 @@
* <tt>dst.put(src, start, end)</tt> has exactly the same effect
* as the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = start; i < end; i++)
- * dst.put(src.charAt(i)); </pre>
+ * dst.put(src.charAt(i));
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The string from which chars are to be read
- * @param start The offset within the string of the first char to be read;
- * must be non-negative and no larger than
- * <tt>string.length()</tt>
- * @param end The offset within the string of the last char to be read,
- * plus one; must be non-negative and no larger than
- * <tt>string.length()</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>start</tt> and
- * <tt>end</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The string from which chars are to be read
+ *
+ * @param start
+ * The offset within the string of the first char to be read;
+ * must be non-negative and no larger than
+ * <tt>string.length()</tt>
+ *
+ * @param end
+ * The offset within the string of the last char to be read,
+ * plus one; must be non-negative and no larger than
+ * <tt>string.length()</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>start</tt> and <tt>end</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public CharBuffer put(String src, int start, int end) {
checkBounds(start, end - start, src.length());
@@ -667,9 +770,16 @@
* <pre>
* dst.put(s, 0, s.length()) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source string
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final CharBuffer put(String src) {
return put(src, 0, src.length());
@@ -686,8 +796,8 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
@@ -704,9 +814,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final char[] array() {
if (hb == null)
@@ -727,10 +841,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -758,15 +876,19 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract CharBuffer compact();
/**
- * Tells whether or not this char buffer is direct. </p>
+ * Tells whether or not this char buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
@@ -782,7 +904,7 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
@@ -797,15 +919,15 @@
*
* <p> Two char buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
*
*
*
@@ -813,22 +935,23 @@
*
*
*
- * </p></li>
+ * </p></li>
*
* </ol>
*
* <p> A char buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof CharBuffer))
return false;
- CharBuffer that = (CharBuffer) ob;
+ CharBuffer that = (CharBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -860,13 +983,13 @@
*
*
* Pairs of {@code char} elements are compared as if by invoking
- * {@link Character#compare(char, char)}.
- *
+ * {@link Character#compare(char,char)}.
+
*
* <p> A char buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(CharBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -896,7 +1019,7 @@
* at index <tt>limit()</tt> - 1. Invoking this method does not
* change the buffer's position. </p>
*
- * @return The specified string
+ * @return The specified string
*/
public String toString() {
return toString(position(), limit());
@@ -915,7 +1038,7 @@
* (inclusive) and the limit (exclusive); that is, it is equivalent to
* <tt>remaining()</tt>. </p>
*
- * @return The length of this character buffer
+ * @return The length of this character buffer
*/
public final int length() {
return remaining();
@@ -923,13 +1046,17 @@
/**
* Reads the character at the given index relative to the current
- * position. </p>
+ * position.
*
- * @param index The index of the character to be read, relative to the position;
- * must be non-negative and smaller than <tt>remaining()</tt>
- * @return The character at index
- * <tt>position() + index</tt>
- * @throws IndexOutOfBoundsException If the preconditions on <tt>index</tt> do not hold
+ * @param index
+ * The index of the character to be read, relative to the position;
+ * must be non-negative and smaller than <tt>remaining()</tt>
+ *
+ * @return The character at index
+ * <tt>position() + index</tt>
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on <tt>index</tt> do not hold
*/
public final char charAt(int index) {
return get(position() + checkIndex(index, 1));
@@ -948,16 +1075,22 @@
* direct if, and only if, this buffer is direct, and it will be read-only
* if, and only if, this buffer is read-only. </p>
*
- * @param start The index, relative to the current position, of the first
- * character in the subsequence; must be non-negative and no larger
- * than <tt>remaining()</tt>
- * @param end The index, relative to the current position, of the character
- * following the last character in the subsequence; must be no
- * smaller than <tt>start</tt> and no larger than
- * <tt>remaining()</tt>
- * @return The new character buffer
- * @throws IndexOutOfBoundsException If the preconditions on <tt>start</tt> and <tt>end</tt>
- * do not hold
+ * @param start
+ * The index, relative to the current position, of the first
+ * character in the subsequence; must be non-negative and no larger
+ * than <tt>remaining()</tt>
+ *
+ * @param end
+ * The index, relative to the current position, of the character
+ * following the last character in the subsequence; must be no
+ * smaller than <tt>start</tt> and no larger than
+ * <tt>remaining()</tt>
+ *
+ * @return The new character buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on <tt>start</tt> and <tt>end</tt>
+ * do not hold
*/
public abstract CharBuffer subSequence(int start, int end);
@@ -980,13 +1113,20 @@
* toString} method of a character buffer will return a subsequence whose
* content depends upon the buffer's position and limit.
*
- * @param csq The character sequence to append. If <tt>csq</tt> is
- * <tt>null</tt>, then the four characters <tt>"null"</tt> are
- * appended to this character buffer.
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
- * @since 1.5
+ * @param csq
+ * The character sequence to append. If <tt>csq</tt> is
+ * <tt>null</tt>, then the four characters <tt>"null"</tt> are
+ * appended to this character buffer.
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ *
+ * @since 1.5
*/
public CharBuffer append(CharSequence csq) {
if (csq == null)
@@ -1006,19 +1146,26 @@
* <pre>
* dst.put(csq.subSequence(start, end).toString()) </pre>
*
- * @param csq The character sequence from which a subsequence will be
- * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
- * will be appended as if <tt>csq</tt> contained the four
- * characters <tt>"null"</tt>.
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If <tt>start</tt> or <tt>end</tt> are negative,
- * <tt>start</tt>
- * is greater than <tt>end</tt>, or <tt>end</tt> is greater
- * than
- * <tt>csq.length()</tt>
- * @throws ReadOnlyBufferException If this buffer is read-only
- * @since 1.5
+ * @param csq
+ * The character sequence from which a subsequence will be
+ * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
+ * will be appended as if <tt>csq</tt> contained the four
+ * characters <tt>"null"</tt>.
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
+ * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
+ * <tt>csq.length()</tt>
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ *
+ * @since 1.5
*/
public CharBuffer append(CharSequence csq, int start, int end) {
CharSequence cs = (csq == null ? "null" : csq);
@@ -1035,11 +1182,18 @@
* <pre>
* dst.put(c) </pre>
*
- * @param c The 16-bit char to append
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
- * @since 1.5
+ * @param c
+ * The 16-bit char to append
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ *
+ * @since 1.5
*/
public CharBuffer append(char c) {
return put(c);
@@ -1054,12 +1208,12 @@
*
* <p> The byte order of a char buffer created by allocation or by
* wrapping an existing <tt>char</tt> array is the {@link
- * ByteOrder#nativeOrder </code>native order<code>} of the underlying
+ * ByteOrder#nativeOrder native order} of the underlying
* hardware. The byte order of a char buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public abstract ByteOrder order();
diff --git a/ojluni/src/main/java/java/nio/DoubleBuffer.java b/ojluni/src/main/java/java/nio/DoubleBuffer.java
index 5f63d24..d0a0c15 100644
--- a/ojluni/src/main/java/java/nio/DoubleBuffer.java
+++ b/ojluni/src/main/java/java/nio/DoubleBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -36,30 +36,37 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(double) </code><i>put</i><code>} methods that read and write
- * single doubles; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(double) <i>put</i>} methods that read and write
+ * single doubles; </p></li>
*
- * <li><p> Relative {@link #get(double[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of doubles from this buffer
- * into an array; and</p></li>
+ * <li><p> Relative {@link #get(double[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of doubles from this buffer
+ * into an array; and</p></li>
*
- * <li><p> Relative {@link #put(double[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of doubles from a
- * double array or some other double
- * buffer into this buffer; and </p></li>
+ * <li><p> Relative {@link #put(double[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of doubles from a
+ * double array or some other double
+ * buffer into this buffer; and </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} a double buffer. </p></li>
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a double buffer. </p></li>
+ *
* </ul>
*
* <p> Double buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
- * content, by {@link #wrap(double[]) </code><i>wrapping</i><code>} an existing
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(double[]) <i>wrapping</i>} an existing
* double array into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
+ *
+*
+ *
* <p> Like a byte buffer, a double buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
* double buffer created via the <tt>wrap</tt> methods of this class will
@@ -68,18 +75,24 @@
* a double buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
+*
+ *
+ *
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class DoubleBuffer
- extends Buffer
- implements Comparable<DoubleBuffer> {
+ extends Buffer
+ implements Comparable<DoubleBuffer>
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -93,7 +106,8 @@
// backing array, and array offset
//
DoubleBuffer(int mark, int pos, int lim, int cap, // package-private
- double[] hb, int offset) {
+ double[] hb, int offset)
+ {
super(mark, pos, lim, cap, 3);
this.hb = hb;
this.offset = offset;
@@ -111,13 +125,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in doubles
- * @return The new double buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in doubles
+ *
+ * @return The new double buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static DoubleBuffer allocate(int capacity) {
if (capacity < 0)
@@ -133,24 +150,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new double buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new double buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static DoubleBuffer wrap(double[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapDoubleBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -165,12 +190,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new double buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new double buffer
*/
public static DoubleBuffer wrap(double[] array) {
return wrap(array, 0, array.length);
@@ -192,7 +219,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new double buffer
+ * @return The new double buffer
*/
public abstract DoubleBuffer slice();
@@ -209,7 +236,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new double buffer
+ * @return The new double buffer
*/
public abstract DoubleBuffer duplicate();
@@ -229,7 +256,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only double buffer
+ * @return The new, read-only double buffer
*/
public abstract DoubleBuffer asReadOnlyBuffer();
@@ -238,11 +265,12 @@
/**
* Relative <i>get</i> method. Reads the double at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The double at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The double at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract double get();
@@ -252,22 +280,31 @@
* <p> Writes the given double into this buffer at the current
* position, and then increments the position. </p>
*
- * @param d The double to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param d
+ * The double to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract DoubleBuffer put(double d);
/**
* Absolute <i>get</i> method. Reads the double at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the double will be read
- * @return The double at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the double will be read
+ *
+ * @return The double at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract double get(int index);
@@ -277,12 +314,20 @@
* <p> Writes the given double into this buffer at the given
* index. </p>
*
- * @param index The index at which the double will be written
- * @param d The double value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the double will be written
+ *
+ * @param d
+ * The double value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract DoubleBuffer put(int index, double d);
@@ -308,26 +353,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient doubles in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which doubles are to be written
- * @param offset The offset within the array of the first double to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of doubles to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> doubles
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which doubles are to be written
+ *
+ * @param offset
+ * The offset within the array of the first double to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of doubles to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> doubles
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public DoubleBuffer get(double[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -349,9 +404,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> doubles
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> doubles
+ * remaining in this buffer
*/
public DoubleBuffer get(double[] dst) {
return get(dst, 0, dst.length);
@@ -383,15 +443,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which doubles are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining doubles in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which doubles are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining doubles in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public DoubleBuffer put(DoubleBuffer src) {
if (src == this)
@@ -423,25 +491,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which doubles are to be read
- * @param offset The offset within the array of the first double to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of doubles to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which doubles are to be read
+ *
+ * @param offset
+ * The offset within the array of the first double to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of doubles to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public DoubleBuffer put(double[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -464,9 +544,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final DoubleBuffer put(double[] src) {
return put(src, 0, src.length);
@@ -483,8 +570,8 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
@@ -501,9 +588,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final double[] array() {
if (hb == null)
@@ -524,10 +615,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -555,23 +650,27 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract DoubleBuffer compact();
/**
- * Tells whether or not this double buffer is direct. </p>
+ * Tells whether or not this double buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
/**
- * Returns a string summarizing the state of this buffer. </p>
+ * Returns a string summarizing the state of this buffer.
*
- * @return A summary string
+ * @return A summary string
*/
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -598,7 +697,7 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
@@ -613,38 +712,39 @@
*
* <p> Two double buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
- *
- * This method considers two double elements {@code a} and {@code b}
- * to be equal if
- * {@code (a == b) || (Double.isNaN(a) && Double.isNaN(b))}.
- * The values {@code -0.0} and {@code +0.0} are considered to be
- * equal, unlike {@link Double#equals(Object)}.
- *
- * </p></li>
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * This method considers two double elements {@code a} and {@code b}
+ * to be equal if
+ * {@code (a == b) || (Double.isNaN(a) && Double.isNaN(b))}.
+ * The values {@code -0.0} and {@code +0.0} are considered to be
+ * equal, unlike {@link Double#equals(Object)}.
+
+ * </p></li>
*
* </ol>
*
* <p> A double buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof DoubleBuffer))
return false;
- DoubleBuffer that = (DoubleBuffer) ob;
+ DoubleBuffer that = (DoubleBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -667,22 +767,19 @@
* <p> Two double buffers are compared by comparing their sequences of
* remaining elements lexicographically, without regard to the starting
* position of each sequence within its corresponding buffer.
- *
+
* Pairs of {@code double} elements are compared as if by invoking
- * {@link Double#compare(double, double)}, except that
+ * {@link Double#compare(double,double)}, except that
* {@code -0.0} and {@code 0.0} are considered to be equal.
* {@code Double.NaN} is considered by this method to be equal
* to itself and greater than all other {@code double} values
* (including {@code Double.POSITIVE_INFINITY}).
- *
- *
- *
- *
+
*
* <p> A double buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(DoubleBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -698,11 +795,10 @@
private static int compare(double x, double y) {
- return ((x < y) ? -1 :
- (x > y) ? +1 :
- (x == y) ? 0 :
- Double.isNaN(x) ? (Double.isNaN(y) ? 0 : +1) : -1);
-
+ return ((x < y) ? -1 :
+ (x > y) ? +1 :
+ (x == y) ? 0 :
+ Double.isNaN(x) ? (Double.isNaN(y) ? 0 : +1) : -1);
}
@@ -717,12 +813,12 @@
*
* <p> The byte order of a double buffer created by allocation or by
* wrapping an existing <tt>double</tt> array is the {@link
- * ByteOrder#nativeOrder </code>native order<code>} of the underlying
+ * ByteOrder#nativeOrder native order} of the underlying
* hardware. The byte order of a double buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public abstract ByteOrder order();
diff --git a/ojluni/src/main/java/java/nio/FloatBuffer.java b/ojluni/src/main/java/java/nio/FloatBuffer.java
index cd2a502..90e65ff 100644
--- a/ojluni/src/main/java/java/nio/FloatBuffer.java
+++ b/ojluni/src/main/java/java/nio/FloatBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -36,31 +36,37 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(float) </code><i>put</i><code>} methods that read and write
- * single floats; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(float) <i>put</i>} methods that read and write
+ * single floats; </p></li>
*
- * <li><p> Relative {@link #get(float[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of floats from this buffer
- * into an array; and</p></li>
+ * <li><p> Relative {@link #get(float[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of floats from this buffer
+ * into an array; and</p></li>
*
- * <li><p> Relative {@link #put(float[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of floats from a
- * float array or some other float
- * buffer into this buffer; and </p></li>
+ * <li><p> Relative {@link #put(float[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of floats from a
+ * float array or some other float
+ * buffer into this buffer; and </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} a float buffer. </p></li>
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a float buffer. </p></li>
*
* </ul>
*
* <p> Float buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
- * content, by {@link #wrap(float[]) </code><i>wrapping</i><code>} an existing
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(float[]) <i>wrapping</i>} an existing
* float array into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
+ *
+*
+ *
* <p> Like a byte buffer, a float buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
* float buffer created via the <tt>wrap</tt> methods of this class will
@@ -69,18 +75,24 @@
* a float buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
+*
+ *
+ *
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class FloatBuffer
- extends Buffer
- implements Comparable<FloatBuffer> {
+ extends Buffer
+ implements Comparable<FloatBuffer>
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -94,7 +106,8 @@
// backing array, and array offset
//
FloatBuffer(int mark, int pos, int lim, int cap, // package-private
- float[] hb, int offset) {
+ float[] hb, int offset)
+ {
super(mark, pos, lim, cap, 2);
this.hb = hb;
this.offset = offset;
@@ -112,13 +125,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in floats
- * @return The new float buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in floats
+ *
+ * @return The new float buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static FloatBuffer allocate(int capacity) {
if (capacity < 0)
@@ -134,24 +150,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new float buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new float buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static FloatBuffer wrap(float[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapFloatBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -166,12 +190,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new float buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new float buffer
*/
public static FloatBuffer wrap(float[] array) {
return wrap(array, 0, array.length);
@@ -193,7 +219,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new float buffer
+ * @return The new float buffer
*/
public abstract FloatBuffer slice();
@@ -210,7 +236,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new float buffer
+ * @return The new float buffer
*/
public abstract FloatBuffer duplicate();
@@ -230,7 +256,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only float buffer
+ * @return The new, read-only float buffer
*/
public abstract FloatBuffer asReadOnlyBuffer();
@@ -239,11 +265,12 @@
/**
* Relative <i>get</i> method. Reads the float at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The float at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The float at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract float get();
@@ -253,22 +280,31 @@
* <p> Writes the given float into this buffer at the current
* position, and then increments the position. </p>
*
- * @param f The float to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param f
+ * The float to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract FloatBuffer put(float f);
/**
* Absolute <i>get</i> method. Reads the float at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the float will be read
- * @return The float at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the float will be read
+ *
+ * @return The float at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract float get(int index);
@@ -278,12 +314,20 @@
* <p> Writes the given float into this buffer at the given
* index. </p>
*
- * @param index The index at which the float will be written
- * @param f The float value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the float will be written
+ *
+ * @param f
+ * The float value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract FloatBuffer put(int index, float f);
@@ -309,26 +353,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient floats in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which floats are to be written
- * @param offset The offset within the array of the first float to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of floats to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> floats
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which floats are to be written
+ *
+ * @param offset
+ * The offset within the array of the first float to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of floats to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> floats
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public FloatBuffer get(float[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -350,9 +404,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> floats
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> floats
+ * remaining in this buffer
*/
public FloatBuffer get(float[] dst) {
return get(dst, 0, dst.length);
@@ -384,15 +443,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which floats are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining floats in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which floats are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining floats in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public FloatBuffer put(FloatBuffer src) {
if (src == this)
@@ -424,25 +491,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which floats are to be read
- * @param offset The offset within the array of the first float to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of floats to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which floats are to be read
+ *
+ * @param offset
+ * The offset within the array of the first float to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of floats to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public FloatBuffer put(float[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -465,9 +544,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final FloatBuffer put(float[] src) {
return put(src, 0, src.length);
@@ -484,8 +570,8 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
@@ -502,9 +588,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final float[] array() {
if (hb == null)
@@ -525,10 +615,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -556,23 +650,27 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract FloatBuffer compact();
/**
- * Tells whether or not this float buffer is direct. </p>
+ * Tells whether or not this float buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
/**
- * Returns a string summarizing the state of this buffer. </p>
+ * Returns a string summarizing the state of this buffer.
*
- * @return A summary string
+ * @return A summary string
*/
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -599,7 +697,7 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
@@ -614,38 +712,39 @@
*
* <p> Two float buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
- *
- * This method considers two float elements {@code a} and {@code b}
- * to be equal if
- * {@code (a == b) || (Float.isNaN(a) && Float.isNaN(b))}.
- * The values {@code -0.0} and {@code +0.0} are considered to be
- * equal, unlike {@link Float#equals(Object)}.
- *
- * </p></li>
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * This method considers two float elements {@code a} and {@code b}
+ * to be equal if
+ * {@code (a == b) || (Float.isNaN(a) && Float.isNaN(b))}.
+ * The values {@code -0.0} and {@code +0.0} are considered to be
+ * equal, unlike {@link Float#equals(Object)}.
+
+ * </p></li>
*
* </ol>
*
* <p> A float buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof FloatBuffer))
return false;
- FloatBuffer that = (FloatBuffer) ob;
+ FloatBuffer that = (FloatBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -668,9 +767,9 @@
* <p> Two float buffers are compared by comparing their sequences of
* remaining elements lexicographically, without regard to the starting
* position of each sequence within its corresponding buffer.
- *
+
* Pairs of {@code float} elements are compared as if by invoking
- * {@link Float#compare(float, float)}, except that
+ * {@link Float#compare(float,float)}, except that
* {@code -0.0} and {@code 0.0} are considered to be equal.
* {@code Float.NaN} is considered by this method to be equal
* to itself and greater than all other {@code float} values
@@ -682,8 +781,8 @@
*
* <p> A float buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(FloatBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -697,25 +796,28 @@
private static int compare(float x, float y) {
- return ((x < y) ? -1 :
- (x > y) ? +1 :
- (x == y) ? 0 :
- Float.isNaN(x) ? (Float.isNaN(y) ? 0 : +1) : -1);
-
+ return ((x < y) ? -1 :
+ (x > y) ? +1 :
+ (x == y) ? 0 :
+ Float.isNaN(x) ? (Float.isNaN(y) ? 0 : +1) : -1);
}
+ // -- Other char stuff --
+
+ // -- Other byte stuff: Access to binary data --
+
/**
* Retrieves this buffer's byte order.
*
* <p> The byte order of a float buffer created by allocation or by
* wrapping an existing <tt>float</tt> array is the {@link
- * ByteOrder#nativeOrder </code>native order<code>} of the underlying
+ * ByteOrder#nativeOrder native order} of the underlying
* hardware. The byte order of a float buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public abstract ByteOrder order();
diff --git a/ojluni/src/main/java/java/nio/IntBuffer.java b/ojluni/src/main/java/java/nio/IntBuffer.java
index 4a20949..a0004ba 100644
--- a/ojluni/src/main/java/java/nio/IntBuffer.java
+++ b/ojluni/src/main/java/java/nio/IntBuffer.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -37,32 +37,37 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(int) </code><i>put</i><code>} methods that read and write
- * single ints; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(int) <i>put</i>} methods that read and write
+ * single ints; </p></li>
*
- * <li><p> Relative {@link #get(int[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of ints from this buffer
- * into an array; and</p></li>
+ * <li><p> Relative {@link #get(int[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of ints from this buffer
+ * into an array; and</p></li>
*
- * <li><p> Relative {@link #put(int[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of ints from an
- * int array or some other int
- * buffer into this buffer; and </p></li>
+ * <li><p> Relative {@link #put(int[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of ints from an
+ * int array or some other int
+ * buffer into this buffer; and </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} an int buffer. </p></li>
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * an int buffer. </p></li>
*
* </ul>
*
* <p> Int buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
+ * <i>allocation</i>}, which allocates space for the buffer's
*
- * content, by {@link #wrap(int[]) </code><i>wrapping</i><code>} an existing
+ *
+ * content, by {@link #wrap(int[]) <i>wrapping</i>} an existing
* int array into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
+ *
+*
+ *
* <p> Like a byte buffer, an int buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
* int buffer created via the <tt>wrap</tt> methods of this class will
@@ -71,18 +76,24 @@
* an int buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
+*
+ *
+ *
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class IntBuffer
- extends Buffer
- implements Comparable<IntBuffer> {
+ extends Buffer
+ implements Comparable<IntBuffer>
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -96,7 +107,8 @@
// backing array, and array offset
//
IntBuffer(int mark, int pos, int lim, int cap, // package-private
- int[] hb, int offset) {
+ int[] hb, int offset)
+ {
super(mark, pos, lim, cap, 2);
this.hb = hb;
this.offset = offset;
@@ -114,13 +126,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in ints
- * @return The new int buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in ints
+ *
+ * @return The new int buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static IntBuffer allocate(int capacity) {
if (capacity < 0)
@@ -136,24 +151,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new int buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new int buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static IntBuffer wrap(int[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapIntBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -168,12 +191,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new int buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new int buffer
*/
public static IntBuffer wrap(int[] array) {
return wrap(array, 0, array.length);
@@ -195,7 +220,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new int buffer
+ * @return The new int buffer
*/
public abstract IntBuffer slice();
@@ -212,7 +237,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new int buffer
+ * @return The new int buffer
*/
public abstract IntBuffer duplicate();
@@ -232,7 +257,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only int buffer
+ * @return The new, read-only int buffer
*/
public abstract IntBuffer asReadOnlyBuffer();
@@ -241,11 +266,12 @@
/**
* Relative <i>get</i> method. Reads the int at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The int at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The int at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract int get();
@@ -255,22 +281,31 @@
* <p> Writes the given int into this buffer at the current
* position, and then increments the position. </p>
*
- * @param i The int to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param i
+ * The int to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract IntBuffer put(int i);
/**
* Absolute <i>get</i> method. Reads the int at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the int will be read
- * @return The int at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the int will be read
+ *
+ * @return The int at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract int get(int index);
@@ -280,12 +315,20 @@
* <p> Writes the given int into this buffer at the given
* index. </p>
*
- * @param index The index at which the int will be written
- * @param i The int value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the int will be written
+ *
+ * @param i
+ * The int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract IntBuffer put(int index, int i);
@@ -311,26 +354,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient ints in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which ints are to be written
- * @param offset The offset within the array of the first int to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of ints to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> ints
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which ints are to be written
+ *
+ * @param offset
+ * The offset within the array of the first int to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of ints to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> ints
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public IntBuffer get(int[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -352,9 +405,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> ints
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> ints
+ * remaining in this buffer
*/
public IntBuffer get(int[] dst) {
return get(dst, 0, dst.length);
@@ -386,15 +444,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which ints are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining ints in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which ints are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining ints in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public IntBuffer put(IntBuffer src) {
if (src == this)
@@ -426,25 +492,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which ints are to be read
- * @param offset The offset within the array of the first int to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of ints to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which ints are to be read
+ *
+ * @param offset
+ * The offset within the array of the first int to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of ints to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public IntBuffer put(int[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -467,9 +545,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final IntBuffer put(int[] src) {
return put(src, 0, src.length);
@@ -486,8 +571,8 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
@@ -504,9 +589,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int[] array() {
if (hb == null)
@@ -527,10 +616,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -558,23 +651,27 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract IntBuffer compact();
/**
- * Tells whether or not this int buffer is direct. </p>
+ * Tells whether or not this int buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
/**
- * Returns a string summarizing the state of this buffer. </p>
+ * Returns a string summarizing the state of this buffer.
*
- * @return A summary string
+ * @return A summary string
*/
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -601,7 +698,7 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
@@ -616,15 +713,15 @@
*
* <p> Two int buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
*
*
*
@@ -632,22 +729,23 @@
*
*
*
- * </p></li>
+ * </p></li>
*
* </ol>
*
* <p> A int buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof IntBuffer))
return false;
- IntBuffer that = (IntBuffer) ob;
+ IntBuffer that = (IntBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -679,13 +777,13 @@
*
*
* Pairs of {@code int} elements are compared as if by invoking
- * {@link Integer#compare(int, int)}.
- *
+ * {@link Integer#compare(int,int)}.
+
*
* <p> A int buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(IntBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -715,12 +813,12 @@
*
* <p> The byte order of an int buffer created by allocation or by
* wrapping an existing <tt>int</tt> array is the {@link
- * ByteOrder#nativeOrder </code>native order<code>} of the underlying
+ * ByteOrder#nativeOrder native order} of the underlying
* hardware. The byte order of an int buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public abstract ByteOrder order();
diff --git a/ojluni/src/main/java/java/nio/LongBuffer.java b/ojluni/src/main/java/java/nio/LongBuffer.java
index c1c2888..80e506c 100644
--- a/ojluni/src/main/java/java/nio/LongBuffer.java
+++ b/ojluni/src/main/java/java/nio/LongBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -36,31 +36,37 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(long) </code><i>put</i><code>} methods that read and write
- * single longs; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(long) <i>put</i>} methods that read and write
+ * single longs; </p></li>
*
- * <li><p> Relative {@link #get(long[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of longs from this buffer
- * into an array; and</p></li>
+ * <li><p> Relative {@link #get(long[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of longs from this buffer
+ * into an array; and</p></li>
*
- * <li><p> Relative {@link #put(long[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of longs from a
- * long array or some other long
- * buffer into this buffer; and </p></li>
+ * <li><p> Relative {@link #put(long[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of longs from a
+ * long array or some other long
+ * buffer into this buffer; and </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} a long buffer. </p></li>
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a long buffer. </p></li>
*
* </ul>
*
* <p> Long buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
- * content, by {@link #wrap(long[]) </code><i>wrapping</i><code>} an existing
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(long[]) <i>wrapping</i>} an existing
* long array into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
+ *
+*
+ *
* <p> Like a byte buffer, a long buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
* long buffer created via the <tt>wrap</tt> methods of this class will
@@ -69,18 +75,24 @@
* a long buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
+*
+ *
+ *
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class LongBuffer
- extends Buffer
- implements Comparable<LongBuffer> {
+ extends Buffer
+ implements Comparable<LongBuffer>
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -94,7 +106,8 @@
// backing array, and array offset
//
LongBuffer(int mark, int pos, int lim, int cap, // package-private
- long[] hb, int offset) {
+ long[] hb, int offset)
+ {
super(mark, pos, lim, cap, 3);
this.hb = hb;
this.offset = offset;
@@ -112,13 +125,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in longs
- * @return The new long buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in longs
+ *
+ * @return The new long buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static LongBuffer allocate(int capacity) {
if (capacity < 0)
@@ -134,24 +150,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new long buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new long buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static LongBuffer wrap(long[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapLongBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -166,12 +190,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new long buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new long buffer
*/
public static LongBuffer wrap(long[] array) {
return wrap(array, 0, array.length);
@@ -193,7 +219,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new long buffer
+ * @return The new long buffer
*/
public abstract LongBuffer slice();
@@ -210,7 +236,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new long buffer
+ * @return The new long buffer
*/
public abstract LongBuffer duplicate();
@@ -230,7 +256,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only long buffer
+ * @return The new, read-only long buffer
*/
public abstract LongBuffer asReadOnlyBuffer();
@@ -239,11 +265,12 @@
/**
* Relative <i>get</i> method. Reads the long at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The long at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The long at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract long get();
@@ -253,22 +280,31 @@
* <p> Writes the given long into this buffer at the current
* position, and then increments the position. </p>
*
- * @param l The long to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param l
+ * The long to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract LongBuffer put(long l);
/**
* Absolute <i>get</i> method. Reads the long at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the long will be read
- * @return The long at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the long will be read
+ *
+ * @return The long at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract long get(int index);
@@ -278,12 +314,20 @@
* <p> Writes the given long into this buffer at the given
* index. </p>
*
- * @param index The index at which the long will be written
- * @param l The long value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the long will be written
+ *
+ * @param l
+ * The long value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract LongBuffer put(int index, long l);
@@ -309,26 +353,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient longs in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which longs are to be written
- * @param offset The offset within the array of the first long to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of longs to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> longs
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which longs are to be written
+ *
+ * @param offset
+ * The offset within the array of the first long to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of longs to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> longs
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public LongBuffer get(long[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -350,9 +404,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> longs
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> longs
+ * remaining in this buffer
*/
public LongBuffer get(long[] dst) {
return get(dst, 0, dst.length);
@@ -384,15 +443,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which longs are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining longs in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which longs are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining longs in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public LongBuffer put(LongBuffer src) {
if (src == this)
@@ -424,25 +491,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which longs are to be read
- * @param offset The offset within the array of the first long to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of longs to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which longs are to be read
+ *
+ * @param offset
+ * The offset within the array of the first long to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of longs to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public LongBuffer put(long[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -465,9 +544,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final LongBuffer put(long[] src) {
return put(src, 0, src.length);
@@ -484,8 +570,8 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
@@ -502,9 +588,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final long[] array() {
if (hb == null)
@@ -525,10 +615,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -556,23 +650,27 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract LongBuffer compact();
/**
- * Tells whether or not this long buffer is direct. </p>
+ * Tells whether or not this long buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
/**
- * Returns a string summarizing the state of this buffer. </p>
+ * Returns a string summarizing the state of this buffer.
*
- * @return A summary string
+ * @return A summary string
*/
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -599,7 +697,7 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
@@ -614,38 +712,33 @@
*
* <p> Two long buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
- *
- *
- *
- *
- *
- *
- *
- * </p></li>
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * </p></li>
*
* </ol>
*
* <p> A long buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof LongBuffer))
return false;
- LongBuffer that = (LongBuffer) ob;
+ LongBuffer that = (LongBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -677,13 +770,13 @@
*
*
* Pairs of {@code long} elements are compared as if by invoking
- * {@link Long#compare(long, long)}.
- *
+ * {@link Long#compare(long,long)}.
+
*
* <p> A long buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(LongBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -713,12 +806,12 @@
*
* <p> The byte order of a long buffer created by allocation or by
* wrapping an existing <tt>long</tt> array is the {@link
- * ByteOrder#nativeOrder </code>native order<code>} of the underlying
+ * ByteOrder#nativeOrder native order} of the underlying
* hardware. The byte order of a long buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public abstract ByteOrder order();
diff --git a/ojluni/src/main/java/java/nio/ShortBuffer.java b/ojluni/src/main/java/java/nio/ShortBuffer.java
index 9ca0f36..6903b54 100644
--- a/ojluni/src/main/java/java/nio/ShortBuffer.java
+++ b/ojluni/src/main/java/java/nio/ShortBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -36,32 +36,37 @@
*
* <ul>
*
- * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- * {@link #put(short) </code><i>put</i><code>} methods that read and write
- * single shorts; </p></li>
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(short) <i>put</i>} methods that read and write
+ * single shorts; </p></li>
*
- * <li><p> Relative {@link #get(short[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of shorts from this buffer
- * into an array; and</p></li>
+ * <li><p> Relative {@link #get(short[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of shorts from this buffer
+ * into an array; and</p></li>
*
- * <li><p> Relative {@link #put(short[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of shorts from a
- * short array or some other short
- * buffer into this buffer; and </p></li>
+ * <li><p> Relative {@link #put(short[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of shorts from a
+ * short array or some other short
+ * buffer into this buffer; and </p></li>
*
- * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- * #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} a short buffer. </p></li>
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a short buffer. </p></li>
*
* </ul>
*
* <p> Short buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
+ * <i>allocation</i>}, which allocates space for the buffer's
*
- * content, by {@link #wrap(short[]) </code><i>wrapping</i><code>} an existing
+ *
+ * content, by {@link #wrap(short[]) <i>wrapping</i>} an existing
* short array into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
+ *
+*
+ *
* <p> Like a byte buffer, a short buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
* short buffer created via the <tt>wrap</tt> methods of this class will
@@ -70,18 +75,24 @@
* a short buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
+*
+ *
+ *
* <p> Methods in this class that do not otherwise have a value to return are
* specified to return the buffer upon which they are invoked. This allows
* method invocations to be chained.
*
+ *
+ *
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class ShortBuffer
- extends Buffer
- implements Comparable<ShortBuffer> {
+ extends Buffer
+ implements Comparable<ShortBuffer>
+{
// These fields are declared here rather than in Heap-X-Buffer in order to
// reduce the number of virtual method invocations needed to access these
@@ -95,7 +106,8 @@
// backing array, and array offset
//
ShortBuffer(int mark, int pos, int lim, int cap, // package-private
- short[] hb, int offset) {
+ short[] hb, int offset)
+ {
super(mark, pos, lim, cap, 1);
this.hb = hb;
this.offset = offset;
@@ -113,13 +125,16 @@
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
- * initialized to zero. It will have a {@link #array
- * </code>backing array<code>}, and its {@link #arrayOffset </code>array
- * offset<code>} will be zero.
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
*
- * @param capacity The new buffer's capacity, in shorts
- * @return The new short buffer
- * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
+ * @param capacity
+ * The new buffer's capacity, in shorts
+ *
+ * @return The new short buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
*/
public static ShortBuffer allocate(int capacity) {
if (capacity < 0)
@@ -135,24 +150,32 @@
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
* will be <tt>offset + length</tt>, and its mark will be undefined. Its
- * {@link #array </code>backing array<code>} will be the given array, and
- * its {@link #arrayOffset </code>array offset<code>} will be zero. </p>
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
*
- * @param array The array that will back the new buffer
- * @param offset The offset of the subarray to be used; must be non-negative and
- * no larger than <tt>array.length</tt>. The new buffer's position
- * will be set to this value.
- * @param length The length of the subarray to be used;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>.
- * The new buffer's limit will be set to <tt>offset + length</tt>.
- * @return The new short buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new short buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public static ShortBuffer wrap(short[] array,
- int offset, int length) {
+ int offset, int length)
+ {
try {
return new HeapShortBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
@@ -167,12 +190,14 @@
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
- * undefined. Its {@link #array </code>backing array<code>} will be the
- * given array, and its {@link #arrayOffset </code>array offset<code>} will
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
* be zero. </p>
*
- * @param array The array that will back this buffer
- * @return The new short buffer
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new short buffer
*/
public static ShortBuffer wrap(short[] array) {
return wrap(array, 0, array.length);
@@ -194,7 +219,7 @@
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new short buffer
+ * @return The new short buffer
*/
public abstract ShortBuffer slice();
@@ -211,7 +236,7 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new short buffer
+ * @return The new short buffer
*/
public abstract ShortBuffer duplicate();
@@ -231,7 +256,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only short buffer
+ * @return The new, read-only short buffer
*/
public abstract ShortBuffer asReadOnlyBuffer();
@@ -240,11 +265,12 @@
/**
* Relative <i>get</i> method. Reads the short at this buffer's
- * current position, and then increments the position. </p>
+ * current position, and then increments the position.
*
- * @return The short at the buffer's current position
- * @throws BufferUnderflowException If the buffer's current position is not smaller than its
- * limit
+ * @return The short at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
*/
public abstract short get();
@@ -254,22 +280,31 @@
* <p> Writes the given short into this buffer at the current
* position, and then increments the position. </p>
*
- * @param s The short to be written
- * @return This buffer
- * @throws BufferOverflowException If this buffer's current position is not smaller than its
- * limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param s
+ * The short to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ShortBuffer put(short s);
/**
* Absolute <i>get</i> method. Reads the short at the given
- * index. </p>
+ * index.
*
- * @param index The index from which the short will be read
- * @return The short at the given index
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
+ * @param index
+ * The index from which the short will be read
+ *
+ * @return The short at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
*/
public abstract short get(int index);
@@ -279,12 +314,20 @@
* <p> Writes the given short into this buffer at the given
* index. </p>
*
- * @param index The index at which the short will be written
- * @param s The short value to be written
- * @return This buffer
- * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
- * or not smaller than the buffer's limit
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param index
+ * The index at which the short will be written
+ *
+ * @param s
+ * The short value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ShortBuffer put(int index, short s);
@@ -310,26 +353,36 @@
* <tt>src.get(dst, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst[i] = src.get(); </pre>
+ * dst[i] = src.get();
+ * }</pre>
*
* except that it first checks that there are sufficient shorts in
- * this buffer and it is potentially much more efficient. </p>
+ * this buffer and it is potentially much more efficient.
*
- * @param dst The array into which shorts are to be written
- * @param offset The offset within the array of the first short to be
- * written; must be non-negative and no larger than
- * <tt>dst.length</tt>
- * @param length The maximum number of shorts to be written to the given
- * array; must be non-negative and no larger than
- * <tt>dst.length - offset</tt>
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> shorts
- * remaining in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
+ * @param dst
+ * The array into which shorts are to be written
+ *
+ * @param offset
+ * The offset within the array of the first short to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of shorts to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> shorts
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
*/
public ShortBuffer get(short[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
@@ -351,9 +404,14 @@
* <pre>
* src.get(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferUnderflowException If there are fewer than <tt>length</tt> shorts
- * remaining in this buffer
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> shorts
+ * remaining in this buffer
*/
public ShortBuffer get(short[] dst) {
return get(dst, 0, dst.length);
@@ -385,15 +443,23 @@
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The source buffer from which shorts are to be read;
- * must not be this buffer
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * for the remaining shorts in the source buffer
- * @throws IllegalArgumentException If the source buffer is this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source buffer from which shorts are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining shorts in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public ShortBuffer put(ShortBuffer src) {
if (src == this)
@@ -425,25 +491,37 @@
* <tt>dst.put(src, off, len)</tt> has exactly the same effect as
* the loop
*
- * <pre>
+ * <pre>{@code
* for (int i = off; i < off + len; i++)
- * dst.put(a[i]); </pre>
+ * dst.put(a[i]);
+ * }</pre>
*
* except that it first checks that there is sufficient space in this
- * buffer and it is potentially much more efficient. </p>
+ * buffer and it is potentially much more efficient.
*
- * @param src The array from which shorts are to be read
- * @param offset The offset within the array of the first short to be read;
- * must be non-negative and no larger than <tt>array.length</tt>
- * @param length The number of shorts to be read from the given array;
- * must be non-negative and no larger than
- * <tt>array.length - offset</tt>
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws IndexOutOfBoundsException If the preconditions on the <tt>offset</tt> and
- * <tt>length</tt>
- * parameters do not hold
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The array from which shorts are to be read
+ *
+ * @param offset
+ * The offset within the array of the first short to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of shorts to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public ShortBuffer put(short[] src, int offset, int length) {
checkBounds(offset, length, src.length);
@@ -466,9 +544,16 @@
* <pre>
* dst.put(a, 0, a.length) </pre>
*
- * @return This buffer
- * @throws BufferOverflowException If there is insufficient space in this buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public final ShortBuffer put(short[] src) {
return put(src, 0, src.length);
@@ -485,8 +570,8 @@
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
* </p>
*
- * @return <tt>true</tt> if, and only if, this buffer
- * is backed by an array and is not read-only
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
@@ -503,9 +588,13 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The array that backs this buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final short[] array() {
if (hb == null)
@@ -526,10 +615,14 @@
* method in order to ensure that this buffer has an accessible backing
* array. </p>
*
- * @return The offset within this buffer's array
- * of the first element of the buffer
- * @throws ReadOnlyBufferException If this buffer is backed by an array but is read-only
- * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
*/
public final int arrayOffset() {
if (hb == null)
@@ -557,23 +650,27 @@
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
*
- * @return This buffer
- * @throws ReadOnlyBufferException If this buffer is read-only
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
*/
public abstract ShortBuffer compact();
/**
- * Tells whether or not this short buffer is direct. </p>
+ * Tells whether or not this short buffer is direct.
*
- * @return <tt>true</tt> if, and only if, this buffer is direct
+ * @return <tt>true</tt> if, and only if, this buffer is direct
*/
public abstract boolean isDirect();
/**
- * Returns a string summarizing the state of this buffer. </p>
+ * Returns a string summarizing the state of this buffer.
*
- * @return A summary string
+ * @return A summary string
*/
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -600,7 +697,7 @@
* to use buffers as keys in hash maps or similar data structures unless it
* is known that their contents will not change. </p>
*
- * @return The current hash code of this buffer
+ * @return The current hash code of this buffer
*/
public int hashCode() {
int h = 1;
@@ -615,38 +712,33 @@
*
* <p> Two short buffers are equal if, and only if,
*
- * <p><ol>
+ * <ol>
*
- * <li><p> They have the same element type, </p></li>
+ * <li><p> They have the same element type, </p></li>
*
- * <li><p> They have the same number of remaining elements, and
- * </p></li>
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
*
- * <li><p> The two sequences of remaining elements, considered
- * independently of their starting positions, are pointwise equal.
- *
- *
- *
- *
- *
- *
- *
- * </p></li>
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * </p></li>
*
* </ol>
*
* <p> A short buffer is not equal to any other type of object. </p>
*
- * @param ob The object to which this buffer is to be compared
- * @return <tt>true</tt> if, and only if, this buffer is equal to the
- * given object
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
*/
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof ShortBuffer))
return false;
- ShortBuffer that = (ShortBuffer) ob;
+ ShortBuffer that = (ShortBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
@@ -678,13 +770,13 @@
*
*
* Pairs of {@code short} elements are compared as if by invoking
- * {@link Short#compare(short, short)}.
- *
+ * {@link Short#compare(short,short)}.
+
*
* <p> A short buffer is not comparable to any other type of object.
*
- * @return A negative integer, zero, or a positive integer as this buffer
- * is less than, equal to, or greater than the given buffer
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
*/
public int compareTo(ShortBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
@@ -714,12 +806,12 @@
*
* <p> The byte order of a short buffer created by allocation or by
* wrapping an existing <tt>short</tt> array is the {@link
- * ByteOrder#nativeOrder </code>native order<code>} of the underlying
+ * ByteOrder#nativeOrder native order} of the underlying
* hardware. The byte order of a short buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
- * @return This buffer's byte order
+ * @return This buffer's byte order
*/
public abstract ByteOrder order();
diff --git a/ojluni/src/main/java/java/security/AlgorithmParameters.java b/ojluni/src/main/java/java/security/AlgorithmParameters.java
index 864866e..bca4a5c 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameters.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameters.java
@@ -66,6 +66,10 @@
* <td>10+</td>
* </tr>
* <tr>
+ * <td>ChaCha20</td>
+ * <td>28+</td>
+ * </tr>
+ * <tr>
* <td>DES</td>
* <td>1+</td>
* </tr>
diff --git a/ojluni/src/main/java/java/util/TreeMap.java b/ojluni/src/main/java/java/util/TreeMap.java
index dc55ba6..f46fbb7 100644
--- a/ojluni/src/main/java/java/util/TreeMap.java
+++ b/ojluni/src/main/java/java/util/TreeMap.java
@@ -536,34 +536,8 @@
public V put(K key, V value) {
TreeMapEntry<K,V> t = root;
if (t == null) {
- // BEGIN Android-changed: Work around buggy comparators. http://b/34084348
- // We could just call compare(key, key) for its side effect of checking the type and
- // nullness of the input key. However, several applications seem to have written comparators
- // that only expect to be called on elements that aren't equal to each other (after
- // making assumptions about the domain of the map). Clearly, such comparators are bogus
- // because get() would never work, but TreeSets are frequently used for sorting a set
- // of distinct elements.
- //
- // As a temporary work around, we perform the null & instanceof checks by hand so that
- // we can guarantee that elements are never compared against themselves.
- //
- // **** THIS CHANGE WILL BE REVERTED IN A FUTURE ANDROID RELEASE ****
- //
- // Upstream code was:
- // compare(key, key); // type (and possibly null) check
- if (comparator != null) {
- if (key == null) {
- comparator.compare(key, key);
- }
- } else {
- if (key == null) {
- throw new NullPointerException("key == null");
- } else if (!(key instanceof Comparable)) {
- throw new ClassCastException(
- "Cannot cast" + key.getClass().getName() + " to Comparable.");
- }
- }
- // END Android-changed: Work around buggy comparators. http://b/34084348
+ compare(key, key); // type (and possibly null) check
+
root = new TreeMapEntry<>(key, value, null);
size = 1;
modCount++;
diff --git a/ojluni/src/main/java/java/util/concurrent/TimeUnit.java b/ojluni/src/main/java/java/util/concurrent/TimeUnit.java
index fa52083..44d7964 100644
--- a/ojluni/src/main/java/java/util/concurrent/TimeUnit.java
+++ b/ojluni/src/main/java/java/util/concurrent/TimeUnit.java
@@ -37,10 +37,6 @@
import java.util.Objects;
-// BEGIN android-note
-// removed java 9 ChronoUnit related code
-// END android-note
-
/**
* A {@code TimeUnit} represents time durations at a given unit of
* granularity and provides utility methods to convert across units,
@@ -395,4 +391,53 @@
Thread.sleep(ms, ns);
}
}
+
+ // BEGIN Android-removed: OpenJDK 9 ChronoUnit related code.
+ /*
+ /**
+ * Converts this {@code TimeUnit} to the equivalent {@code ChronoUnit}.
+ *
+ * @return the converted equivalent ChronoUnit
+ * @since 9
+ *
+ public ChronoUnit toChronoUnit() {
+ switch (this) {
+ case NANOSECONDS: return ChronoUnit.NANOS;
+ case MICROSECONDS: return ChronoUnit.MICROS;
+ case MILLISECONDS: return ChronoUnit.MILLIS;
+ case SECONDS: return ChronoUnit.SECONDS;
+ case MINUTES: return ChronoUnit.MINUTES;
+ case HOURS: return ChronoUnit.HOURS;
+ case DAYS: return ChronoUnit.DAYS;
+ default: throw new AssertionError();
+ }
+ }
+
+ /**
+ * Converts a {@code ChronoUnit} to the equivalent {@code TimeUnit}.
+ *
+ * @param chronoUnit the ChronoUnit to convert
+ * @return the converted equivalent TimeUnit
+ * @throws IllegalArgumentException if {@code chronoUnit} has no
+ * equivalent TimeUnit
+ * @throws NullPointerException if {@code chronoUnit} is null
+ * @since 9
+ *
+ public static TimeUnit of(ChronoUnit chronoUnit) {
+ switch (Objects.requireNonNull(chronoUnit, "chronoUnit")) {
+ case NANOS: return TimeUnit.NANOSECONDS;
+ case MICROS: return TimeUnit.MICROSECONDS;
+ case MILLIS: return TimeUnit.MILLISECONDS;
+ case SECONDS: return TimeUnit.SECONDS;
+ case MINUTES: return TimeUnit.MINUTES;
+ case HOURS: return TimeUnit.HOURS;
+ case DAYS: return TimeUnit.DAYS;
+ default:
+ throw new IllegalArgumentException(
+ "No TimeUnit equivalent for " + chronoUnit);
+ }
+ }
+ */
+ // END Android-removed: OpenJDK 9 ChronoUnit related code.
+
}
diff --git a/ojluni/src/main/java/javax/crypto/Cipher.java b/ojluni/src/main/java/javax/crypto/Cipher.java
index 010587d..f3da679 100644
--- a/ojluni/src/main/java/javax/crypto/Cipher.java
+++ b/ojluni/src/main/java/javax/crypto/Cipher.java
@@ -174,18 +174,29 @@
* <td>26+</td>
* </tr>
* <tr>
- * <td>ARC4</td>
+ * <td rowspan="2">ARC4</td>
* <td>ECB</td>
* <td>NoPadding</td>
* <td>10+</td>
* </tr>
* <tr>
+ * <td>NONE</td>
+ * <td>NoPadding</td>
+ * <td>28+</td>
+ * </tr>
+ * <tr>
* <td>BLOWFISH</td>
* <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
* <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
* <td>10+</td>
* </tr>
* <tr>
+ * <td>ChaCha20</td>
+ * <td>NONE<br>Poly1305</td>
+ * <td>NoPadding</td>
+ * <td>28+</td>
+ * </tr>
+ * <tr>
* <td>DES</td>
* <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
* <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
diff --git a/ojluni/src/main/java/javax/crypto/KeyGenerator.java b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
index b0977f0..2d6f43d 100644
--- a/ojluni/src/main/java/javax/crypto/KeyGenerator.java
+++ b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
@@ -109,6 +109,10 @@
* <td>10+</td>
* </tr>
* <tr>
+ * <td>ChaCha20</td>
+ * <td>28+</td>
+ * </tr>
+ * <tr>
* <td>DES</td>
* <td>1+</td>
* </tr>
diff --git a/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java b/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
index d2e5820..94c401f 100644
--- a/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
+++ b/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
@@ -143,6 +143,19 @@
!lookupClass.isInterface(); // interfaces are types, not classes.
}
+ // Android-removed: Use public API instead of getClassModifiers() to check if public.
+ /*
+ static int getClassModifiers(Class<?> c) {
+ // This would return the mask stored by javac for the source-level modifiers.
+ // return c.getModifiers();
+ // But what we need for JVM access checks are the actual bits from the class header.
+ // ...But arrays and primitives are synthesized with their own odd flags:
+ if (c.isArray() || c.isPrimitive())
+ return c.getModifiers();
+ return Reflection.getClassAccessFlags(c);
+ }
+ */
+
/**
* Evaluate the JVM linkage rules for access to the given class on behalf of caller.
* <h3>JVM Specification, 5.4.4 "Access Control"</h3>
@@ -157,8 +170,13 @@
public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass,
int allowedModes) {
if (allowedModes == 0) return false;
- // Android-changed: Use public APIs to figure out whether a class
- // is public or not.
+ // Android-changed: Use public API instead of getClassModifiers() to check if public.
+ /*
+ assert((allowedModes & PUBLIC) != 0 &&
+ (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0);
+ int mods = getClassModifiers(refc);
+ if (isPublic(mods))
+ */
if (Modifier.isPublic(refc.getModifiers()))
return true;
if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
@@ -215,6 +233,7 @@
*/
public static boolean isSamePackage(Class<?> class1, Class<?> class2) {
// Android-changed: Throw IAE (instead of asserting) if called with array classes.
+ // assert(!class1.isArray() && !class2.isArray());
if (class1.isArray() || class2.isArray()) {
throw new IllegalArgumentException();
}
diff --git a/ojluni/src/main/native/Runtime.c b/ojluni/src/main/native/Runtime.c
index f070249..4c023b5 100644
--- a/ojluni/src/main/native/Runtime.c
+++ b/ojluni/src/main/native/Runtime.c
@@ -75,9 +75,9 @@
JNIEXPORT jstring JNICALL
Runtime_nativeLoad(JNIEnv* env, jclass ignored, jstring javaFilename,
- jobject javaLoader, jstring javaLibrarySearchPath)
+ jobject javaLoader)
{
- return JVM_NativeLoad(env, javaFilename, javaLoader, javaLibrarySearchPath);
+ return JVM_NativeLoad(env, javaFilename, javaLoader);
}
static JNINativeMethod gMethods[] = {
@@ -87,7 +87,7 @@
NATIVE_METHOD(Runtime, gc, "()V"),
NATIVE_METHOD(Runtime, nativeExit, "(I)V"),
NATIVE_METHOD(Runtime, nativeLoad,
- "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)"
+ "(Ljava/lang/String;Ljava/lang/ClassLoader;)"
"Ljava/lang/String;"),
};
diff --git a/ojluni/src/main/native/jvm.h b/ojluni/src/main/native/jvm.h
index 48b5e62..83067ce 100644
--- a/ojluni/src/main/native/jvm.h
+++ b/ojluni/src/main/native/jvm.h
@@ -166,7 +166,7 @@
JVM_ActiveProcessorCount(void);
JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename,
- jobject javaLoader, jstring javaLibrarySearchPath);
+ jobject javaLoader);
JNIEXPORT void * JNICALL
JVM_LoadLibrary(const char *name);
diff --git a/ojluni/src/test/testng.xml b/ojluni/src/test/testng.xml
index 5c0e62f..92c2a27 100644
--- a/ojluni/src/test/testng.xml
+++ b/ojluni/src/test/testng.xml
@@ -173,7 +173,6 @@
<class name="tck.java.time.zone.TCKZoneRules" />
<class name="tck.java.time.zone.TCKZoneRulesProvider" />
<class name="test.java.time.AbstractTest" />
- <class name="test.java.time.chrono;" />
<class name="test.java.time.chrono.TestChronoLocalDate" />
<class name="test.java.time.chrono.TestChronologyPerf" />
<class name="test.java.time.chrono.TestIsoChronoImpl" />
@@ -239,4 +238,4 @@
</classes>
</test>
-</suite>
\ No newline at end of file
+</suite>
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index 124a457..8730405 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -1,6 +1,6 @@
# This file is autogenerated. See libcore/tools/docs/crypto/README for details.
{
- "api_level": "26",
+ "api_level": "28",
"categories": [
{
"algorithms": [
@@ -41,6 +41,10 @@
"supported_api_levels": "10+"
},
{
+ "name": "ChaCha20",
+ "supported_api_levels": "28+"
+ },
+ {
"name": "DES",
"supported_api_levels": "1+"
},
@@ -283,6 +287,10 @@
"supported_api_levels": "10+"
},
{
+ "name": "ARC4/NONE/NoPadding",
+ "supported_api_levels": "28+"
+ },
+ {
"name": "BLOWFISH/CBC/ISO10126Padding",
"supported_api_levels": "10+"
},
@@ -355,6 +363,14 @@
"supported_api_levels": "10+"
},
{
+ "name": "ChaCha20/NONE/NoPadding",
+ "supported_api_levels": "28+"
+ },
+ {
+ "name": "ChaCha20/Poly1305/NoPadding",
+ "supported_api_levels": "28+"
+ },
+ {
"name": "DES/CBC/ISO10126Padding",
"supported_api_levels": "1+"
},
@@ -624,6 +640,10 @@
"supported_api_levels": "10+"
},
{
+ "name": "ChaCha20",
+ "supported_api_levels": "28+"
+ },
+ {
"name": "DES",
"supported_api_levels": "1+"
},
@@ -2721,5 +2741,5 @@
"name": "TrustManagerFactory"
}
],
- "last_updated": "2017-05-05 07:40:17 UTC"
+ "last_updated": "2018-01-03 14:21:23 UTC"
}
\ No newline at end of file