diff options
241 files changed, 7701 insertions, 4578 deletions
diff --git a/NativeCode.mk b/NativeCode.mk index 910527c..b21dd2d 100644 --- a/NativeCode.mk +++ b/NativeCode.mk @@ -82,7 +82,7 @@ LOCAL_CPPFLAGS += $(core_cppflags) LOCAL_SRC_FILES += $(core_src_files) LOCAL_C_INCLUDES += $(core_c_includes) LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libcrypto libdl libexpat libicuuc libicui18n libnativehelper libz libutils -LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive +LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive libbase LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libjavacore LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk @@ -157,8 +157,8 @@ endif LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libjavacore LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk -LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host -LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive-host libutils +LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host libziparchive-host +LOCAL_STATIC_LIBRARIES += $(core_static_libraries) LOCAL_MULTILIB := both LOCAL_CXX_STL := libc++ include $(BUILD_HOST_SHARED_LIBRARY) diff --git a/benchmarks/src/benchmarks/regression/ProviderBenchmark.java b/benchmarks/src/benchmarks/regression/ProviderBenchmark.java new file mode 100644 index 0000000..649aa01 --- /dev/null +++ b/benchmarks/src/benchmarks/regression/ProviderBenchmark.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 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 benchmarks.regression; + +import java.security.Provider; +import java.security.Security; +import javax.crypto.Cipher; + +import com.google.caliper.Param; +import com.google.caliper.SimpleBenchmark; +import javax.net.ssl.SSLSocketFactory; + +public class ProviderBenchmark extends SimpleBenchmark { + public void timeStableProviders(int reps) throws Exception { + for (int i = 0; i < reps; ++i) { + Cipher c = Cipher.getInstance("RSA"); + } + } + + public void timeWithNewProvider(int reps) throws Exception { + for (int i = 0; i < reps; ++i) { + Security.addProvider(new MockProvider()); + try { + Cipher c = Cipher.getInstance("RSA"); + } finally { + Security.removeProvider("Mock"); + } + } + } + + private static class MockProvider extends Provider { + public MockProvider() { + super("Mock", 1.0, "Mock me!"); + } + } +} diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java index 4124ffa..5ef00bf 100644 --- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java +++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java @@ -130,24 +130,8 @@ public class BaseDexClassLoader extends ClassLoader { } result.append(directory); } - return result.toString(); - } - /** - * Returns the list of jar/apk files containing classes and - * resources, delimited by {@code File.pathSeparator}. - * - * @hide - */ - public String getDexPath() { - StringBuilder builder = new StringBuilder(); - for (File file : pathList.getDexFiles()) { - if (builder.length() > 0) { - builder.append(':'); - } - builder.append(file); - } - return builder.toString(); + return result.toString(); } @Override public String toString() { diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java index 79f2912..52d5d8a 100644 --- a/dalvik/src/main/java/dalvik/system/DexFile.java +++ b/dalvik/src/main/java/dalvik/system/DexFile.java @@ -318,8 +318,6 @@ public final class DexFile { * @throws java.io.IOException if fileName is not a valid apk/jar file or * if problems occur while parsing it. * @throws java.lang.NullPointerException if fileName is null. - * @throws dalvik.system.StaleDexCacheError if the optimized dex file - * is stale but exists on a read-only partition. */ public static native boolean isDexOptNeeded(String fileName) throws FileNotFoundException, IOException; @@ -368,8 +366,6 @@ public final class DexFile { * @throws java.io.IOException if fileName is not a valid apk/jar file or * if problems occur while parsing it. * @throws java.lang.NullPointerException if fileName is null. - * @throws dalvik.system.StaleDexCacheError if the optimized dex file - * is stale but exists on a read-only partition. * * @hide */ diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java index b1ff1c8..e25feb9 100644 --- a/dalvik/src/main/java/dalvik/system/DexPathList.java +++ b/dalvik/src/main/java/dalvik/system/DexPathList.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; import libcore.io.IoUtils; import libcore.io.Libcore; import static android.system.OsConstants.*; @@ -47,13 +48,11 @@ import static android.system.OsConstants.*; */ /*package*/ final class DexPathList { private static final String DEX_SUFFIX = ".dex"; + private static final String zipSeparator = "!/"; /** class definition context */ private final ClassLoader definingContext; - /** List of dexfiles. */ - private final List<File> dexFiles; - /** * List of dex/resource (class path) elements. * Should be called pathElements, but the Facebook app uses reflection @@ -61,9 +60,15 @@ import static android.system.OsConstants.*; */ private final Element[] dexElements; - /** List of native library directories. */ + /** List of native library path elements. */ + private final Element[] nativeLibraryPathElements; + + /** List of application native library directories. */ private final List<File> nativeLibraryDirectories; + /** List of system native library directories. */ + private final List<File> systemNativeLibraryDirectories; + /** * Exceptions thrown during creation of the dexElements list. */ @@ -84,6 +89,7 @@ import static android.system.OsConstants.*; */ public DexPathList(ClassLoader definingContext, String dexPath, String libraryPath, File optimizedDirectory) { + if (definingContext == null) { throw new NullPointerException("definingContext == null"); } @@ -108,23 +114,46 @@ import static android.system.OsConstants.*; } this.definingContext = definingContext; + ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>(); // save dexPath for BaseDexClassLoader - this.dexFiles = splitDexPath(dexPath); - this.dexElements = makeDexElements(dexFiles, optimizedDirectory, - suppressedExceptions); + this.dexElements = makePathElements(splitDexPath(dexPath), optimizedDirectory, + suppressedExceptions); + + // Native libraries may exist in both the system and + // application library paths, and we use this search order: + // + // 1. This class loader's library path for application libraries (libraryPath): + // 1.1. Native library directories + // 1.2. Path to libraries in apk-files + // 2. The VM's library path from the system property for system libraries + // also known as java.library.path + // + // This order was reversed prior to Gingerbread; see http://b/2933456. + this.nativeLibraryDirectories = splitPaths(libraryPath, false); + this.systemNativeLibraryDirectories = + splitPaths(System.getProperty("java.library.path"), true); + List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories); + allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories); + + this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null, + suppressedExceptions); + if (suppressedExceptions.size() > 0) { this.dexElementsSuppressedExceptions = suppressedExceptions.toArray(new IOException[suppressedExceptions.size()]); } else { dexElementsSuppressedExceptions = null; } - this.nativeLibraryDirectories = splitLibraryPath(libraryPath); } @Override public String toString() { + List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories); + allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories); + File[] nativeLibraryDirectoriesArray = - nativeLibraryDirectories.toArray(new File[nativeLibraryDirectories.size()]); + allNativeLibraryDirectories.toArray( + new File[allNativeLibraryDirectories.size()]); return "DexPathList[" + Arrays.toString(dexElements) + ",nativeLibraryDirectories=" + Arrays.toString(nativeLibraryDirectoriesArray) + "]"; @@ -138,38 +167,13 @@ import static android.system.OsConstants.*; } /** - * For BaseDexClassLoader.getDexPath. - */ - public List<File> getDexFiles() { - return dexFiles; - } - - /** * Splits the given dex path string into elements using the path * separator, pruning out any elements that do not refer to existing * and readable files. (That is, directories are not included in the * result.) */ private static List<File> splitDexPath(String path) { - return splitPaths(path, null, false); - } - - /** - * Splits the given library directory path string into elements - * using the path separator ({@code File.pathSeparator}, which - * defaults to {@code ":"} on Android, appending on the elements - * from the system library path, and pruning out any elements that - * do not refer to existing and readable directories. - */ - private static List<File> splitLibraryPath(String path) { - // Native libraries may exist in both the system and - // application library paths, and we use this search order: - // - // 1. this class loader's library path for application libraries - // 2. the VM's library path from the system property for system libraries - // - // This order was reversed prior to Gingerbread; see http://b/2933456. - return splitPaths(path, System.getProperty("java.library.path"), true); + return splitPaths(path, false); } /** @@ -181,55 +185,55 @@ import static android.system.OsConstants.*; * are empty or {@code null}, or all elements get pruned out, then * this returns a zero-element list. */ - private static List<File> splitPaths(String path1, String path2, boolean wantDirectories) { - List<File> result = new ArrayList<File>(); + private static List<File> splitPaths(String searchPath, boolean directoriesOnly) { + List<File> result = new ArrayList<>(); - splitAndAdd(path1, wantDirectories, result); - splitAndAdd(path2, wantDirectories, result); - return result; - } - - /** - * Helper for {@link #splitPaths}, which does the actual splitting - * and filtering and adding to a result. - */ - private static void splitAndAdd(String searchPath, boolean directoriesOnly, - List<File> resultList) { - if (searchPath == null) { - return; - } - for (String path : searchPath.split(":")) { - try { - StructStat sb = Libcore.os.stat(path); - if (!directoriesOnly || S_ISDIR(sb.st_mode)) { - resultList.add(new File(path)); + if (searchPath != null) { + for (String path : searchPath.split(File.pathSeparator)) { + if (directoriesOnly) { + try { + StructStat sb = Libcore.os.stat(path); + if (!S_ISDIR(sb.st_mode)) { + continue; + } + } catch (ErrnoException ignored) { + continue; + } } - } catch (ErrnoException ignored) { + result.add(new File(path)); } } + + return result; } /** * Makes an array of dex/resource path elements, one per element of * the given array. */ - private static Element[] makeDexElements(List<File> files, File optimizedDirectory, - List<IOException> suppressedExceptions) { - ArrayList<Element> elements = new ArrayList<Element>(); + private static Element[] makePathElements(List<File> files, File optimizedDirectory, + List<IOException> suppressedExceptions) { + List<Element> elements = new ArrayList<>(); /* * Open all files and load the (direct or contained) dex files * up front. */ for (File file : files) { File zip = null; + File dir = new File(""); DexFile dex = null; + String path = file.getPath(); String name = file.getName(); - if (file.isDirectory()) { - // We support directories for looking up resources. - // This is only useful for running libcore tests. + if (path.contains(zipSeparator)) { + String split[] = path.split(zipSeparator, 2); + zip = new File(split[0]); + dir = new File(split[1]); + } else if (file.isDirectory()) { + // We support directories for looking up resources and native libraries. + // Looking up resources in directories is useful for running libcore tests. elements.add(new Element(file, true, null, null)); - } else if (file.isFile()){ + } else if (file.isFile()) { if (name.endsWith(DEX_SUFFIX)) { // Raw dex file (not inside a zip/jar). try { @@ -258,7 +262,7 @@ import static android.system.OsConstants.*; } if ((zip != null) || (dex != null)) { - elements.add(new Element(file, false, zip, dex)); + elements.add(new Element(dir, false, zip, dex)); } } @@ -391,12 +395,15 @@ import static android.system.OsConstants.*; */ public String findLibrary(String libraryName) { String fileName = System.mapLibraryName(libraryName); - for (File directory : nativeLibraryDirectories) { - String path = new File(directory, fileName).getPath(); - if (IoUtils.canOpenReadOnly(path)) { + + for (Element element : nativeLibraryPathElements) { + String path = element.findNativeLibrary(fileName); + + if (path != null) { return path; } } + return null; } @@ -404,7 +411,7 @@ import static android.system.OsConstants.*; * Element of the dex/resource file path */ /*package*/ static class Element { - private final File file; + private final File dir; private final boolean isDirectory; private final File zip; private final DexFile dexFile; @@ -412,8 +419,8 @@ import static android.system.OsConstants.*; private ZipFile zipFile; private boolean initialized; - public Element(File file, boolean isDirectory, File zip, DexFile dexFile) { - this.file = file; + public Element(File dir, boolean isDirectory, File zip, DexFile dexFile) { + this.dir = dir; this.isDirectory = isDirectory; this.zip = zip; this.dexFile = dexFile; @@ -421,9 +428,10 @@ import static android.system.OsConstants.*; @Override public String toString() { if (isDirectory) { - return "directory \"" + file + "\""; + return "directory \"" + dir + "\""; } else if (zip != null) { - return "zip file \"" + zip + "\""; + return "zip file \"" + zip + "\"" + + (dir != null && !dir.getPath().isEmpty() ? ", dir \"" + dir + "\"" : ""); } else { return "dex file \"" + dexFile + "\""; } @@ -449,18 +457,51 @@ import static android.system.OsConstants.*; * (e.g. if the file isn't actually a zip/jar * file). */ - System.logE("Unable to open zip file: " + file, ioe); + System.logE("Unable to open zip file: " + zip, ioe); zipFile = null; } } + /** + * Returns true if entry with specified path exists and not compressed. + * + * Note that ZipEntry does not provide information about offset so we + * cannot reliably check if entry is page-aligned. For now we are going + * take optimistic approach and rely on (1) if library was extracted + * it would have been found by the previous step (2) if library was not extracted + * but STORED and not page-aligned the installation of the app would have failed + * because of checks in PackageManagerService. + */ + private boolean isZipEntryExistsAndStored(ZipFile zipFile, String path) { + ZipEntry entry = zipFile.getEntry(path); + return entry != null && entry.getMethod() == ZipEntry.STORED; + } + + public String findNativeLibrary(String name) { + maybeInit(); + + if (isDirectory) { + String path = new File(dir, name).getPath(); + if (IoUtils.canOpenReadOnly(path)) { + return path; + } + } else if (zipFile != null) { + String entryName = new File(dir, name).getPath(); + if (isZipEntryExistsAndStored(zipFile, entryName)) { + return zip.getPath() + zipSeparator + entryName; + } + } + + return null; + } + public URL findResource(String name) { maybeInit(); // We support directories so we can run tests and/or legacy code // that uses Class.getResource. if (isDirectory) { - File resourceFile = new File(file, name); + File resourceFile = new File(dir, name); if (resourceFile.exists()) { try { return resourceFile.toURI().toURL(); @@ -487,7 +528,7 @@ import static android.system.OsConstants.*; * might end up with illegal URLs for relative * names. */ - return new URL("jar:" + file.toURL() + "!/" + name); + return new URL("jar:" + zip.toURL() + "!/" + name); } catch (MalformedURLException ex) { throw new RuntimeException(ex); } diff --git a/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java b/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java deleted file mode 100644 index 8bdd86a..0000000 --- a/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008 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 dalvik.system; - -/** - * Is thrown when the VM determines that a DEX file's cache is out of date, and - * that there is no way to recreate it. - * - * @hide - */ -public class StaleDexCacheError extends VirtualMachineError { - /** - * Creates a new exception instance and initializes it with default values. - */ - public StaleDexCacheError() { - super(); - } - - /** - * Creates a new exception instance and initializes it with a given message. - * - * @param detailMessage the error message - */ - public StaleDexCacheError(String detailMessage) { - super(detailMessage); - } -} diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt index 6470e36..f5a13c6 100644 --- a/expectations/knownfailures.txt +++ b/expectations/knownfailures.txt @@ -1509,5 +1509,22 @@ "libcore.java.util.zip.Zip64FileTest#testZip64Support_totalLargerThan4G", "libcore.java.util.zip.Zip64FileTest#testZip64Support_hugeEntry" ] +}, +{ + description: "OsTest.test_PacketSocketAddress needs CAP_NET_RAW", + bug: 19764047, + result: EXEC_FAILED, + names: [ + "libcore.io.OsTest#test_PacketSocketAddress" + ] +}, +{ + description: "Need to rewrite tests for the client-side of renegotiation", + bug: 21876068, + result: EXEC_FAILED, + names: [ + "com.android.org.conscrypt.NativeCryptoTest#test_SSL_renegotiate", + "com.android.org.conscrypt.NativeCryptoTest#test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate" + ] } ] diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java index b6a5861..264e004 100644 --- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java +++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java @@ -922,7 +922,10 @@ public class MulticastSocketTest extends junit.framework.TestCase { return iface.isUp() // Typically loopback interfaces do not support multicast, but we rule them out // explicitly anyway. - && !iface.isLoopback() && iface.supportsMulticast() + && !iface.isLoopback() + // Point-to-point interfaces are known to cause problems. http://b/23279677 + && !iface.isPointToPoint() + && iface.supportsMulticast() && iface.getInetAddresses().hasMoreElements(); } diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java index ffdfb2c..892cd1d 100644 --- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java +++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java @@ -16,6 +16,10 @@ package org.apache.harmony.tests.java.nio; import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; public class DirectByteBufferTest extends ByteBufferTest { @@ -57,4 +61,57 @@ public class DirectByteBufferTest extends ByteBufferTest { public void testIsReadOnly() { assertFalse(buf.isReadOnly()); } + + // http://b/19692084 + // http://b/21491780 + public void testUnalignedReadsAndWrites() { + // We guarantee that the first byte of the buffer is 8 byte aligned. + ByteBuffer buf = ByteBuffer.allocateDirect(23); + // Native order is always little endian, so this forces swaps. + buf.order(ByteOrder.BIG_ENDIAN); + + for (int i = 0; i < 8; ++i) { + buf.position(i); + + // 2 byte swaps. + ShortBuffer shortBuf = buf.asShortBuffer(); + short[] shortArray = new short[] { 42, 24 }; + + // Write. + shortBuf.put(shortArray); + // Read + shortBuf.flip(); + shortBuf.get(shortArray); + // Assert Equality + assertEquals(42, shortArray[0]); + assertEquals(24, shortArray[1]); + + buf.position(i); + // 4 byte swaps. + IntBuffer intBuf = buf.asIntBuffer(); + int[] intArray = new int[] { 967, 1983 }; + // Write. + intBuf.put(intArray); + // Read + intBuf.flip(); + intBuf.get(intArray); + // Assert Equality + assertEquals(967, intArray[0]); + assertEquals(1983, intArray[1]); + + + buf.position(i); + // 8 byte swaps. + LongBuffer longBuf = buf.asLongBuffer(); + long[] longArray = new long[] { 2147484614L, 2147485823L }; + // Write. + longBuf.put(longArray); + // Read + longBuf.flip(); + longBuf.get(longArray); + // Assert Equality + assertEquals(2147484614L, longArray[0]); + assertEquals(2147485823L, longArray[1]); + } + } } diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java index 8f68d6e..9360c00 100644 --- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java +++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java @@ -36,6 +36,7 @@ import javax.net.ssl.SSLException; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import junit.framework.TestCase; import libcore.java.security.StandardNames; +import libcore.javax.net.ssl.TestSSLContext; /** * Tests for SSLEngine class @@ -1042,21 +1043,12 @@ public class SSLEngineTest extends TestCase { private ByteBuffer writeBuffer; - HandshakeHandler(boolean clientMode, SourceChannel in, SinkChannel out) throws Exception { + HandshakeHandler(SSLContext context, boolean clientMode, SourceChannel in, SinkChannel out) + throws Exception { this.in = in; this.out = out; - engine = getEngine(); + engine = context.createSSLEngine(); engine.setUseClientMode(clientMode); - String[] cipherSuites = engine.getSupportedCipherSuites(); - Set<String> enabledSuites = new HashSet<String>(); - for (String cipherSuite : cipherSuites) { - if (cipherSuite.contains("anon")) { - enabledSuites.add(cipherSuite); - } - } - engine.setEnabledCipherSuites((String[]) enabledSuites.toArray( - new String[enabledSuites.size()])); - engine.beginHandshake(); status = engine.getHandshakeStatus(); @@ -1179,8 +1171,9 @@ public class SSLEngineTest extends TestCase { SinkChannel serverSink = serverSendPipe.sink(); SourceChannel clientSource = serverSendPipe.source(); - clientEngine = new HandshakeHandler(true, clientSource, clientSink); - serverEngine = new HandshakeHandler(false, serverSource, serverSink); + TestSSLContext context = TestSSLContext.create(); + clientEngine = new HandshakeHandler(context.clientContext, true, clientSource, clientSink); + serverEngine = new HandshakeHandler(context.serverContext, false, serverSource, serverSink); } boolean doHandshake() throws InterruptedException { diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java index 26403f5..093e2e1 100644 --- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java +++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java @@ -39,6 +39,7 @@ import java.security.Principal; import java.security.Provider; import java.security.PublicKey; import java.security.Security; +import java.security.Signature; import java.security.SignatureException; import java.security.Provider.Service; import java.security.cert.CertificateFactory; @@ -763,16 +764,16 @@ public class X509CertificateTest extends TestCase { } Security.addProvider(myProvider); - Provider[] providers = Security.getProviders("Signature.MD5withRSA"); - if (providers == null || providers.length == 0) { - fail("no Provider for Signature.MD5withRSA"); - return; - } + // Find the Provider which offers MD5withRSA for the certificate's + // public key. + Signature signature = Signature.getInstance("MD5withRSA"); + signature.initVerify(javaxSSCert.getPublicKey()); + Provider provider = signature.getProvider(); // self signed cert: should verify with provider try { javaxSSCert.verify(javaxSSCert.getPublicKey(), - providers[0].getName()); + provider.getName()); } catch (SignatureException e) { fail("blu"); } diff --git a/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java b/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java index ba4cc66..9e83de2 100644 --- a/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java +++ b/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java @@ -8,14 +8,38 @@ package jsr166; -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.security.*; + +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import junit.framework.Test; +import junit.framework.TestSuite; public class AbstractExecutorServiceTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * A no-frills implementation of AbstractExecutorService, designed @@ -42,11 +66,10 @@ public class AbstractExecutorServiceTest extends JSR166TestCase { public void testExecuteRunnable() throws Exception { ExecutorService e = new DirectExecutorService(); final AtomicBoolean done = new AtomicBoolean(false); - CheckedRunnable task = new CheckedRunnable() { + Future<?> future = e.submit(new CheckedRunnable() { public void realRun() { done.set(true); - }}; - Future<?> future = e.submit(task); + }}); assertNull(future.get()); assertNull(future.get(0, MILLISECONDS)); assertTrue(done.get()); @@ -149,8 +172,8 @@ public class AbstractExecutorServiceTest extends JSR166TestCase { * execute(null runnable) throws NPE */ public void testExecuteNullRunnable() { + ExecutorService e = new DirectExecutorService(); try { - ExecutorService e = new DirectExecutorService(); e.submit((Runnable) null); shouldThrow(); } catch (NullPointerException success) {} @@ -160,8 +183,8 @@ public class AbstractExecutorServiceTest extends JSR166TestCase { * submit(null callable) throws NPE */ public void testSubmitNullCallable() { + ExecutorService e = new DirectExecutorService(); try { - ExecutorService e = new DirectExecutorService(); e.submit((Callable) null); shouldThrow(); } catch (NullPointerException success) {} diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java index e74fc3c..2aa7326 100644 --- a/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java @@ -8,13 +8,24 @@ package jsr166; -import junit.framework.*; import java.util.AbstractQueue; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AbstractQueueTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class Succeed extends AbstractQueue<Integer> { public boolean offer(Integer x) { @@ -110,8 +121,8 @@ public class AbstractQueueTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testAddAll1() { + Succeed q = new Succeed(); try { - Succeed q = new Succeed(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -121,8 +132,8 @@ public class AbstractQueueTest extends JSR166TestCase { * addAll(this) throws IAE */ public void testAddAllSelf() { + Succeed q = new Succeed(); try { - Succeed q = new Succeed(); q.addAll(q); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -132,9 +143,9 @@ public class AbstractQueueTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testAddAll2() { + Succeed q = new Succeed(); + Integer[] ints = new Integer[SIZE]; try { - Succeed q = new Succeed(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -145,11 +156,11 @@ public class AbstractQueueTest extends JSR166TestCase { * possibly adding some elements */ public void testAddAll3() { + Succeed q = new Succeed(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); try { - Succeed q = new Succeed(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -159,11 +170,11 @@ public class AbstractQueueTest extends JSR166TestCase { * addAll throws ISE if an add fails */ public void testAddAll4() { + Fail q = new Fail(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); try { - Fail q = new Fail(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(i); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (IllegalStateException success) {} diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java index d957e61..8604d86 100644 --- a/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java +++ b/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java @@ -8,13 +8,29 @@ package jsr166; -import junit.framework.*; -import java.util.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.concurrent.locks.AbstractQueuedLongSynchronizer; import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject; +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * A simple mutex class, adapted from the class javadoc. Exclusive @@ -83,7 +99,7 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { } public boolean tryReleaseShared(long ignore) { - setState(1 << 62); + setState(1L << 62); return true; } } @@ -191,7 +207,7 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { new HashSet<Thread>(Arrays.asList(threads))); } - enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }; + enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } /** * Awaits condition using the specified AwaitMethod. @@ -214,6 +230,8 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { case awaitUntil: assertTrue(c.awaitUntil(delayedDate(timeoutMillis))); break; + default: + throw new AssertionError(); } } @@ -1184,7 +1202,6 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { public void testTryAcquireSharedNanos_Timeout() { final BooleanLatch l = new BooleanLatch(); final BooleanLatch observedQueued = new BooleanLatch(); - final long timeoutMillis = timeoutMillis(); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { assertFalse(l.isSignalled()); @@ -1206,4 +1223,28 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { assertFalse(l.isSignalled()); } + /** + * awaitNanos/timed await with 0 wait times out immediately + */ + public void testAwait_Zero() throws InterruptedException { + final Mutex sync = new Mutex(); + final ConditionObject c = sync.newCondition(); + sync.acquire(); + assertTrue(c.awaitNanos(0L) <= 0); + assertFalse(c.await(0L, NANOSECONDS)); + sync.release(); + } + + /** + * awaitNanos/timed await with maximum negative wait times does not underflow + */ + public void testAwait_NegativeInfinity() throws InterruptedException { + final Mutex sync = new Mutex(); + final ConditionObject c = sync.newCondition(); + sync.acquire(); + assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0); + assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS)); + sync.release(); + } + } diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java index b9dab06..b3c4110 100644 --- a/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java +++ b/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java @@ -8,13 +8,29 @@ package jsr166; -import junit.framework.*; -import java.util.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject; +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AbstractQueuedSynchronizerTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * A simple mutex class, adapted from the class javadoc. Exclusive @@ -194,7 +210,7 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase { new HashSet<Thread>(Arrays.asList(threads))); } - enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }; + enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } /** * Awaits condition using the specified AwaitMethod. @@ -217,6 +233,8 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase { case awaitUntil: assertTrue(c.awaitUntil(delayedDate(timeoutMillis))); break; + default: + throw new AssertionError(); } } @@ -1187,7 +1205,6 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase { public void testTryAcquireSharedNanos_Timeout() { final BooleanLatch l = new BooleanLatch(); final BooleanLatch observedQueued = new BooleanLatch(); - final long timeoutMillis = timeoutMillis(); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { assertFalse(l.isSignalled()); @@ -1209,4 +1226,28 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase { assertFalse(l.isSignalled()); } + /** + * awaitNanos/timed await with 0 wait times out immediately + */ + public void testAwait_Zero() throws InterruptedException { + final Mutex sync = new Mutex(); + final ConditionObject c = sync.newCondition(); + sync.acquire(); + assertTrue(c.awaitNanos(0L) <= 0); + assertFalse(c.await(0L, NANOSECONDS)); + sync.release(); + } + + /** + * awaitNanos/timed await with maximum negative wait times does not underflow + */ + public void testAwait_NegativeInfinity() throws InterruptedException { + final Mutex sync = new Mutex(); + final ConditionObject c = sync.newCondition(); + sync.acquire(); + assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0); + assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS)); + sync.release(); + } + } diff --git a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNonFairTest.java index ddb1c5d..7bd920f 100644 --- a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java +++ b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNonFairTest.java @@ -11,7 +11,7 @@ package jsr166; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -public class ArrayBlockingQueueNotFairTest extends BlockingQueueTest { +public class ArrayBlockingQueueNonFairTest extends BlockingQueueTest { protected BlockingQueue emptyCollection() { return new ArrayBlockingQueue(SIZE, false); diff --git a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java index b999496..247c90e 100644 --- a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java @@ -8,9 +8,10 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; @@ -20,10 +21,36 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; public class ArrayBlockingQueueTest extends JSR166TestCase { + // android-note: These tests have been moved into their own separate + // classes to work around CTS issues. + // + // public static class Fair extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new ArrayBlockingQueue(SIZE, true); + // } + // } + // + // public static class NonFair extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new ArrayBlockingQueue(SIZE, false); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(ArrayBlockingQueueTest.class, + // new Fair().testSuite(), + // new NonFair().testSuite()); + // } + /** * Returns a new queue of given size containing consecutive * Integers 0 ... n. @@ -86,7 +113,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { ints[i] = i; Collection<Integer> elements = Arrays.asList(ints); try { - new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints)); + new ArrayBlockingQueue(SIZE, false, elements); shouldThrow(); } catch (NullPointerException success) {} } @@ -137,16 +164,16 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { * remainingCapacity decreases on add, increases on remove */ public void testRemainingCapacity() { - ArrayBlockingQueue q = populatedQueue(SIZE); + BlockingQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(i, q.remainingCapacity()); - assertEquals(SIZE-i, q.size()); - q.remove(); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertEquals(i, q.remove()); } for (int i = 0; i < SIZE; ++i) { assertEquals(SIZE-i, q.remainingCapacity()); - assertEquals(i, q.size()); - q.add(new Integer(i)); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertTrue(q.add(i)); } } @@ -163,12 +190,12 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { * add succeeds if not full; throws ISE if full */ public void testAdd() { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.add(new Integer(i))); + } + assertEquals(0, q.remainingCapacity()); try { - ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.add(new Integer(i))); - } - assertEquals(0, q.remainingCapacity()); q.add(new Integer(SIZE)); shouldThrow(); } catch (IllegalStateException success) {} @@ -178,8 +205,8 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { * addAll(this) throws IAE */ public void testAddAllSelf() { + ArrayBlockingQueue q = populatedQueue(SIZE); try { - ArrayBlockingQueue q = populatedQueue(SIZE); q.addAll(q); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -190,11 +217,11 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { * possibly adding some elements */ public void testAddAll3() { + ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); try { - ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -204,11 +231,11 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { * addAll throws ISE if not enough room */ public void testAddAll4() { + ArrayBlockingQueue q = new ArrayBlockingQueue(1); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); try { - ArrayBlockingQueue q = new ArrayBlockingQueue(1); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(i); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (IllegalStateException success) {} @@ -235,9 +262,9 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { public void testPut() throws InterruptedException { ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.put(I); - assertTrue(q.contains(I)); + Integer x = new Integer(i); + q.put(x); + assertTrue(q.contains(x)); } assertEquals(0, q.remainingCapacity()); } @@ -565,8 +592,8 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -676,9 +703,24 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { public void testIterator() throws InterruptedException { ArrayBlockingQueue q = populatedQueue(SIZE); Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) + assertTrue(q.contains(it.next())); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + + it = q.iterator(); + for (i = 0; it.hasNext(); i++) assertEquals(it.next(), q.take()); - } + assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new ArrayBlockingQueue(SIZE).iterator()); } /** @@ -872,8 +914,22 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { assertEquals(SIZE-k, q.size()); for (int j = 0; j < k; ++j) assertEquals(l.get(j), new Integer(j)); - while (q.poll() != null) ; + do {} while (q.poll() != null); } } + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?>[] qs = { + new ArrayBlockingQueue<Object>(10), + populatedQueue(2), + }; + + for (Collection<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } + } } diff --git a/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java b/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java index d18a560..16290e9 100644 --- a/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java +++ b/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java @@ -6,9 +6,8 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; import java.util.ArrayDeque; +import java.util.Arrays; import java.util.Collection; import java.util.Deque; import java.util.Iterator; @@ -16,7 +15,19 @@ import java.util.NoSuchElementException; import java.util.Queue; import java.util.Random; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ArrayDequeTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new deque of given size containing consecutive @@ -44,7 +55,7 @@ public class ArrayDequeTest extends JSR166TestCase { */ public void testConstructor3() { try { - ArrayDeque q = new ArrayDeque((Collection)null); + new ArrayDeque((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -55,7 +66,7 @@ public class ArrayDequeTest extends JSR166TestCase { public void testConstructor4() { try { Integer[] ints = new Integer[SIZE]; - ArrayDeque q = new ArrayDeque(Arrays.asList(ints)); + new ArrayDeque(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -68,7 +79,7 @@ public class ArrayDequeTest extends JSR166TestCase { Integer[] ints = new Integer[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new Integer(i); - ArrayDeque q = new ArrayDeque(Arrays.asList(ints)); + new ArrayDeque(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -386,13 +397,13 @@ public class ArrayDequeTest extends JSR166TestCase { */ public void testRemoveElement() { ArrayDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -525,10 +536,10 @@ public class ArrayDequeTest extends JSR166TestCase { */ public void testRemoveFirstOccurrence() { ArrayDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); assertFalse(q.removeFirstOccurrence(new Integer(i+1))); } @@ -540,10 +551,10 @@ public class ArrayDequeTest extends JSR166TestCase { */ public void testRemoveLastOccurrence() { ArrayDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); assertFalse(q.removeLastOccurrence(new Integer(i+1))); } @@ -735,13 +746,21 @@ public class ArrayDequeTest extends JSR166TestCase { */ public void testIterator() { ArrayDeque q = populatedDeque(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + Deque c = new ArrayDeque(); + assertIteratorExhausted(c.iterator()); + assertIteratorExhausted(c.descendingIterator()); } /** @@ -885,4 +904,21 @@ public class ArrayDequeTest extends JSR166TestCase { assertTrue(y.isEmpty()); } + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Deque<?>[] qs = { + new ArrayDeque<Object>(), + populatedDeque(2), + }; + + for (Deque<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + assertFalse(q.removeFirstOccurrence(null)); + assertFalse(q.removeLastOccurrence(null)); + } + } + } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java b/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java index 7a50120..bfe3fc6 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java @@ -8,10 +8,21 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicBoolean; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicBooleanTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor initializes to given value @@ -91,11 +102,11 @@ public class AtomicBooleanTest extends JSR166TestCase { */ public void testWeakCompareAndSet() { AtomicBoolean ai = new AtomicBoolean(true); - while (!ai.weakCompareAndSet(true, false)); + do {} while (!ai.weakCompareAndSet(true, false)); assertFalse(ai.get()); - while (!ai.weakCompareAndSet(false, false)); + do {} while (!ai.weakCompareAndSet(false, false)); assertFalse(ai.get()); - while (!ai.weakCompareAndSet(false, true)); + do {} while (!ai.weakCompareAndSet(false, true)); assertTrue(ai.get()); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java index e81a107..670b9ce 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java @@ -8,11 +8,22 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.concurrent.atomic.AtomicIntegerArray; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicIntegerArrayTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor creates array of given size with all elements zero @@ -29,7 +40,7 @@ public class AtomicIntegerArrayTest extends JSR166TestCase { public void testConstructor2NPE() { try { int[] a = null; - AtomicIntegerArray aa = new AtomicIntegerArray(a); + new AtomicIntegerArray(a); shouldThrow(); } catch (NullPointerException success) {} } @@ -157,10 +168,10 @@ public class AtomicIntegerArrayTest extends JSR166TestCase { AtomicIntegerArray aa = new AtomicIntegerArray(SIZE); for (int i = 0; i < SIZE; i++) { aa.set(i, 1); - while (!aa.weakCompareAndSet(i, 1, 2)); - while (!aa.weakCompareAndSet(i, 2, -4)); + do {} while (!aa.weakCompareAndSet(i, 1, 2)); + do {} while (!aa.weakCompareAndSet(i, 2, -4)); assertEquals(-4, aa.get(i)); - while (!aa.weakCompareAndSet(i, -4, 7)); + do {} while (!aa.weakCompareAndSet(i, -4, 7)); assertEquals(7, aa.get(i)); } } @@ -267,8 +278,6 @@ public class AtomicIntegerArrayTest extends JSR166TestCase { } } - static final int COUNTDOWN = 100000; - class Counter extends CheckedRunnable { final AtomicIntegerArray aa; volatile int counts; @@ -297,8 +306,9 @@ public class AtomicIntegerArrayTest extends JSR166TestCase { */ public void testCountingInMultipleThreads() throws InterruptedException { final AtomicIntegerArray aa = new AtomicIntegerArray(SIZE); + int countdown = 10000; for (int i = 0; i < SIZE; i++) - aa.set(i, COUNTDOWN); + aa.set(i, countdown); Counter c1 = new Counter(aa); Counter c2 = new Counter(aa); Thread t1 = new Thread(c1); @@ -307,7 +317,7 @@ public class AtomicIntegerArrayTest extends JSR166TestCase { t2.start(); t1.join(); t2.join(); - assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN); + assertEquals(c1.counts+c2.counts, SIZE * countdown); } /** diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java index f0c1ae6..ef75b46 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java @@ -8,13 +8,24 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase { volatile int x = 0; int w; long z; + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) { return AtomicIntegerFieldUpdater.newUpdater @@ -127,10 +138,10 @@ public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase { AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; a = updaterFor("x"); x = 1; - while (!a.weakCompareAndSet(this, 1, 2)); - while (!a.weakCompareAndSet(this, 2, -4)); + do {} while (!a.weakCompareAndSet(this, 1, 2)); + do {} while (!a.weakCompareAndSet(this, 2, -4)); assertEquals(-4, a.get(this)); - while (!a.weakCompareAndSet(this, -4, 7)); + do {} while (!a.weakCompareAndSet(this, -4, 7)); assertEquals(7, a.get(this)); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java index 2afaa73..cf73810 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java @@ -8,10 +8,21 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicInteger; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicIntegerTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } final int[] VALUES = { Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE, @@ -96,10 +107,10 @@ public class AtomicIntegerTest extends JSR166TestCase { */ public void testWeakCompareAndSet() { AtomicInteger ai = new AtomicInteger(1); - while (!ai.weakCompareAndSet(1, 2)); - while (!ai.weakCompareAndSet(2, -4)); + do {} while (!ai.weakCompareAndSet(1, 2)); + do {} while (!ai.weakCompareAndSet(2, -4)); assertEquals(-4, ai.get()); - while (!ai.weakCompareAndSet(-4, 7)); + do {} while (!ai.weakCompareAndSet(-4, 7)); assertEquals(7, ai.get()); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java index 53be5dc..08df01e 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java @@ -8,11 +8,22 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.concurrent.atomic.AtomicLongArray; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicLongArrayTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor creates array of given size with all elements zero @@ -29,7 +40,7 @@ public class AtomicLongArrayTest extends JSR166TestCase { public void testConstructor2NPE() { try { long[] a = null; - AtomicLongArray aa = new AtomicLongArray(a); + new AtomicLongArray(a); shouldThrow(); } catch (NullPointerException success) {} } @@ -157,10 +168,10 @@ public class AtomicLongArrayTest extends JSR166TestCase { AtomicLongArray aa = new AtomicLongArray(SIZE); for (int i = 0; i < SIZE; i++) { aa.set(i, 1); - while (!aa.weakCompareAndSet(i, 1, 2)); - while (!aa.weakCompareAndSet(i, 2, -4)); + do {} while (!aa.weakCompareAndSet(i, 1, 2)); + do {} while (!aa.weakCompareAndSet(i, 2, -4)); assertEquals(-4, aa.get(i)); - while (!aa.weakCompareAndSet(i, -4, 7)); + do {} while (!aa.weakCompareAndSet(i, -4, 7)); assertEquals(7, aa.get(i)); } } @@ -267,8 +278,6 @@ public class AtomicLongArrayTest extends JSR166TestCase { } } - static final long COUNTDOWN = 100000; - class Counter extends CheckedRunnable { final AtomicLongArray aa; volatile long counts; @@ -297,8 +306,9 @@ public class AtomicLongArrayTest extends JSR166TestCase { */ public void testCountingInMultipleThreads() throws InterruptedException { final AtomicLongArray aa = new AtomicLongArray(SIZE); + long countdown = 10000; for (int i = 0; i < SIZE; i++) - aa.set(i, COUNTDOWN); + aa.set(i, countdown); Counter c1 = new Counter(aa); Counter c2 = new Counter(aa); Thread t1 = new Thread(c1); @@ -307,7 +317,7 @@ public class AtomicLongArrayTest extends JSR166TestCase { t2.start(); t1.join(); t2.join(); - assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN); + assertEquals(c1.counts+c2.counts, SIZE * countdown); } /** diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java index c9374e0..204f814 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java @@ -8,14 +8,26 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicLongFieldUpdaterTest extends JSR166TestCase { volatile long x = 0; int z; long w; + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) { return AtomicLongFieldUpdater.newUpdater (AtomicLongFieldUpdaterTest.class, fieldName); @@ -127,10 +139,10 @@ public class AtomicLongFieldUpdaterTest extends JSR166TestCase { AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; a = updaterFor("x"); x = 1; - while (!a.weakCompareAndSet(this, 1, 2)); - while (!a.weakCompareAndSet(this, 2, -4)); + do {} while (!a.weakCompareAndSet(this, 1, 2)); + do {} while (!a.weakCompareAndSet(this, 2, -4)); assertEquals(-4, a.get(this)); - while (!a.weakCompareAndSet(this, -4, 7)); + do {} while (!a.weakCompareAndSet(this, -4, 7)); assertEquals(7, a.get(this)); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java index d300367..b9c1722 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java @@ -8,10 +8,21 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicLong; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicLongTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } final long[] VALUES = { Long.MIN_VALUE, @@ -98,10 +109,10 @@ public class AtomicLongTest extends JSR166TestCase { */ public void testWeakCompareAndSet() { AtomicLong ai = new AtomicLong(1); - while (!ai.weakCompareAndSet(1, 2)); - while (!ai.weakCompareAndSet(2, -4)); + do {} while (!ai.weakCompareAndSet(1, 2)); + do {} while (!ai.weakCompareAndSet(2, -4)); assertEquals(-4, ai.get()); - while (!ai.weakCompareAndSet(-4, 7)); + do {} while (!ai.weakCompareAndSet(-4, 7)); assertEquals(7, ai.get()); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java index fd1f2f1..61b6b1b 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java @@ -8,10 +8,21 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicMarkableReference; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicMarkableReferenceTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor initializes to given reference and mark @@ -135,11 +146,11 @@ public class AtomicMarkableReferenceTest extends JSR166TestCase { assertFalse(ai.isMarked()); assertFalse(mark[0]); - while (!ai.weakCompareAndSet(one, two, false, false)); + do {} while (!ai.weakCompareAndSet(one, two, false, false)); assertSame(two, ai.get(mark)); assertFalse(mark[0]); - while (!ai.weakCompareAndSet(two, m3, false, true)); + do {} while (!ai.weakCompareAndSet(two, m3, false, true)); assertSame(m3, ai.get(mark)); assertTrue(mark[0]); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java index 0a4f3d9..1df2f9f 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java @@ -8,11 +8,22 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.concurrent.atomic.AtomicReferenceArray; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicReferenceArrayTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor creates array of given size with all elements null @@ -30,7 +41,7 @@ public class AtomicReferenceArrayTest extends JSR166TestCase { public void testConstructor2NPE() { try { Integer[] a = null; - AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a); + new AtomicReferenceArray<Integer>(a); shouldThrow(); } catch (NullPointerException success) {} } @@ -165,10 +176,10 @@ public class AtomicReferenceArrayTest extends JSR166TestCase { AtomicReferenceArray aa = new AtomicReferenceArray(SIZE); for (int i = 0; i < SIZE; i++) { aa.set(i, one); - while (!aa.weakCompareAndSet(i, one, two)); - while (!aa.weakCompareAndSet(i, two, m4)); + do {} while (!aa.weakCompareAndSet(i, one, two)); + do {} while (!aa.weakCompareAndSet(i, two, m4)); assertSame(m4, aa.get(i)); - while (!aa.weakCompareAndSet(i, m4, seven)); + do {} while (!aa.weakCompareAndSet(i, m4, seven)); assertSame(seven, aa.get(i)); } } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java index 271c7b7..4b0d946 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java @@ -8,15 +8,27 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { volatile Integer x = null; Object z; Integer w; volatile int i; + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) { return AtomicReferenceFieldUpdater.newUpdater (AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName); @@ -68,7 +80,7 @@ public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { * get returns the last value set or assigned */ public void testGetSet() { - AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; a = updaterFor("x"); x = one; assertSame(one, a.get(this)); @@ -82,7 +94,7 @@ public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { * get returns the last value lazySet by same thread */ public void testGetLazySet() { - AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; a = updaterFor("x"); x = one; assertSame(one, a.get(this)); @@ -96,7 +108,7 @@ public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { * compareAndSet succeeds in changing value if equal to expected else fails */ public void testCompareAndSet() { - AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; a = updaterFor("x"); x = one; assertTrue(a.compareAndSet(this, one, two)); @@ -114,7 +126,7 @@ public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { */ public void testCompareAndSetInMultipleThreads() throws Exception { x = one; - final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; a = updaterFor("x"); Thread t = new Thread(new CheckedRunnable() { @@ -135,13 +147,13 @@ public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { * to expected */ public void testWeakCompareAndSet() { - AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; a = updaterFor("x"); x = one; - while (!a.weakCompareAndSet(this, one, two)); - while (!a.weakCompareAndSet(this, two, m4)); + do {} while (!a.weakCompareAndSet(this, one, two)); + do {} while (!a.weakCompareAndSet(this, two, m4)); assertSame(m4, a.get(this)); - while (!a.weakCompareAndSet(this, m4, seven)); + do {} while (!a.weakCompareAndSet(this, m4, seven)); assertSame(seven, a.get(this)); } @@ -149,7 +161,7 @@ public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase { * getAndSet returns previous value and sets to given value */ public void testGetAndSet() { - AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a; + AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; a = updaterFor("x"); x = one; assertSame(one, a.getAndSet(this, zero)); diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java index 8032546..457182f 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java @@ -8,10 +8,21 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicReference; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicReferenceTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor initializes to given value @@ -92,10 +103,10 @@ public class AtomicReferenceTest extends JSR166TestCase { */ public void testWeakCompareAndSet() { AtomicReference ai = new AtomicReference(one); - while (!ai.weakCompareAndSet(one, two)); - while (!ai.weakCompareAndSet(two, m4)); + do {} while (!ai.weakCompareAndSet(one, two)); + do {} while (!ai.weakCompareAndSet(two, m4)); assertSame(m4, ai.get()); - while (!ai.weakCompareAndSet(m4, seven)); + do {} while (!ai.weakCompareAndSet(m4, seven)); assertSame(seven, ai.get()); } diff --git a/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java index 3e6445e..b3ff06a 100644 --- a/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java +++ b/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java @@ -8,10 +8,21 @@ package jsr166; -import junit.framework.*; import java.util.concurrent.atomic.AtomicStampedReference; +import junit.framework.Test; +import junit.framework.TestSuite; + public class AtomicStampedReferenceTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * constructor initializes to given reference and stamp @@ -135,11 +146,11 @@ public class AtomicStampedReferenceTest extends JSR166TestCase { assertEquals(0, ai.getStamp()); assertEquals(0, mark[0]); - while (!ai.weakCompareAndSet(one, two, 0, 0)); + do {} while (!ai.weakCompareAndSet(one, two, 0, 0)); assertSame(two, ai.get(mark)); assertEquals(0, mark[0]); - while (!ai.weakCompareAndSet(two, m3, 0, 1)); + do {} while (!ai.weakCompareAndSet(two, m3, 0, 1)); assertSame(m3, ai.get(mark)); assertEquals(1, mark[0]); } diff --git a/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java index 1ed7559..db0f03d 100644 --- a/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java @@ -9,14 +9,17 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Queue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; +import junit.framework.TestSuite; /** * Contains "contract" tests applicable to all BlockingQueue implementations. @@ -32,6 +35,15 @@ public abstract class BlockingQueueTest extends JSR166TestCase { * instances. */ + /** Like suite(), but non-static */ + // android-note: Explicitly instantiated. + // + // public Test testSuite() { + // // TODO: filter the returned tests using the configuration + // // information provided by the subclass via protected methods. + // return new TestSuite(this.getClass()); + // } + //---------------------------------------------------------------- // Configuration methods //---------------------------------------------------------------- @@ -335,7 +347,7 @@ public abstract class BlockingQueueTest extends JSR166TestCase { checkEmpty(q); for (int i = 0; i < size; i++) q.add(elts[i] = makeElement(i)); - for (int i = 1; i < size; i+=2) { + for (int i = 1; i < size; i += 2) { for (int pass = 0; pass < 2; pass++) { assertEquals((pass == 0), q.contains(elts[i])); assertEquals((pass == 0), q.remove(elts[i])); @@ -347,7 +359,7 @@ public abstract class BlockingQueueTest extends JSR166TestCase { } if (size > 0) assertTrue(q.contains(elts[0])); - for (int i = size-2; i >= 0; i-=2) { + for (int i = size-2; i >= 0; i -= 2) { assertTrue(q.contains(elts[i])); assertFalse(q.contains(elts[i+1])); assertTrue(q.remove(elts[i])); diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java index 5d9e2ac..4650f41 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java @@ -8,17 +8,36 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ConcurrentHashMapTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new map from Integers 1-5 to Strings "A"-"E". */ - private static ConcurrentHashMap map5() { - ConcurrentHashMap map = new ConcurrentHashMap(5); + private static ConcurrentHashMap<Integer, String> map5() { + ConcurrentHashMap map = new ConcurrentHashMap<Integer, String>(5); assertTrue(map.isEmpty()); map.put(one, "A"); map.put(two, "B"); @@ -30,12 +49,15 @@ public class ConcurrentHashMapTest extends JSR166TestCase { return map; } + /** Re-implement Integer.compare for old java versions */ + static int compare(int x, int y) { return x < y ? -1 : x > y ? 1 : 0; } + // classes for testing Comparable fallbacks static class BI implements Comparable<BI> { private final int value; BI(int value) { this.value = value; } public int compareTo(BI other) { - return Integer.compare(value, other.value); + return compare(value, other.value); } public boolean equals(Object x) { return (x instanceof BI) && ((BI)x).value == value; @@ -59,12 +81,9 @@ public class ConcurrentHashMapTest extends JSR166TestCase { static class LexicographicList<E extends Comparable<E>> extends ArrayList<E> implements Comparable<LexicographicList<E>> { - static long total; - static long n; LexicographicList(Collection<E> c) { super(c); } LexicographicList(E e) { super(Collections.singleton(e)); } public int compareTo(LexicographicList<E> other) { - long start = System.currentTimeMillis(); int common = Math.min(size(), other.size()); int r = 0; for (int i = 0; i < common; i++) { @@ -72,25 +91,40 @@ public class ConcurrentHashMapTest extends JSR166TestCase { break; } if (r == 0) - r = Integer.compare(size(), other.size()); - total += System.currentTimeMillis() - start; - n++; + r = compare(size(), other.size()); return r; } private static final long serialVersionUID = 0; } + static class CollidingObject { + final String value; + CollidingObject(final String value) { this.value = value; } + public int hashCode() { return this.value.hashCode() & 1; } + public boolean equals(final Object obj) { + return (obj instanceof CollidingObject) && ((CollidingObject)obj).value.equals(value); + } + } + + static class ComparableCollidingObject extends CollidingObject implements Comparable<ComparableCollidingObject> { + ComparableCollidingObject(final String value) { super(value); } + public int compareTo(final ComparableCollidingObject o) { + return value.compareTo(o.value); + } + } + /** * Inserted elements that are subclasses of the same Comparable * class are found. */ public void testComparableFamily() { + int size = 500; // makes measured test run time -> 60ms ConcurrentHashMap<BI, Boolean> m = new ConcurrentHashMap<BI, Boolean>(); - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < size; i++) { assertTrue(m.put(new CI(i), true) == null); } - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < size; i++) { assertTrue(m.containsKey(new CI(i))); assertTrue(m.containsKey(new DI(i))); } @@ -100,24 +134,25 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * Elements of classes with erased generic type parameters based * on Comparable can be inserted and found. */ - public void testGenericComparable() { - ConcurrentHashMap<Object, Boolean> m = - new ConcurrentHashMap<Object, Boolean>(); - for (int i = 0; i < 1000; i++) { - BI bi = new BI(i); - BS bs = new BS(String.valueOf(i)); - LexicographicList<BI> bis = new LexicographicList<BI>(bi); - LexicographicList<BS> bss = new LexicographicList<BS>(bs); - assertTrue(m.putIfAbsent(bis, true) == null); - assertTrue(m.containsKey(bis)); - if (m.putIfAbsent(bss, true) == null) - assertTrue(m.containsKey(bss)); - assertTrue(m.containsKey(bis)); - } - for (int i = 0; i < 1000; i++) { - assertTrue(m.containsKey(new ArrayList(Collections.singleton(new BI(i))))); - } - } + public void testGenericComparable() { + int size = 120; // makes measured test run time -> 60ms + ConcurrentHashMap<Object, Boolean> m = + new ConcurrentHashMap<Object, Boolean>(); + for (int i = 0; i < size; i++) { + BI bi = new BI(i); + BS bs = new BS(String.valueOf(i)); + LexicographicList<BI> bis = new LexicographicList<BI>(bi); + LexicographicList<BS> bss = new LexicographicList<BS>(bs); + assertTrue(m.putIfAbsent(bis, true) == null); + assertTrue(m.containsKey(bis)); + if (m.putIfAbsent(bss, true) == null) + assertTrue(m.containsKey(bss)); + assertTrue(m.containsKey(bis)); + } + for (int i = 0; i < size; i++) { + assertTrue(m.containsKey(Collections.singletonList(new BI(i)))); + } + } /** * Elements of non-comparable classes equal to those of classes @@ -125,19 +160,55 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * inserted and found. */ public void testGenericComparable2() { + int size = 500; // makes measured test run time -> 60ms ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<Object, Boolean>(); - for (int i = 0; i < 1000; i++) { - m.put(new ArrayList(Collections.singleton(new BI(i))), true); + for (int i = 0; i < size; i++) { + m.put(Collections.singletonList(new BI(i)), true); } - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < size; i++) { LexicographicList<BI> bis = new LexicographicList<BI>(new BI(i)); assertTrue(m.containsKey(bis)); } } /** + * Mixtures of instances of comparable and non-comparable classes + * can be inserted and found. + */ + public void testMixedComparable() { + int size = 1200; // makes measured test run time -> 35ms + ConcurrentHashMap<Object, Object> map = + new ConcurrentHashMap<Object, Object>(); + Random rng = new Random(); + for (int i = 0; i < size; i++) { + Object x; + switch (rng.nextInt(4)) { + case 0: + x = new Object(); + break; + case 1: + x = new CollidingObject(Integer.toString(i)); + break; + default: + x = new ComparableCollidingObject(Integer.toString(i)); + } + assertNull(map.put(x, x)); + } + int count = 0; + for (Object k : map.keySet()) { + assertEquals(map.get(k), k); + ++count; + } + assertEquals(count, size); + assertEquals(map.size(), size); + for (Object k : map.keySet()) { + assertEquals(map.put(k, k), k); + } + } + + /** * clear removes all pairs */ public void testClear() { @@ -160,6 +231,17 @@ public class ConcurrentHashMapTest extends JSR166TestCase { } /** + * hashCode() equals sum of each key.hashCode ^ value.hashCode + */ + public void testHashCode() { + ConcurrentHashMap<Integer,String> map = map5(); + int sum = 0; + for (Map.Entry<Integer,String> e : map.entrySet()) + sum += e.getKey().hashCode() ^ e.getValue().hashCode(); + assertEquals(sum, map.hashCode()); + } + + /** * contains returns true for contained value */ public void testContains() { @@ -210,6 +292,7 @@ public class ConcurrentHashMapTest extends JSR166TestCase { assertEquals("A", (String)map.get(one)); ConcurrentHashMap empty = new ConcurrentHashMap(); assertNull(map.get("anything")); + assertNull(empty.get("anything")); } /** @@ -443,41 +526,81 @@ public class ConcurrentHashMapTest extends JSR166TestCase { // Exception tests /** - * Cannot create with negative capacity + * Cannot create with only negative capacity */ public void testConstructor1() { try { - new ConcurrentHashMap(-1,0,1); + new ConcurrentHashMap(-1); shouldThrow(); } catch (IllegalArgumentException success) {} } /** - * Cannot create with negative concurrency level - */ + * Constructor (initialCapacity, loadFactor) throws + * IllegalArgumentException if either argument is negative + */ public void testConstructor2() { try { - new ConcurrentHashMap(1,0,-1); + new ConcurrentHashMap(-1, .75f); + shouldThrow(); + } catch (IllegalArgumentException success) {} + + try { + new ConcurrentHashMap(16, -1); shouldThrow(); } catch (IllegalArgumentException success) {} } /** - * Cannot create with only negative capacity + * Constructor (initialCapacity, loadFactor, concurrencyLevel) + * throws IllegalArgumentException if any argument is negative */ public void testConstructor3() { try { - new ConcurrentHashMap(-1); + new ConcurrentHashMap(-1, .75f, 1); + shouldThrow(); + } catch (IllegalArgumentException success) {} + + try { + new ConcurrentHashMap(16, -1, 1); + shouldThrow(); + } catch (IllegalArgumentException success) {} + + try { + new ConcurrentHashMap(16, .75f, -1); shouldThrow(); } catch (IllegalArgumentException success) {} } /** + * ConcurrentHashMap(map) throws NullPointerException if the given + * map is null + */ + public void testConstructor4() { + try { + new ConcurrentHashMap(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * ConcurrentHashMap(map) creates a new map with the same mappings + * as the given map + */ + public void testConstructor5() { + ConcurrentHashMap map1 = map5(); + ConcurrentHashMap map2 = new ConcurrentHashMap(map5()); + assertTrue(map2.equals(map1)); + map2.put(one, "F"); + assertFalse(map2.equals(map1)); + } + + /** * get(null) throws NPE */ public void testGet_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.get(null); shouldThrow(); } catch (NullPointerException success) {} @@ -487,8 +610,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * containsKey(null) throws NPE */ public void testContainsKey_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.containsKey(null); shouldThrow(); } catch (NullPointerException success) {} @@ -498,8 +621,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * containsValue(null) throws NPE */ public void testContainsValue_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.containsValue(null); shouldThrow(); } catch (NullPointerException success) {} @@ -509,8 +632,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * contains(null) throws NPE */ public void testContains_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.contains(null); shouldThrow(); } catch (NullPointerException success) {} @@ -520,8 +643,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * put(null,x) throws NPE */ public void testPut1_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.put(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -531,8 +654,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * put(x, null) throws NPE */ public void testPut2_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.put("whatever", null); shouldThrow(); } catch (NullPointerException success) {} @@ -542,8 +665,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * putIfAbsent(null, x) throws NPE */ public void testPutIfAbsent1_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.putIfAbsent(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -553,8 +676,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * replace(null, x) throws NPE */ public void testReplace_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.replace(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -564,8 +687,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * replace(null, x, y) throws NPE */ public void testReplaceValue_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.replace(null, one, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -575,8 +698,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * putIfAbsent(x, null) throws NPE */ public void testPutIfAbsent2_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.putIfAbsent("whatever", null); shouldThrow(); } catch (NullPointerException success) {} @@ -586,8 +709,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * replace(x, null) throws NPE */ public void testReplace2_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.replace("whatever", null); shouldThrow(); } catch (NullPointerException success) {} @@ -597,8 +720,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * replace(x, null, y) throws NPE */ public void testReplaceValue2_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.replace("whatever", null, "A"); shouldThrow(); } catch (NullPointerException success) {} @@ -608,8 +731,8 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * replace(x, y, null) throws NPE */ public void testReplaceValue3_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); c.replace("whatever", one, null); shouldThrow(); } catch (NullPointerException success) {} @@ -619,9 +742,9 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * remove(null) throws NPE */ public void testRemove1_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.put("sadsdf", "asdads"); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); - c.put("sadsdf", "asdads"); c.remove(null); shouldThrow(); } catch (NullPointerException success) {} @@ -631,9 +754,9 @@ public class ConcurrentHashMapTest extends JSR166TestCase { * remove(null, x) throws NPE */ public void testRemove2_NullPointerException() { + ConcurrentHashMap c = new ConcurrentHashMap(5); + c.put("sadsdf", "asdads"); try { - ConcurrentHashMap c = new ConcurrentHashMap(5); - c.put("sadsdf", "asdads"); c.remove(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java index f5b8318..c445957 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java @@ -8,17 +8,30 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.Collection; +import java.util.Deque; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; import java.util.Random; import java.util.concurrent.ConcurrentLinkedDeque; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ConcurrentLinkedDequeTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + /** * Returns a new deque of given size containing consecutive * Integers 0 ... n. @@ -46,7 +59,7 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { */ public void testConstructor3() { try { - ConcurrentLinkedDeque q = new ConcurrentLinkedDeque((Collection)null); + new ConcurrentLinkedDeque((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -57,7 +70,7 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { public void testConstructor4() { try { Integer[] ints = new Integer[SIZE]; - ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints)); + new ConcurrentLinkedDeque(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -70,7 +83,7 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { Integer[] ints = new Integer[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new Integer(i); - ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints)); + new ConcurrentLinkedDeque(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -428,13 +441,13 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { */ public void testRemoveElement() { ConcurrentLinkedDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -538,10 +551,10 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { */ public void testRemoveFirstOccurrence() { ConcurrentLinkedDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); assertFalse(q.removeFirstOccurrence(new Integer(i+1))); } @@ -553,10 +566,10 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { */ public void testRemoveLastOccurrence() { ConcurrentLinkedDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); assertFalse(q.removeLastOccurrence(new Integer(i+1))); } @@ -632,8 +645,8 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -687,13 +700,21 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { */ public void testIterator() { ConcurrentLinkedDeque q = populatedDeque(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + Deque c = new ConcurrentLinkedDeque(); + assertIteratorExhausted(c.iterator()); + assertIteratorExhausted(c.descendingIterator()); } /** @@ -855,4 +876,30 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { assertTrue(y.isEmpty()); } + /** + * contains(null) always return false. + * remove(null) always throws NullPointerException. + */ + public void testNeverContainsNull() { + Deque<?>[] qs = { + new ConcurrentLinkedDeque<Object>(), + populatedDeque(2), + }; + + for (Deque<?> q : qs) { + assertFalse(q.contains(null)); + try { + assertFalse(q.remove(null)); + shouldThrow(); + } catch (NullPointerException success) {} + try { + assertFalse(q.removeFirstOccurrence(null)); + shouldThrow(); + } catch (NullPointerException success) {} + try { + assertFalse(q.removeLastOccurrence(null)); + shouldThrow(); + } catch (NullPointerException success) {} + } + } } diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java index 7924034..d3f5b1f 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java @@ -8,7 +8,6 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -16,8 +15,21 @@ import java.util.NoSuchElementException; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ConcurrentLinkedQueueTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + /** * Returns a new queue of given size containing consecutive * Integers 0 ... n. @@ -44,7 +56,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { */ public void testConstructor3() { try { - ConcurrentLinkedQueue q = new ConcurrentLinkedQueue((Collection)null); + new ConcurrentLinkedQueue((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -55,7 +67,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { public void testConstructor4() { try { Integer[] ints = new Integer[SIZE]; - ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints)); + new ConcurrentLinkedQueue(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -68,7 +80,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { Integer[] ints = new Integer[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new Integer(i); - ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints)); + new ConcurrentLinkedQueue(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -279,13 +291,13 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { */ public void testRemoveElement() { ConcurrentLinkedQueue q = populatedQueue(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -364,8 +376,8 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -419,13 +431,19 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { */ public void testIterator() { ConcurrentLinkedQueue q = populatedQueue(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new ConcurrentLinkedQueue().iterator()); } /** @@ -508,4 +526,18 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { assertTrue(y.isEmpty()); } + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?>[] qs = { + new ConcurrentLinkedQueue<Object>(), + populatedQueue(2), + }; + + for (Collection<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } + } } diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java index 4359287..0aadd23 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java @@ -6,11 +6,32 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; import java.util.concurrent.ConcurrentSkipListMap; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ConcurrentSkipListMapTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new map from Integers 1-5 to Strings "A"-"E". @@ -678,8 +699,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * get(null) of nonempty map throws NPE */ public void testGet_NullPointerException() { + ConcurrentSkipListMap c = map5(); try { - ConcurrentSkipListMap c = map5(); c.get(null); shouldThrow(); } catch (NullPointerException success) {} @@ -689,8 +710,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * containsKey(null) of nonempty map throws NPE */ public void testContainsKey_NullPointerException() { + ConcurrentSkipListMap c = map5(); try { - ConcurrentSkipListMap c = map5(); c.containsKey(null); shouldThrow(); } catch (NullPointerException success) {} @@ -700,8 +721,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * containsValue(null) throws NPE */ public void testContainsValue_NullPointerException() { + ConcurrentSkipListMap c = new ConcurrentSkipListMap(); try { - ConcurrentSkipListMap c = new ConcurrentSkipListMap(); c.containsValue(null); shouldThrow(); } catch (NullPointerException success) {} @@ -711,8 +732,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * put(null,x) throws NPE */ public void testPut1_NullPointerException() { + ConcurrentSkipListMap c = map5(); try { - ConcurrentSkipListMap c = map5(); c.put(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -722,8 +743,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * putIfAbsent(null, x) throws NPE */ public void testPutIfAbsent1_NullPointerException() { + ConcurrentSkipListMap c = map5(); try { - ConcurrentSkipListMap c = map5(); c.putIfAbsent(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -733,8 +754,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * replace(null, x) throws NPE */ public void testReplace_NullPointerException() { + ConcurrentSkipListMap c = map5(); try { - ConcurrentSkipListMap c = map5(); c.replace(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -744,8 +765,8 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * replace(null, x, y) throws NPE */ public void testReplaceValue_NullPointerException() { + ConcurrentSkipListMap c = map5(); try { - ConcurrentSkipListMap c = map5(); c.replace(null, one, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -755,9 +776,9 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * remove(null) throws NPE */ public void testRemove1_NullPointerException() { + ConcurrentSkipListMap c = new ConcurrentSkipListMap(); + c.put("sadsdf", "asdads"); try { - ConcurrentSkipListMap c = new ConcurrentSkipListMap(); - c.put("sadsdf", "asdads"); c.remove(null); shouldThrow(); } catch (NullPointerException success) {} @@ -767,9 +788,9 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { * remove(null, x) throws NPE */ public void testRemove2_NullPointerException() { + ConcurrentSkipListMap c = new ConcurrentSkipListMap(); + c.put("sadsdf", "asdads"); try { - ConcurrentSkipListMap c = new ConcurrentSkipListMap(); - c.put("sadsdf", "asdads"); c.remove(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -1014,7 +1035,7 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { // Add entries till we're back to original size while (map.size() < size) { int key = min + rnd.nextInt(rangeSize); - assertTrue(key >= min && key<= max); + assertTrue(key >= min && key <= max); put(map, key); } } @@ -1039,7 +1060,7 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase { // Add entries till we're back to original size while (map.size() < size) { int key = min - 5 + rnd.nextInt(rangeSize + 10); - if (key >= min && key<= max) { + if (key >= min && key <= max) { put(map, key); } else { try { diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java index 1fd3c5f..41f8835 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java @@ -6,7 +6,6 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; @@ -19,7 +18,19 @@ import java.util.Set; import java.util.SortedSet; import java.util.concurrent.ConcurrentSkipListSet; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ConcurrentSkipListSetTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class MyReverseComparator implements Comparator { public int compare(Object x, Object y) { @@ -35,9 +46,9 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { ConcurrentSkipListSet<Integer> q = new ConcurrentSkipListSet<Integer>(); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.add(new Integer(i))); assertFalse(q.isEmpty()); assertEquals(n, q.size()); @@ -71,7 +82,7 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { */ public void testConstructor3() { try { - ConcurrentSkipListSet q = new ConcurrentSkipListSet((Collection)null); + new ConcurrentSkipListSet((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -82,7 +93,7 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { public void testConstructor4() { try { Integer[] ints = new Integer[SIZE]; - ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints)); + new ConcurrentSkipListSet(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -95,7 +106,7 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { Integer[] ints = new Integer[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new Integer(i); - ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints)); + new ConcurrentSkipListSet(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -160,8 +171,8 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { * add(null) throws NPE */ public void testAddNull() { + ConcurrentSkipListSet q = new ConcurrentSkipListSet(); try { - ConcurrentSkipListSet q = new ConcurrentSkipListSet(); q.add(null); shouldThrow(); } catch (NullPointerException success) {} @@ -189,9 +200,8 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { * Add of non-Comparable throws CCE */ public void testAddNonComparable() { + ConcurrentSkipListSet q = new ConcurrentSkipListSet(); try { - ConcurrentSkipListSet q = new ConcurrentSkipListSet(); - q.add(new Object()); q.add(new Object()); q.add(new Object()); shouldThrow(); @@ -202,8 +212,8 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testAddAll1() { + ConcurrentSkipListSet q = new ConcurrentSkipListSet(); try { - ConcurrentSkipListSet q = new ConcurrentSkipListSet(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -213,9 +223,9 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testAddAll2() { + ConcurrentSkipListSet q = new ConcurrentSkipListSet(); + Integer[] ints = new Integer[SIZE]; try { - ConcurrentSkipListSet q = new ConcurrentSkipListSet(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -226,11 +236,11 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { * possibly adding some elements */ public void testAddAll3() { + ConcurrentSkipListSet q = new ConcurrentSkipListSet(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); try { - ConcurrentSkipListSet q = new ConcurrentSkipListSet(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -278,13 +288,13 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { */ public void testRemoveElement() { ConcurrentSkipListSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -363,8 +373,8 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.pollFirst()); + assertFalse(q.contains(x)); } } } @@ -467,27 +477,21 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { */ public void testIterator() { ConcurrentSkipListSet q = populatedSet(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); } /** * iterator of empty set has no elements */ public void testEmptyIterator() { - ConcurrentSkipListSet q = new ConcurrentSkipListSet(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); + NavigableSet s = new ConcurrentSkipListSet(); + assertIteratorExhausted(s.iterator()); + assertIteratorExhausted(s.descendingSet().iterator()); } /** @@ -726,7 +730,7 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { // Add entries till we're back to original size while (set.size() < size) { int element = min + rnd.nextInt(rangeSize); - assertTrue(element >= min && element<= max); + assertTrue(element >= min && element <= max); put(set, element, bs); } } @@ -752,7 +756,7 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { // Add entries till we're back to original size while (set.size() < size) { int element = min - 5 + rnd.nextInt(rangeSize + 10); - if (element >= min && element<= max) { + if (element >= min && element <= max) { put(set, element, bs); } else { try { diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java index 7247657..5315bcb 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java @@ -6,12 +6,30 @@ package jsr166; -import junit.framework.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.Set; +import java.util.SortedMap; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; -import java.util.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ConcurrentSkipListSubMapTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new map from Integers 1-5 to Strings "A"-"E". diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java index 43c1759..f1c4aae 100644 --- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java +++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java @@ -6,20 +6,26 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.NavigableSet; -import java.util.NoSuchElementException; -import java.util.Random; -import java.util.Set; import java.util.SortedSet; import java.util.concurrent.ConcurrentSkipListSet; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ConcurrentSkipListSubSetTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class MyReverseComparator implements Comparator { public int compare(Object x, Object y) { @@ -36,9 +42,9 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { new ConcurrentSkipListSet<Integer>(); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.add(new Integer(i))); assertTrue(q.add(new Integer(-n))); assertTrue(q.add(new Integer(n))); @@ -134,8 +140,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * add(null) throws NPE */ public void testAddNull() { + NavigableSet q = set0(); try { - NavigableSet q = set0(); q.add(null); shouldThrow(); } catch (NullPointerException success) {} @@ -162,9 +168,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * Add of non-Comparable throws CCE */ public void testAddNonComparable() { + NavigableSet q = set0(); try { - NavigableSet q = set0(); - q.add(new Object()); q.add(new Object()); q.add(new Object()); shouldThrow(); @@ -175,8 +180,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testAddAll1() { + NavigableSet q = set0(); try { - NavigableSet q = set0(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -186,9 +191,9 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testAddAll2() { + NavigableSet q = set0(); + Integer[] ints = new Integer[SIZE]; try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -199,11 +204,11 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * possibly adding some elements */ public void testAddAll3() { + NavigableSet q = set0(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i+SIZE); try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -240,13 +245,13 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { */ public void testRemoveElement() { NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -325,8 +330,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.pollFirst()); + assertFalse(q.contains(x)); } } } @@ -430,27 +435,19 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { */ public void testIterator() { NavigableSet q = populatedSet(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); } /** * iterator of empty set has no elements */ public void testEmptyIterator() { - NavigableSet q = set0(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); + assertIteratorExhausted(set0().iterator()); } /** @@ -639,8 +636,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * add(null) throws NPE */ public void testDescendingAddNull() { + NavigableSet q = dset0(); try { - NavigableSet q = dset0(); q.add(null); shouldThrow(); } catch (NullPointerException success) {} @@ -667,9 +664,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * Add of non-Comparable throws CCE */ public void testDescendingAddNonComparable() { + NavigableSet q = dset0(); try { - NavigableSet q = dset0(); - q.add(new Object()); q.add(new Object()); q.add(new Object()); shouldThrow(); @@ -680,8 +676,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testDescendingAddAll1() { + NavigableSet q = dset0(); try { - NavigableSet q = dset0(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -691,9 +687,9 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testDescendingAddAll2() { + NavigableSet q = dset0(); + Integer[] ints = new Integer[SIZE]; try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -704,11 +700,11 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { * possibly adding some elements */ public void testDescendingAddAll3() { + NavigableSet q = dset0(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i+SIZE); try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -745,10 +741,10 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { */ public void testDescendingRemoveElement() { NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.remove(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2 ) { assertTrue(q.remove(new Integer(i))); assertFalse(q.remove(new Integer(i+1))); } @@ -824,8 +820,8 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.pollFirst()); + assertFalse(q.contains(x)); } } } diff --git a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java index 6bef8be..658268a 100644 --- a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java +++ b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java @@ -8,7 +8,6 @@ package jsr166; -import junit.framework.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -18,11 +17,23 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; -import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; +import junit.framework.Test; +import junit.framework.TestSuite; + public class CopyOnWriteArrayListTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + static CopyOnWriteArrayList<Integer> populatedArray(int n) { CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>(); assertTrue(a.isEmpty()); @@ -76,16 +87,14 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { } /** - * addAll adds each element from the given collection + * addAll adds each element from the given collection, including duplicates */ public void testAddAll() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(three); - v.add(four); - v.add(five); - full.addAll(v); + assertTrue(full.addAll(Arrays.asList(three, four, five))); assertEquals(6, full.size()); + assertTrue(full.addAll(Arrays.asList(three, four, five))); + assertEquals(9, full.size()); } /** @@ -94,11 +103,10 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { */ public void testAddAllAbsent() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(three); - v.add(four); - v.add(one); // will not add this element - full.addAllAbsent(v); + // "one" is duplicate and will not be added + assertEquals(2, full.addAllAbsent(Arrays.asList(three, four, one))); + assertEquals(5, full.size()); + assertEquals(0, full.addAllAbsent(Arrays.asList(three, four, one))); assertEquals(5, full.size()); } @@ -188,12 +196,11 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { */ public void testContainsAll() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(one); - v.add(two); - assertTrue(full.containsAll(v)); - v.add(six); - assertFalse(full.containsAll(v)); + assertTrue(full.containsAll(Arrays.asList())); + assertTrue(full.containsAll(Arrays.asList(one))); + assertTrue(full.containsAll(Arrays.asList(one, two))); + assertFalse(full.containsAll(Arrays.asList(one, two, six))); + assertFalse(full.containsAll(Arrays.asList(six))); } /** @@ -256,11 +263,15 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { assertTrue(it.hasNext()); assertEquals(elements[j], it.next()); } - assertFalse(it.hasNext()); - try { - it.next(); - shouldThrow(); - } catch (NoSuchElementException success) {} + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + Collection c = new CopyOnWriteArrayList(); + assertIteratorExhausted(c.iterator()); } /** @@ -375,10 +386,9 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { */ public void testRemoveAll() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(one); - v.add(two); - full.removeAll(v); + assertTrue(full.removeAll(Arrays.asList(one, two))); + assertEquals(1, full.size()); + assertFalse(full.removeAll(Arrays.asList(one, two))); assertEquals(1, full.size()); } @@ -494,10 +504,10 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { * can not store the objects inside the list */ public void testToArray_ArrayStoreException() { + CopyOnWriteArrayList c = new CopyOnWriteArrayList(); + c.add("zfasdfsdf"); + c.add("asdadasd"); try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("zfasdfsdf"); - c.add("asdadasd"); c.toArray(new Long[5]); shouldThrow(); } catch (ArrayStoreException success) {} @@ -507,167 +517,196 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { * get throws an IndexOutOfBoundsException on a negative index */ public void testGet1_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.get(-1); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.get(-1); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * get throws an IndexOutOfBoundsException on a too high index */ public void testGet2_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("asdasd"); - c.add("asdad"); - c.get(100); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.get(list.size()); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * set throws an IndexOutOfBoundsException on a negative index */ public void testSet1_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.set(-1,"qwerty"); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.set(-1, "qwerty"); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * set throws an IndexOutOfBoundsException on a too high index */ public void testSet2() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("asdasd"); - c.add("asdad"); - c.set(100, "qwerty"); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.set(list.size(), "qwerty"); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * add throws an IndexOutOfBoundsException on a negative index */ public void testAdd1_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add(-1,"qwerty"); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.add(-1, "qwerty"); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * add throws an IndexOutOfBoundsException on a too high index */ public void testAdd2_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("asdasd"); - c.add("asdasdasd"); - c.add(100, "qwerty"); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.add(list.size() + 1, "qwerty"); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * remove throws an IndexOutOfBoundsException on a negative index */ public void testRemove1_IndexOutOfBounds() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.remove(-1); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.remove(-1); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * remove throws an IndexOutOfBoundsException on a too high index */ public void testRemove2_IndexOutOfBounds() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("asdasd"); - c.add("adasdasd"); - c.remove(100); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.remove(list.size()); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * addAll throws an IndexOutOfBoundsException on a negative index */ public void testAddAll1_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.addAll(-1,new LinkedList()); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.addAll(-1, new LinkedList()); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * addAll throws an IndexOutOfBoundsException on a too high index */ public void testAddAll2_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("asdasd"); - c.add("asdasdasd"); - c.addAll(100, new LinkedList()); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.addAll(list.size() + 1, new LinkedList()); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * listIterator throws an IndexOutOfBoundsException on a negative index */ public void testListIterator1_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.listIterator(-1); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.listIterator(-1); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * listIterator throws an IndexOutOfBoundsException on a too high index */ public void testListIterator2_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("adasd"); - c.add("asdasdas"); - c.listIterator(100); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.listIterator(list.size() + 1); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * subList throws an IndexOutOfBoundsException on a negative index */ public void testSubList1_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.subList(-1,100); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.subList(-1, list.size()); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** * subList throws an IndexOutOfBoundsException on a too high index */ public void testSubList2_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.add("asdasd"); - c.subList(1,100); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.subList(0, list.size() + 1); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** @@ -675,11 +714,14 @@ public class CopyOnWriteArrayListTest extends JSR166TestCase { * is lower then the first */ public void testSubList3_IndexOutOfBoundsException() { - try { - CopyOnWriteArrayList c = new CopyOnWriteArrayList(); - c.subList(3,1); - shouldThrow(); - } catch (IndexOutOfBoundsException success) {} + CopyOnWriteArrayList c = populatedArray(5); + List[] lists = { c, c.subList(1, c.size() - 1) }; + for (List list : lists) { + try { + list.subList(list.size() - 1, 1); + shouldThrow(); + } catch (IndexOutOfBoundsException success) {} + } } /** diff --git a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java index feb283f..2810802 100644 --- a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java +++ b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java @@ -8,7 +8,6 @@ package jsr166; -import junit.framework.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -16,17 +15,28 @@ import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; -import java.util.Vector; import java.util.concurrent.CopyOnWriteArraySet; +import junit.framework.Test; +import junit.framework.TestSuite; + public class CopyOnWriteArraySetTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static CopyOnWriteArraySet<Integer> populatedSet(int n) { CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<Integer>(); assertTrue(a.isEmpty()); for (int i = 0; i < n; i++) a.add(i); - assertFalse(a.isEmpty()); + assertEquals(n == 0, a.isEmpty()); assertEquals(n, a.size()); return a; } @@ -62,29 +72,25 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { } /** - * addAll adds each element from the given collection + * addAll adds each non-duplicate element from the given collection */ public void testAddAll() { - CopyOnWriteArraySet full = populatedSet(3); - Vector v = new Vector(); - v.add(three); - v.add(four); - v.add(five); - full.addAll(v); + Set full = populatedSet(3); + assertTrue(full.addAll(Arrays.asList(three, four, five))); + assertEquals(6, full.size()); + assertFalse(full.addAll(Arrays.asList(three, four, five))); assertEquals(6, full.size()); } /** - * addAll adds each element from the given collection that did not - * already exist in the set + * addAll adds each non-duplicate element from the given collection */ public void testAddAll2() { - CopyOnWriteArraySet full = populatedSet(3); - Vector v = new Vector(); - v.add(three); - v.add(four); - v.add(one); // will not add this element - full.addAll(v); + Set full = populatedSet(3); + // "one" is duplicate and will not be added + assertTrue(full.addAll(Arrays.asList(three, four, one))); + assertEquals(5, full.size()); + assertFalse(full.addAll(Arrays.asList(three, four, one))); assertEquals(5, full.size()); } @@ -92,7 +98,7 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * add will not add the element if it already exists in the set */ public void testAdd2() { - CopyOnWriteArraySet full = populatedSet(3); + Set full = populatedSet(3); full.add(one); assertEquals(3, full.size()); } @@ -101,7 +107,7 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * add adds the element when it does not exist in the set */ public void testAdd3() { - CopyOnWriteArraySet full = populatedSet(3); + Set full = populatedSet(3); full.add(three); assertTrue(full.contains(three)); } @@ -110,16 +116,17 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * clear removes all elements from the set */ public void testClear() { - CopyOnWriteArraySet full = populatedSet(3); + Collection full = populatedSet(3); full.clear(); assertEquals(0, full.size()); + assertTrue(full.isEmpty()); } /** * contains returns true for added elements */ public void testContains() { - CopyOnWriteArraySet full = populatedSet(3); + Collection full = populatedSet(3); assertTrue(full.contains(one)); assertFalse(full.contains(five)); } @@ -146,23 +153,20 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * containsAll returns true for collections with subset of elements */ public void testContainsAll() { - CopyOnWriteArraySet full = populatedSet(3); - Vector v = new Vector(); - v.add(one); - v.add(two); - assertTrue(full.containsAll(v)); - v.add(six); - assertFalse(full.containsAll(v)); + Collection full = populatedSet(3); + assertTrue(full.containsAll(Arrays.asList())); + assertTrue(full.containsAll(Arrays.asList(one))); + assertTrue(full.containsAll(Arrays.asList(one, two))); + assertFalse(full.containsAll(Arrays.asList(one, two, six))); + assertFalse(full.containsAll(Arrays.asList(six))); } /** * isEmpty is true when empty, else false */ public void testIsEmpty() { - CopyOnWriteArraySet empty = new CopyOnWriteArraySet(); - CopyOnWriteArraySet full = populatedSet(3); - assertTrue(empty.isEmpty()); - assertFalse(full.isEmpty()); + assertTrue(populatedSet(0).isEmpty()); + assertFalse(populatedSet(3).isEmpty()); } /** @@ -188,18 +192,21 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { assertTrue(it.hasNext()); assertEquals(elements[j], it.next()); } - assertFalse(it.hasNext()); - try { - it.next(); - shouldThrow(); - } catch (NoSuchElementException success) {} + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new CopyOnWriteArraySet().iterator()); } /** * iterator remove is unsupported */ public void testIteratorRemove() { - CopyOnWriteArraySet full = populatedSet(3); + Collection full = populatedSet(3); Iterator it = full.iterator(); it.next(); try { @@ -213,7 +220,7 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { */ public void testToString() { assertEquals("[]", new CopyOnWriteArraySet().toString()); - CopyOnWriteArraySet full = populatedSet(3); + Collection full = populatedSet(3); String s = full.toString(); for (int i = 0; i < 3; ++i) assertTrue(s.contains(String.valueOf(i))); @@ -225,11 +232,10 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * removeAll removes all elements from the given collection */ public void testRemoveAll() { - CopyOnWriteArraySet full = populatedSet(3); - Vector v = new Vector(); - v.add(one); - v.add(two); - full.removeAll(v); + Set full = populatedSet(3); + assertTrue(full.removeAll(Arrays.asList(one, two))); + assertEquals(1, full.size()); + assertFalse(full.removeAll(Arrays.asList(one, two))); assertEquals(1, full.size()); } @@ -237,7 +243,7 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * remove removes an element */ public void testRemove() { - CopyOnWriteArraySet full = populatedSet(3); + Collection full = populatedSet(3); full.remove(one); assertFalse(full.contains(one)); assertEquals(2, full.size()); @@ -247,8 +253,8 @@ public class CopyOnWriteArraySetTest extends JSR166TestCase { * size returns the number of elements */ public void testSize() { - CopyOnWriteArraySet empty = new CopyOnWriteArraySet(); - CopyOnWriteArraySet full = populatedSet(3); + Collection empty = new CopyOnWriteArraySet(); + Collection full = populatedSet(3); assertEquals(3, full.size()); assertEquals(0, empty.size()); } diff --git a/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java b/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java index bc2aecf..da1ebb4 100644 --- a/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java +++ b/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java @@ -8,12 +8,23 @@ package jsr166; -import junit.framework.*; -import java.util.*; -import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.concurrent.CountDownLatch; + +import junit.framework.Test; +import junit.framework.TestSuite; + public class CountDownLatchTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * negative constructor argument throws IAE diff --git a/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java b/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java index 2f8665b..80d7b3b 100644 --- a/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java +++ b/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java @@ -6,25 +6,34 @@ package jsr166; -import java.util.concurrent.ExecutionException; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.HashSet; import java.util.concurrent.CancellationException; +import java.util.concurrent.CountedCompleter; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.CountedCompleter; -import java.util.concurrent.ForkJoinWorkerThread; -import java.util.concurrent.RecursiveAction; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; -import java.util.HashSet; -import junit.framework.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class CountedCompleterTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + // Runs with "mainPool" use > 1 thread. singletonPool tests use 1 static final int mainPoolSize = Math.max(2, Runtime.getRuntime().availableProcessors()); @@ -193,8 +202,8 @@ public class CountedCompleterTest extends JSR166TestCase { try { a.invoke(); shouldThrow(); - } catch (Throwable ex) { - assertSame(t, ex); + } catch (Throwable success) { + assertSame(t, success); } } @@ -494,8 +503,9 @@ public class CountedCompleterTest extends JSR166TestCase { // Invocation tests use some interdependent task classes // to better test propagation etc - - // Version of Fibonacci with different classes for left vs right forks + /** + * Version of Fibonacci with different classes for left vs right forks + */ abstract class CCF extends CheckedCC { int number; int rnumber; @@ -1131,7 +1141,7 @@ public class CountedCompleterTest extends JSR166TestCase { } /** - * invokeAll(collection) throws exception if any task does + * invokeAll(collection) throws exception if any task does */ public void testAbnormalInvokeAllCollection() { ForkJoinTask a = new CheckedRecursiveAction() { @@ -1796,7 +1806,7 @@ public class CountedCompleterTest extends JSR166TestCase { } /** - * invokeAll(collection) throws exception if any task does + * invokeAll(collection) throws exception if any task does */ public void testAbnormalInvokeAllCollectionSingleton() { ForkJoinTask a = new CheckedRecursiveAction() { diff --git a/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java b/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java index 3239030..a9d8c54 100644 --- a/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java +++ b/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java @@ -8,16 +8,27 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; +import junit.framework.TestSuite; public class CyclicBarrierTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } private volatile int countAction; private class MyAction implements Runnable { diff --git a/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java b/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java index dc221ab..7619b48 100644 --- a/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java @@ -8,9 +8,11 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.concurrent.BlockingQueue; @@ -20,10 +22,33 @@ import java.util.concurrent.DelayQueue; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; -import static java.util.concurrent.TimeUnit.MILLISECONDS; +import junit.framework.Test; + +// android-changed: Extend BlockingQueueTest directly. public class DelayQueueTest extends BlockingQueueTest { + // android-changed: Extend BlockingQueueTest directly instead of creating + // an inner class and its associated suite. + // + // public static class Generic extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new DelayQueue(); + // } + // protected PDelay makeElement(int i) { + // return new PDelay(i); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(DelayQueueTest.class, + // new Generic().testSuite()); + // } + protected BlockingQueue emptyCollection() { return new DelayQueue(); } @@ -32,8 +57,6 @@ public class DelayQueueTest extends BlockingQueueTest { return new PDelay(i); } - private static final int NOCAP = Integer.MAX_VALUE; - /** * A delayed implementation for testing. * Most tests use Pseudodelays, where delays are all elapsed @@ -115,12 +138,12 @@ public class DelayQueueTest extends BlockingQueueTest { private DelayQueue<PDelay> populatedQueue(int n) { DelayQueue<PDelay> q = new DelayQueue<PDelay>(); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.offer(new PDelay(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.offer(new PDelay(i))); assertFalse(q.isEmpty()); - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(n, q.size()); return q; } @@ -129,7 +152,7 @@ public class DelayQueueTest extends BlockingQueueTest { * A new queue has unbounded capacity */ public void testConstructor1() { - assertEquals(NOCAP, new DelayQueue().remainingCapacity()); + assertEquals(Integer.MAX_VALUE, new DelayQueue().remainingCapacity()); } /** @@ -137,7 +160,7 @@ public class DelayQueueTest extends BlockingQueueTest { */ public void testConstructor3() { try { - DelayQueue q = new DelayQueue(null); + new DelayQueue(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -148,7 +171,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testConstructor4() { try { PDelay[] ints = new PDelay[SIZE]; - DelayQueue q = new DelayQueue(Arrays.asList(ints)); + new DelayQueue(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -161,7 +184,7 @@ public class DelayQueueTest extends BlockingQueueTest { PDelay[] ints = new PDelay[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new PDelay(i); - DelayQueue q = new DelayQueue(Arrays.asList(ints)); + new DelayQueue(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -184,7 +207,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testEmpty() { DelayQueue q = new DelayQueue(); assertTrue(q.isEmpty()); - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); q.add(new PDelay(1)); assertFalse(q.isEmpty()); q.add(new PDelay(2)); @@ -194,20 +217,19 @@ public class DelayQueueTest extends BlockingQueueTest { } /** - * remainingCapacity does not change when elements added or removed, - * but size does + * remainingCapacity() always returns Integer.MAX_VALUE */ public void testRemainingCapacity() { - DelayQueue q = populatedQueue(SIZE); + BlockingQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(SIZE-i, q.size()); - q.remove(); + assertTrue(q.remove() instanceof PDelay); } for (int i = 0; i < SIZE; ++i) { - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(i, q.size()); - q.add(new PDelay(i)); + assertTrue(q.add(new PDelay(i))); } } @@ -278,9 +300,9 @@ public class DelayQueueTest extends BlockingQueueTest { public void testPut() { DelayQueue q = new DelayQueue(); for (int i = 0; i < SIZE; ++i) { - PDelay I = new PDelay(i); - q.put(I); - assertTrue(q.contains(I)); + PDelay x = new PDelay(i); + q.put(x); + assertTrue(q.contains(x)); } assertEquals(SIZE, q.size()); } @@ -324,7 +346,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testTake() throws InterruptedException { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.take())); + assertEquals(new PDelay(i), q.take()); } } @@ -367,7 +389,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testPoll() { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.poll())); + assertEquals(new PDelay(i), q.poll()); } assertNull(q.poll()); } @@ -378,7 +400,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testTimedPoll0() throws InterruptedException { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.poll(0, MILLISECONDS))); + assertEquals(new PDelay(i), q.poll(0, MILLISECONDS)); } assertNull(q.poll(0, MILLISECONDS)); } @@ -390,7 +412,7 @@ public class DelayQueueTest extends BlockingQueueTest { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { long startTime = System.nanoTime(); - assertEquals(new PDelay(i), ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS))); + assertEquals(new PDelay(i), q.poll(LONG_DELAY_MS, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); } long startTime = System.nanoTime(); @@ -439,8 +461,8 @@ public class DelayQueueTest extends BlockingQueueTest { public void testPeek() { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.peek())); - assertEquals(new PDelay(i), ((PDelay)q.poll())); + assertEquals(new PDelay(i), q.peek()); + assertEquals(new PDelay(i), q.poll()); if (q.isEmpty()) assertNull(q.peek()); else @@ -455,7 +477,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testElement() { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.element())); + assertEquals(new PDelay(i), q.element()); q.poll(); } try { @@ -470,7 +492,7 @@ public class DelayQueueTest extends BlockingQueueTest { public void testRemove() { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.remove())); + assertEquals(new PDelay(i), q.remove()); } try { q.remove(); @@ -498,7 +520,7 @@ public class DelayQueueTest extends BlockingQueueTest { q.clear(); assertTrue(q.isEmpty()); assertEquals(0, q.size()); - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); PDelay x = new PDelay(1); q.add(x); assertFalse(q.isEmpty()); @@ -550,8 +572,8 @@ public class DelayQueueTest extends BlockingQueueTest { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - PDelay I = (PDelay)(p.remove()); - assertFalse(q.contains(I)); + PDelay x = (PDelay)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -603,6 +625,14 @@ public class DelayQueueTest extends BlockingQueueTest { ++i; } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new DelayQueue().iterator()); } /** @@ -763,4 +793,12 @@ public class DelayQueueTest extends BlockingQueueTest { } } + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?> q = populatedQueue(SIZE); + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } } diff --git a/jsr166-tests/src/test/java/jsr166/EntryTest.java b/jsr166-tests/src/test/java/jsr166/EntryTest.java index 4387a53..d141a84 100644 --- a/jsr166-tests/src/test/java/jsr166/EntryTest.java +++ b/jsr166-tests/src/test/java/jsr166/EntryTest.java @@ -6,10 +6,22 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import java.util.AbstractMap; +import java.util.Map; + +import junit.framework.Test; +import junit.framework.TestSuite; public class EntryTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static final String k1 = "1"; static final String v1 = "a"; diff --git a/jsr166-tests/src/test/java/jsr166/ExchangerTest.java b/jsr166-tests/src/test/java/jsr166/ExchangerTest.java index b0f325e..172fccd 100644 --- a/jsr166-tests/src/test/java/jsr166/ExchangerTest.java +++ b/jsr166-tests/src/test/java/jsr166/ExchangerTest.java @@ -8,15 +8,27 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.Exchanger; import java.util.concurrent.TimeoutException; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ExchangerTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + /** * exchange exchanges objects across two threads */ diff --git a/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java b/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java index eced0ba..e988cc6 100644 --- a/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java +++ b/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java @@ -8,30 +8,40 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.RunnableFuture; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.util.concurrent.atomic.AtomicBoolean; -import java.security.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ExecutorCompletionServiceTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Creating a new ECS with null Executor throw NPE */ public void testConstructorNPE() { try { - ExecutorCompletionService ecs = new ExecutorCompletionService(null); + new ExecutorCompletionService(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -42,7 +52,7 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase { public void testConstructorNPE2() { try { ExecutorService e = Executors.newCachedThreadPool(); - ExecutorCompletionService ecs = new ExecutorCompletionService(e, null); + new ExecutorCompletionService(e, null); shouldThrow(); } catch (NullPointerException success) {} } diff --git a/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java b/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java index 18c0975..ae475f1 100644 --- a/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java +++ b/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java @@ -8,13 +8,36 @@ package jsr166; -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.security.*; + +import java.security.AccessControlContext; +import java.security.AccessControlException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ExecutorsTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * A newCachedThreadPool can execute runnables @@ -267,7 +290,6 @@ public class ExecutorsTest extends JSR166TestCase { for (final ExecutorService executor : executors) { threads.add(newStartedThread(new CheckedRunnable() { public void realRun() { - long startTime = System.nanoTime(); Future future = executor.submit(sleeper); assertFutureTimesOut(future); }})); @@ -328,7 +350,8 @@ public class ExecutorsTest extends JSR166TestCase { public void realRun() throws Exception { final ThreadGroup egroup = Thread.currentThread().getThreadGroup(); final ClassLoader thisccl = Thread.currentThread().getContextClassLoader(); - // final AccessControlContext thisacc = AccessController.getContext(); // Android removed + // android-note: Removed unsupported access controller check. + // final AccessControlContext thisacc = AccessController.getContext(); Runnable r = new CheckedRunnable() { public void realRun() { Thread current = Thread.currentThread(); @@ -343,7 +366,7 @@ public class ExecutorsTest extends JSR166TestCase { String name = current.getName(); assertTrue(name.endsWith("thread-1")); assertSame(thisccl, current.getContextClassLoader()); - // assertEquals(thisacc, AccessController.getContext()); // Android removed + // assertEquals(thisacc, AccessController.getContext()); done.countDown(); }}; ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory()); diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java b/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java index 8416198..09a3511 100644 --- a/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java +++ b/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java @@ -6,34 +6,42 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.AbstractExecutorService; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Callable; -import java.util.concurrent.Future; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; -import java.util.concurrent.CancellationException; -import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import java.security.AccessControlException; -import java.security.Policy; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; public class ForkJoinPoolTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /* * Testing coverage notes: @@ -103,7 +111,7 @@ public class ForkJoinPoolTest extends JSR166TestCase { static final class FibTask extends RecursiveTask<Integer> { final int number; FibTask(int n) { number = n; } - public Integer compute() { + protected Integer compute() { int n = number; if (n <= 1) return n; @@ -131,7 +139,7 @@ public class ForkJoinPoolTest extends JSR166TestCase { this.locker = locker; this.lock = lock; } - public Integer compute() { + protected Integer compute() { int n; LockingFibTask f1 = null; LockingFibTask f2 = null; @@ -414,11 +422,10 @@ public class ForkJoinPoolTest extends JSR166TestCase { ExecutorService e = new ForkJoinPool(1); try { final AtomicBoolean done = new AtomicBoolean(false); - CheckedRunnable task = new CheckedRunnable() { + Future<?> future = e.submit(new CheckedRunnable() { public void realRun() { done.set(true); - }}; - Future<?> future = e.submit(task); + }}); assertNull(future.get()); assertNull(future.get(0, MILLISECONDS)); assertTrue(done.get()); diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java b/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java index 080fd9c..3c1fcb7 100644 --- a/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java +++ b/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java @@ -6,22 +6,33 @@ package jsr166; -import java.util.concurrent.ExecutionException; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.HashSet; import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.ForkJoinWorkerThread; import java.util.concurrent.RecursiveAction; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; -import java.util.HashSet; -import junit.framework.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ForkJoinTaskTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + // Runs with "mainPool" use > 1 thread. singletonPool tests use 1 static final int mainPoolSize = Math.max(2, Runtime.getRuntime().availableProcessors()); @@ -913,7 +924,7 @@ public class ForkJoinTaskTest extends JSR166TestCase { } /** - * invokeAll(collection) throws exception if any task does + * invokeAll(collection) throws exception if any task does */ public void testAbnormalInvokeAllCollection() { RecursiveAction a = new CheckedRecursiveAction() { @@ -1580,7 +1591,7 @@ public class ForkJoinTaskTest extends JSR166TestCase { } /** - * invokeAll(collection) throws exception if any task does + * invokeAll(collection) throws exception if any task does */ public void testAbnormalInvokeAllCollectionSingleton() { RecursiveAction a = new CheckedRecursiveAction() { @@ -1602,4 +1613,21 @@ public class ForkJoinTaskTest extends JSR166TestCase { testInvokeOnPool(singletonPool(), a); } + /** + * ForkJoinTask.quietlyComplete returns when task completes + * normally without setting a value. The most recent value + * established by setRawResult(V) (or null by default) is returned + * from invoke. + */ + public void testQuietlyComplete() { + RecursiveAction a = new CheckedRecursiveAction() { + protected void realCompute() { + AsyncFib f = new AsyncFib(8); + f.quietlyComplete(); + assertEquals(8, f.number); + checkCompletedNormally(f); + }}; + testInvokeOnPool(mainPool(), a); + } + } diff --git a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java index baab79e..a5d8c46 100644 --- a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java +++ b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java @@ -8,21 +8,39 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; -import java.util.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class FutureTaskTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + void checkIsDone(Future<?> f) { assertTrue(f.isDone()); assertFalse(f.cancel(false)); @@ -122,7 +140,7 @@ public class FutureTaskTest extends JSR166TestCase { pf.set(new Object()); pf.setException(new Error()); for (boolean mayInterruptIfRunning : new boolean[] { true, false }) { - pf.cancel(true); + pf.cancel(mayInterruptIfRunning); } } @@ -473,8 +491,8 @@ public class FutureTaskTest extends JSR166TestCase { final PublicFutureTask task = new PublicFutureTask(new Runnable() { public void run() { + pleaseCancel.countDown(); try { - pleaseCancel.countDown(); delay(LONG_DELAY_MS); threadShouldThrow(); } catch (InterruptedException success) { @@ -796,4 +814,31 @@ public class FutureTaskTest extends JSR166TestCase { } } + /** + * timed get with most negative timeout works correctly (i.e. no + * underflow bug) + */ + public void testGet_NegativeInfinityTimeout() throws Exception { + final ExecutorService pool = Executors.newFixedThreadPool(10); + final Runnable nop = new Runnable() { public void run() {}}; + final FutureTask<Void> task = new FutureTask<>(nop, null); + final List<Future<?>> futures = new ArrayList<>(); + Runnable r = new Runnable() { public void run() { + for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) { + try { + task.get(timeout, NANOSECONDS); + shouldThrow(); + } catch (TimeoutException success) { + } catch (Throwable fail) {threadUnexpectedException(fail);}}}}; + for (int i = 0; i < 10; i++) + futures.add(pool.submit(r)); + try { + joinPool(pool); + for (Future<?> future : futures) + checkCompletedNormally(future, null); + } finally { + task.run(); // last resort to help terminate + } + } + } diff --git a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java index d9bf255..61fa66d 100644 --- a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java +++ b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java @@ -8,31 +8,49 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.security.SecurityPermission; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Enumeration; +import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.PropertyPermission; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.RecursiveAction; +import java.util.concurrent.RecursiveTask; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.security.SecurityPermission; +import java.util.regex.Pattern; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; /** * Base class for JSR166 Junit TCK tests. Defines some constants, @@ -108,6 +126,7 @@ import java.security.SecurityPermission; * </ul> */ public class JSR166TestCase extends TestCase { + // Delays for timing-dependent tests, in milliseconds. protected static final boolean expensiveTests = false; @@ -116,7 +135,6 @@ public class JSR166TestCase extends TestCase { public static long MEDIUM_DELAY_MS; public static long LONG_DELAY_MS; - /** * Returns the shortest timed delay. This could * be reimplemented to use for example a Property. @@ -204,7 +222,7 @@ public class JSR166TestCase extends TestCase { } /** - * Find missing try { ... } finally { joinPool(e); } + * Finds missing try { ... } finally { joinPool(e); } */ void checkForkJoinPoolThreadLeaks() throws InterruptedException { Thread[] survivors = new Thread[5]; @@ -302,11 +320,11 @@ public class JSR166TestCase extends TestCase { public void threadAssertEquals(Object x, Object y) { try { assertEquals(x, y); - } catch (AssertionFailedError t) { - threadRecordFailure(t); - throw t; - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (AssertionFailedError fail) { + threadRecordFailure(fail); + throw fail; + } catch (Throwable fail) { + threadUnexpectedException(fail); } } @@ -318,9 +336,9 @@ public class JSR166TestCase extends TestCase { public void threadAssertSame(Object x, Object y) { try { assertSame(x, y); - } catch (AssertionFailedError t) { - threadRecordFailure(t); - throw t; + } catch (AssertionFailedError fail) { + threadRecordFailure(fail); + throw fail; } } @@ -385,16 +403,23 @@ public class JSR166TestCase extends TestCase { void joinPool(ExecutorService exec) { try { exec.shutdown(); - assertTrue("ExecutorService did not terminate in a timely manner", - exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)); + if (!exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) + fail("ExecutorService " + exec + + " did not terminate in a timely manner"); } catch (SecurityException ok) { // Allowed in case test doesn't have privs - } catch (InterruptedException ie) { + } catch (InterruptedException fail) { fail("Unexpected InterruptedException"); } } /** + * A debugging tool to print all stack traces, as jstack does. + */ + static void printAllStackTraces() { + } + + /** * Checks that thread does not terminate within the default * millisecond delay of {@code timeoutMillis()}. */ @@ -410,7 +435,7 @@ public class JSR166TestCase extends TestCase { // No need to optimize the failing case via Thread.join. delay(millis); assertTrue(thread.isAlive()); - } catch (InterruptedException ie) { + } catch (InterruptedException fail) { fail("Unexpected InterruptedException"); } } @@ -432,7 +457,7 @@ public class JSR166TestCase extends TestCase { delay(millis); for (Thread thread : threads) assertTrue(thread.isAlive()); - } catch (InterruptedException ie) { + } catch (InterruptedException fail) { fail("Unexpected InterruptedException"); } } @@ -454,8 +479,8 @@ public class JSR166TestCase extends TestCase { future.get(timeoutMillis, MILLISECONDS); shouldThrow(); } catch (TimeoutException success) { - } catch (Exception e) { - threadUnexpectedException(e); + } catch (Exception fail) { + threadUnexpectedException(fail); } finally { future.cancel(true); } assertTrue(millisElapsedSince(startTime) >= timeoutMillis); } @@ -499,20 +524,23 @@ public class JSR166TestCase extends TestCase { public static final Integer m6 = new Integer(-6); public static final Integer m10 = new Integer(-10); - /** - * android-changed - * Android does not use a SecurityManager. This will simply execute - * the runnable ingoring permisions. + * Runs Runnable r with a security policy that permits precisely + * the specified permissions. If there is no current security + * manager, the runnable is run twice, both with and without a + * security manager. We require that any security manager permit + * getPolicy/setPolicy. */ public void runWithPermissions(Runnable r, Permission... permissions) { r.run(); } /** - * android-changed - * Android does not use a SecurityManager. This will simply execute - * the runnable ingoring permisions. + * Runs Runnable r with a security policy that permits precisely + * the specified permissions. If there is no current security + * manager, a temporary one is set for the duration of the + * Runnable. We require that any security manager permit + * getPolicy/setPolicy. */ public void runWithSecurityManagerWithPermissions(Runnable r, Permission... permissions) { @@ -582,10 +610,10 @@ public class JSR166TestCase extends TestCase { void sleep(long millis) { try { delay(millis); - } catch (InterruptedException ie) { + } catch (InterruptedException fail) { AssertionFailedError afe = new AssertionFailedError("Unexpected InterruptedException"); - afe.initCause(ie); + afe.initCause(fail); throw afe; } } @@ -623,12 +651,42 @@ public class JSR166TestCase extends TestCase { /** * Returns the number of milliseconds since time given by * startNanoTime, which must have been previously returned from a - * call to {@link System.nanoTime()}. + * call to {@link System#nanoTime()}. */ - long millisElapsedSince(long startNanoTime) { + static long millisElapsedSince(long startNanoTime) { return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); } +// void assertTerminatesPromptly(long timeoutMillis, Runnable r) { +// long startTime = System.nanoTime(); +// try { +// r.run(); +// } catch (Throwable fail) { threadUnexpectedException(fail); } +// if (millisElapsedSince(startTime) > timeoutMillis/2) +// throw new AssertionFailedError("did not return promptly"); +// } + +// void assertTerminatesPromptly(Runnable r) { +// assertTerminatesPromptly(LONG_DELAY_MS/2, r); +// } + + /** + * Checks that timed f.get() returns the expected value, and does not + * wait for the timeout to elapse before returning. + */ + <T> void checkTimedGet(Future<T> f, T expectedValue, long timeoutMillis) { + long startTime = System.nanoTime(); + try { + assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS)); + } catch (Throwable fail) { threadUnexpectedException(fail); } + if (millisElapsedSince(startTime) > timeoutMillis/2) + throw new AssertionFailedError("timed get did not return promptly"); + } + + <T> void checkTimedGet(Future<T> f, T expectedValue) { + checkTimedGet(f, expectedValue, LONG_DELAY_MS); + } + /** * Returns a new started daemon Thread running the given runnable. */ @@ -647,8 +705,8 @@ public class JSR166TestCase extends TestCase { void awaitTermination(Thread t, long timeoutMillis) { try { t.join(timeoutMillis); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); + } catch (InterruptedException fail) { + threadUnexpectedException(fail); } finally { if (t.getState() != Thread.State.TERMINATED) { t.interrupt(); @@ -674,8 +732,8 @@ public class JSR166TestCase extends TestCase { public final void run() { try { realRun(); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); } } } @@ -729,8 +787,8 @@ public class JSR166TestCase extends TestCase { threadShouldThrow("InterruptedException"); } catch (InterruptedException success) { threadAssertFalse(Thread.interrupted()); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); } } } @@ -741,8 +799,8 @@ public class JSR166TestCase extends TestCase { public final T call() { try { return realCall(); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); return null; } } @@ -759,8 +817,8 @@ public class JSR166TestCase extends TestCase { return result; } catch (InterruptedException success) { threadAssertFalse(Thread.interrupted()); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); } return null; } @@ -800,16 +858,16 @@ public class JSR166TestCase extends TestCase { public void await(CountDownLatch latch) { try { assertTrue(latch.await(LONG_DELAY_MS, MILLISECONDS)); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); } } public void await(Semaphore semaphore) { try { assertTrue(semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS)); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); } } @@ -1003,8 +1061,8 @@ public class JSR166TestCase extends TestCase { @Override protected final void compute() { try { realCompute(); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); } } } @@ -1018,8 +1076,8 @@ public class JSR166TestCase extends TestCase { @Override protected final T compute() { try { return realCompute(); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); return null; } } @@ -1043,12 +1101,12 @@ public class JSR166TestCase extends TestCase { public int await() { try { return super.await(2 * LONG_DELAY_MS, MILLISECONDS); - } catch (TimeoutException e) { + } catch (TimeoutException timedOut) { throw new AssertionFailedError("timed out"); - } catch (Exception e) { + } catch (Exception fail) { AssertionFailedError afe = - new AssertionFailedError("Unexpected exception: " + e); - afe.initCause(e); + new AssertionFailedError("Unexpected exception: " + fail); + afe.initCause(fail); throw afe; } } @@ -1076,9 +1134,7 @@ public class JSR166TestCase extends TestCase { q.remove(); shouldThrow(); } catch (NoSuchElementException success) {} - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } void assertSerialEquals(Object x, Object y) { @@ -1097,8 +1153,8 @@ public class JSR166TestCase extends TestCase { oos.flush(); oos.close(); return bos.toByteArray(); - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); return new byte[0]; } } @@ -1111,8 +1167,8 @@ public class JSR166TestCase extends TestCase { T clone = (T) ois.readObject(); assertSame(o.getClass(), clone.getClass()); return clone; - } catch (Throwable t) { - threadUnexpectedException(t); + } catch (Throwable fail) { + threadUnexpectedException(fail); return null; } } @@ -1137,4 +1193,12 @@ public class JSR166TestCase extends TestCase { shouldThrow(expectedExceptionClass.getName()); } } + + public void assertIteratorExhausted(Iterator<?> it) { + try { + it.next(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertFalse(it.hasNext()); + } } diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java index 4016f6d..62802bb 100644 --- a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java +++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java @@ -6,10 +6,12 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Deque; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; @@ -19,10 +21,36 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingDeque; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; public class LinkedBlockingDequeTest extends JSR166TestCase { + // android-note: These tests have been moved into their own separate + // classes to work around CTS issues. + // + // public static class Unbounded extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new LinkedBlockingDeque(); + // } + // } + // + // public static class Bounded extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new LinkedBlockingDeque(SIZE); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(LinkedBlockingDequeTest.class, + // new Unbounded().testSuite(), + // new Bounded().testSuite()); + // } + /** * Returns a new deque of given size containing consecutive * Integers 0 ... n. @@ -253,10 +281,10 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { */ public void testRemoveFirstOccurrence() { LinkedBlockingDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); assertFalse(q.removeFirstOccurrence(new Integer(i+1))); } @@ -268,10 +296,10 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { */ public void testRemoveLastOccurrence() { LinkedBlockingDeque q = populatedDeque(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); assertFalse(q.removeLastOccurrence(new Integer(i+1))); } @@ -384,16 +412,16 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { * remainingCapacity decreases on add, increases on remove */ public void testRemainingCapacity() { - LinkedBlockingDeque q = populatedDeque(SIZE); + BlockingQueue q = populatedDeque(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(i, q.remainingCapacity()); - assertEquals(SIZE-i, q.size()); - q.remove(); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertEquals(i, q.remove()); } for (int i = 0; i < SIZE; ++i) { assertEquals(SIZE-i, q.remainingCapacity()); - assertEquals(i, q.size()); - q.add(new Integer(i)); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertTrue(q.add(i)); } } @@ -415,9 +443,9 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { try { LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.push(I); - assertEquals(I, q.peek()); + Integer x = new Integer(i); + q.push(x); + assertEquals(x, q.peek()); } assertEquals(0, q.remainingCapacity()); q.push(new Integer(SIZE)); @@ -535,9 +563,9 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { public void testPut() throws InterruptedException { LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.put(I); - assertTrue(q.contains(I)); + Integer x = new Integer(i); + q.put(x); + assertTrue(q.contains(x)); } assertEquals(0, q.remainingCapacity()); } @@ -767,9 +795,9 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { public void testPutFirst() throws InterruptedException { LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.putFirst(I); - assertTrue(q.contains(I)); + Integer x = new Integer(i); + q.putFirst(x); + assertTrue(q.contains(x)); } assertEquals(0, q.remainingCapacity()); } @@ -1114,9 +1142,9 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { public void testPutLast() throws InterruptedException { LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.putLast(I); - assertTrue(q.contains(I)); + Integer x = new Integer(i); + q.putLast(x); + assertTrue(q.contains(x)); } assertEquals(0, q.remainingCapacity()); } @@ -1450,8 +1478,8 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -1495,9 +1523,26 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { public void testIterator() throws InterruptedException { LinkedBlockingDeque q = populatedDeque(SIZE); Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) + assertTrue(q.contains(it.next())); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + + it = q.iterator(); + for (i = 0; it.hasNext(); i++) assertEquals(it.next(), q.take()); - } + assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + Deque c = new LinkedBlockingDeque(); + assertIteratorExhausted(c.iterator()); + assertIteratorExhausted(c.descendingIterator()); } /** @@ -1750,7 +1795,24 @@ public class LinkedBlockingDequeTest extends JSR166TestCase { assertEquals(SIZE-k, q.size()); for (int j = 0; j < k; ++j) assertEquals(l.get(j), new Integer(j)); - while (q.poll() != null) ; + do {} while (q.poll() != null); + } + } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Deque<?>[] qs = { + new LinkedBlockingDeque<Object>(), + populatedDeque(2), + }; + + for (Deque<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + assertFalse(q.removeFirstOccurrence(null)); + assertFalse(q.removeLastOccurrence(null)); } } diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java index fe0b871..bd37b2a 100644 --- a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java @@ -8,22 +8,49 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; -import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.concurrent.LinkedBlockingQueue; + +import junit.framework.Test; public class LinkedBlockingQueueTest extends JSR166TestCase { + // android-note: These tests have been moved into their own separate + // classes to work around CTS issues. + // + // public static class Unbounded extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new LinkedBlockingQueue(); + // } + // } + // + // public static class Bounded extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new LinkedBlockingQueue(SIZE); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(LinkedBlockingQueueTest.class, + // new Unbounded().testSuite(), + // new Bounded().testSuite()); + // } + /** * Returns a new queue of given size containing consecutive * Integers 0 ... n. @@ -126,16 +153,16 @@ public class LinkedBlockingQueueTest extends JSR166TestCase { * remainingCapacity decreases on add, increases on remove */ public void testRemainingCapacity() { - LinkedBlockingQueue q = populatedQueue(SIZE); + BlockingQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(i, q.remainingCapacity()); - assertEquals(SIZE-i, q.size()); - q.remove(); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertEquals(i, q.remove()); } for (int i = 0; i < SIZE; ++i) { assertEquals(SIZE-i, q.remainingCapacity()); - assertEquals(i, q.size()); - q.add(new Integer(i)); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertTrue(q.add(i)); } } @@ -225,9 +252,9 @@ public class LinkedBlockingQueueTest extends JSR166TestCase { public void testPut() throws InterruptedException { LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.put(I); - assertTrue(q.contains(I)); + Integer x = new Integer(i); + q.put(x); + assertTrue(q.contains(x)); } assertEquals(0, q.remainingCapacity()); } @@ -567,8 +594,8 @@ public class LinkedBlockingQueueTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -612,9 +639,24 @@ public class LinkedBlockingQueueTest extends JSR166TestCase { public void testIterator() throws InterruptedException { LinkedBlockingQueue q = populatedQueue(SIZE); Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) + assertTrue(q.contains(it.next())); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + + it = q.iterator(); + for (i = 0; it.hasNext(); i++) assertEquals(it.next(), q.take()); - } + assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new LinkedBlockingQueue().iterator()); } /** @@ -805,7 +847,22 @@ public class LinkedBlockingQueueTest extends JSR166TestCase { assertEquals(SIZE-k, q.size()); for (int j = 0; j < k; ++j) assertEquals(l.get(j), new Integer(j)); - while (q.poll() != null) ; + do {} while (q.poll() != null); + } + } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?>[] qs = { + new LinkedBlockingQueue<Object>(), + populatedQueue(2), + }; + + for (Collection<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); } } diff --git a/jsr166-tests/src/test/java/jsr166/LinkedListTest.java b/jsr166-tests/src/test/java/jsr166/LinkedListTest.java index 5b09100..9d9481d 100644 --- a/jsr166-tests/src/test/java/jsr166/LinkedListTest.java +++ b/jsr166-tests/src/test/java/jsr166/LinkedListTest.java @@ -8,14 +8,25 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.NoSuchElementException; +import junit.framework.Test; +import junit.framework.TestSuite; + public class LinkedListTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new queue of given size containing consecutive @@ -43,7 +54,7 @@ public class LinkedListTest extends JSR166TestCase { */ public void testConstructor3() { try { - LinkedList q = new LinkedList((Collection)null); + new LinkedList((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -230,13 +241,13 @@ public class LinkedListTest extends JSR166TestCase { */ public void testRemoveElement() { LinkedList q = populatedQueue(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove((Integer)i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove((Integer)i)); assertFalse(q.contains(i)); @@ -315,8 +326,8 @@ public class LinkedListTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -372,13 +383,19 @@ public class LinkedListTest extends JSR166TestCase { */ public void testIterator() { LinkedList q = populatedQueue(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new LinkedList().iterator()); } /** @@ -599,10 +616,10 @@ public class LinkedListTest extends JSR166TestCase { */ public void testRemoveFirstOccurrence() { LinkedList q = populatedQueue(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeFirstOccurrence(new Integer(i))); assertFalse(q.removeFirstOccurrence(new Integer(i+1))); } @@ -614,10 +631,10 @@ public class LinkedListTest extends JSR166TestCase { */ public void testRemoveLastOccurrence() { LinkedList q = populatedQueue(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.removeLastOccurrence(new Integer(i))); assertFalse(q.removeLastOccurrence(new Integer(i+1))); } diff --git a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java index 94427df..f5893ec 100644 --- a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java @@ -7,9 +7,10 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -20,12 +21,30 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedTransferQueue; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import junit.framework.Test; @SuppressWarnings({"unchecked", "rawtypes"}) +// android-changed: Extend BlockingQueueTest directly. public class LinkedTransferQueueTest extends BlockingQueueTest { + // android-changed: Extend BlockingQueueTest directly. + // + // public static class Generic extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new LinkedTransferQueue(); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(LinkedTransferQueueTest.class, + // new Generic().testSuite()); + // } + protected BlockingQueue emptyCollection() { return new LinkedTransferQueue(); } @@ -105,16 +124,16 @@ public class LinkedTransferQueueTest extends BlockingQueueTest { * remainingCapacity() always returns Integer.MAX_VALUE */ public void testRemainingCapacity() { - LinkedTransferQueue<Integer> q = populatedQueue(SIZE); + BlockingQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(SIZE - i, q.size()); - q.remove(); + assertEquals(i, q.remove()); } for (int i = 0; i < SIZE; ++i) { assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(i, q.size()); - q.add(i); + assertTrue(q.add(i)); } } @@ -490,11 +509,24 @@ public class LinkedTransferQueueTest extends BlockingQueueTest { public void testIterator() throws InterruptedException { LinkedTransferQueue q = populatedQueue(SIZE); Iterator it = q.iterator(); - int i = 0; - while (it.hasNext()) { - assertEquals(it.next(), i++); - } + int i; + for (i = 0; it.hasNext(); i++) + assertTrue(q.contains(it.next())); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + + it = q.iterator(); + for (i = 0; it.hasNext(); i++) + assertEquals(it.next(), q.take()); assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new LinkedTransferQueue().iterator()); } /** @@ -687,8 +719,7 @@ public class LinkedTransferQueueTest extends BlockingQueueTest { assertEquals(SIZE - k, q.size()); for (int j = 0; j < k; ++j) assertEquals(j, l.get(j)); - while (q.poll() != null) - ; + do {} while (q.poll() != null); } } @@ -1004,4 +1035,19 @@ public class LinkedTransferQueueTest extends BlockingQueueTest { assertFalse(q.isEmpty()); return q; } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?>[] qs = { + new LinkedTransferQueue<Object>(), + populatedQueue(2), + }; + + for (Collection<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } + } } diff --git a/jsr166-tests/src/test/java/jsr166/LockSupportTest.java b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java index 051de35..8347b08 100644 --- a/jsr166-tests/src/test/java/jsr166/LockSupportTest.java +++ b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java @@ -9,13 +9,25 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; +import junit.framework.TestSuite; public class LockSupportTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns the blocker object used by tests in this file. diff --git a/jsr166-tests/src/test/java/jsr166/PhaserTest.java b/jsr166-tests/src/test/java/jsr166/PhaserTest.java index 3889c1f..42d72f4 100644 --- a/jsr166-tests/src/test/java/jsr166/PhaserTest.java +++ b/jsr166-tests/src/test/java/jsr166/PhaserTest.java @@ -7,19 +7,30 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Phaser; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Phaser; import java.util.concurrent.TimeoutException; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import junit.framework.Test; +import junit.framework.TestSuite; + public class PhaserTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + private static final int maxParties = 65535; /** Checks state of unterminated phaser. */ diff --git a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java index 89d6d24..64c3b3a 100644 --- a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java @@ -8,24 +8,49 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; -import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; -import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.concurrent.PriorityBlockingQueue; + +import junit.framework.Test; public class PriorityBlockingQueueTest extends JSR166TestCase { - private static final int NOCAP = Integer.MAX_VALUE; + // android-note: These tests have been moved into their own separate + // classes to work around CTS issues. + // + // public static class Generic extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new PriorityBlockingQueue(); + // } + // } + // + // public static class InitialCapacity extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new PriorityBlockingQueue(SIZE); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(PriorityBlockingQueueTest.class, + // new Generic().testSuite(), + // new InitialCapacity().testSuite()); + // } /** Sample Comparator */ static class MyReverseComparator implements Comparator { @@ -42,12 +67,12 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { PriorityBlockingQueue<Integer> q = new PriorityBlockingQueue<Integer>(n); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.offer(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.offer(new Integer(i))); assertFalse(q.isEmpty()); - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(n, q.size()); return q; } @@ -56,7 +81,8 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { * A new queue has unbounded capacity */ public void testConstructor1() { - assertEquals(NOCAP, new PriorityBlockingQueue(SIZE).remainingCapacity()); + assertEquals(Integer.MAX_VALUE, + new PriorityBlockingQueue(SIZE).remainingCapacity()); } /** @@ -137,7 +163,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { public void testEmpty() { PriorityBlockingQueue q = new PriorityBlockingQueue(2); assertTrue(q.isEmpty()); - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); q.add(one); assertFalse(q.isEmpty()); q.add(two); @@ -147,20 +173,19 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { } /** - * remainingCapacity does not change when elements added or removed, - * but size does + * remainingCapacity() always returns Integer.MAX_VALUE */ public void testRemainingCapacity() { - PriorityBlockingQueue q = populatedQueue(SIZE); + BlockingQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(NOCAP, q.remainingCapacity()); - assertEquals(SIZE-i, q.size()); - q.remove(); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); + assertEquals(SIZE - i, q.size()); + assertEquals(i, q.remove()); } for (int i = 0; i < SIZE; ++i) { - assertEquals(NOCAP, q.remainingCapacity()); + assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(i, q.size()); - q.add(new Integer(i)); + assertTrue(q.add(i)); } } @@ -177,9 +202,8 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { * Offer of non-Comparable throws CCE */ public void testOfferNonComparable() { + PriorityBlockingQueue q = new PriorityBlockingQueue(1); try { - PriorityBlockingQueue q = new PriorityBlockingQueue(1); - q.offer(new Object()); q.offer(new Object()); q.offer(new Object()); shouldThrow(); @@ -244,9 +268,9 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { public void testPut() { PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - Integer I = new Integer(i); - q.put(I); - assertTrue(q.contains(I)); + Integer x = new Integer(i); + q.put(x); + assertTrue(q.contains(x)); } assertEquals(SIZE, q.size()); } @@ -508,8 +532,8 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -554,13 +578,19 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { */ public void testIterator() { PriorityBlockingQueue q = populatedQueue(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new PriorityBlockingQueue().iterator()); } /** @@ -692,7 +722,22 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { assertEquals(SIZE-k, q.size()); for (int j = 0; j < k; ++j) assertEquals(l.get(j), new Integer(j)); - while (q.poll() != null) ; + do {} while (q.poll() != null); + } + } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?>[] qs = { + new PriorityBlockingQueue<Object>(), + populatedQueue(2), + }; + + for (Collection<?> q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); } } diff --git a/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java b/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java index 2b237dd..88cdd37 100644 --- a/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java @@ -8,7 +8,6 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; @@ -17,7 +16,19 @@ import java.util.NoSuchElementException; import java.util.PriorityQueue; import java.util.Queue; +import junit.framework.Test; +import junit.framework.TestSuite; + public class PriorityQueueTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class MyReverseComparator implements Comparator { public int compare(Object x, Object y) { @@ -32,9 +43,9 @@ public class PriorityQueueTest extends JSR166TestCase { private PriorityQueue<Integer> populatedQueue(int n) { PriorityQueue<Integer> q = new PriorityQueue<Integer>(n); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.offer(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.offer(new Integer(i))); assertFalse(q.isEmpty()); assertEquals(n, q.size()); @@ -53,7 +64,7 @@ public class PriorityQueueTest extends JSR166TestCase { */ public void testConstructor2() { try { - PriorityQueue q = new PriorityQueue(0); + new PriorityQueue(0); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -63,7 +74,7 @@ public class PriorityQueueTest extends JSR166TestCase { */ public void testConstructor3() { try { - PriorityQueue q = new PriorityQueue((Collection)null); + new PriorityQueue((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -74,7 +85,7 @@ public class PriorityQueueTest extends JSR166TestCase { public void testConstructor4() { try { Integer[] ints = new Integer[SIZE]; - PriorityQueue q = new PriorityQueue(Arrays.asList(ints)); + new PriorityQueue(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -87,7 +98,7 @@ public class PriorityQueueTest extends JSR166TestCase { Integer[] ints = new Integer[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new Integer(i); - PriorityQueue q = new PriorityQueue(Arrays.asList(ints)); + new PriorityQueue(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -183,9 +194,8 @@ public class PriorityQueueTest extends JSR166TestCase { * Offer of non-Comparable throws CCE */ public void testOfferNonComparable() { + PriorityQueue q = new PriorityQueue(1); try { - PriorityQueue q = new PriorityQueue(1); - q.offer(new Object()); q.offer(new Object()); q.offer(new Object()); shouldThrow(); @@ -315,13 +325,13 @@ public class PriorityQueueTest extends JSR166TestCase { */ public void testRemoveElement() { PriorityQueue q = populatedQueue(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -400,8 +410,8 @@ public class PriorityQueueTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.remove()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); } } } @@ -435,13 +445,19 @@ public class PriorityQueueTest extends JSR166TestCase { */ public void testIterator() { PriorityQueue q = populatedQueue(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new PriorityQueue().iterator()); } /** diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java index ad61a2e..1c3bba8 100644 --- a/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java +++ b/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java @@ -6,23 +6,35 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.Arrays; +import java.util.HashSet; import java.util.concurrent.CancellationException; -import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.ForkJoinWorkerThread; import java.util.concurrent.RecursiveAction; +import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import static java.util.concurrent.TimeUnit.SECONDS; -import java.util.Arrays; -import java.util.HashSet; + +import junit.framework.Test; +import junit.framework.TestSuite; public class RecursiveActionTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + private static ForkJoinPool mainPool() { return new ForkJoinPool(); } @@ -496,6 +508,8 @@ public class RecursiveActionTest extends JSR166TestCase { FibAction f = new FibAction(8); assertSame(f, f.fork()); helpQuiesce(); + while (!f.isDone()) // wait out race + ; assertEquals(21, f.result); assertEquals(0, getQueuedTaskCount()); checkCompletedNormally(f); @@ -581,7 +595,7 @@ public class RecursiveActionTest extends JSR166TestCase { FailingFibAction f = new FailingFibAction(8); assertSame(f, f.fork()); try { - f.get(5L, TimeUnit.SECONDS); + f.get(5L, SECONDS); shouldThrow(); } catch (ExecutionException success) { Throwable cause = success.getCause(); diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java index 48b6470..7783370 100644 --- a/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java +++ b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java @@ -6,20 +6,31 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.HashSet; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.ForkJoinWorkerThread; import java.util.concurrent.RecursiveTask; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import static java.util.concurrent.TimeUnit.SECONDS; -import java.util.HashSet; + +import junit.framework.Test; +import junit.framework.TestSuite; public class RecursiveTaskTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + private static ForkJoinPool mainPool() { return new ForkJoinPool(); } diff --git a/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java b/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java index 6fe8122..17eaf76 100644 --- a/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java +++ b/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java @@ -8,34 +8,48 @@ package jsr166; -import junit.framework.*; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.util.*; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; -public class ReentrantLockTest extends JSR166TestCase { +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; +public class ReentrantLockTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** - * A runnable calling lockInterruptibly + * A checked runnable calling lockInterruptibly */ class InterruptibleLockRunnable extends CheckedRunnable { final ReentrantLock lock; - InterruptibleLockRunnable(ReentrantLock l) { lock = l; } + InterruptibleLockRunnable(ReentrantLock lock) { this.lock = lock; } public void realRun() throws InterruptedException { lock.lockInterruptibly(); } } /** - * A runnable calling lockInterruptibly that expects to be + * A checked runnable calling lockInterruptibly that expects to be * interrupted */ class InterruptedLockRunnable extends CheckedInterruptedRunnable { final ReentrantLock lock; - InterruptedLockRunnable(ReentrantLock l) { lock = l; } + InterruptedLockRunnable(ReentrantLock lock) { this.lock = lock; } public void realRun() throws InterruptedException { lock.lockInterruptibly(); } @@ -133,7 +147,7 @@ public class ReentrantLockTest extends JSR166TestCase { lock.unlock(); } - enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }; + enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } /** * Awaits condition using the specified AwaitMethod. @@ -156,6 +170,8 @@ public class ReentrantLockTest extends JSR166TestCase { case awaitUntil: assertTrue(c.awaitUntil(delayedDate(timeoutMillis))); break; + default: + throw new AssertionError(); } } @@ -448,9 +464,7 @@ public class ReentrantLockTest extends JSR166TestCase { barrier.await(); awaitTermination(t); assertFalse(lock.isLocked()); - } catch (Exception e) { - threadUnexpectedException(e); - } + } catch (Exception fail) { threadUnexpectedException(fail); } } /** @@ -462,9 +476,7 @@ public class ReentrantLockTest extends JSR166TestCase { final PublicReentrantLock lock = new PublicReentrantLock(fair); try { lock.lockInterruptibly(); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } assertLockedByMoi(lock); Thread t = newStartedThread(new InterruptedLockRunnable(lock)); waitForQueuedThread(lock, t); @@ -525,9 +537,7 @@ public class ReentrantLockTest extends JSR166TestCase { assertTrue(nanosRemaining <= 0); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -545,9 +555,7 @@ public class ReentrantLockTest extends JSR166TestCase { assertFalse(c.await(timeoutMillis, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -566,9 +574,7 @@ public class ReentrantLockTest extends JSR166TestCase { assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis))); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** diff --git a/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java b/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java index 2be27d2..7ef8ea3 100644 --- a/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java +++ b/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java @@ -8,16 +8,31 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.CountDownLatch; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.util.*; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; public class ReentrantReadWriteLockTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * A runnable calling lockInterruptibly @@ -142,7 +157,7 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { lock.writeLock().unlock(); } - enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }; + enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } /** * Awaits condition using the specified AwaitMethod. @@ -164,6 +179,8 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { java.util.Date d = new java.util.Date(); assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS))); break; + default: + throw new AssertionError(); } } @@ -818,9 +835,7 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { new PublicReentrantReadWriteLock(fair); try { lock.writeLock().lockInterruptibly(); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.writeLock().lockInterruptibly(); @@ -845,9 +860,7 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { lock.readLock().lockInterruptibly(); lock.readLock().unlock(); lock.writeLock().lockInterruptibly(); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.readLock().lockInterruptibly(); @@ -873,7 +886,9 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { await(c, awaitMethod); shouldThrow(); } catch (IllegalMonitorStateException success) { - } catch (InterruptedException e) { threadUnexpectedException(e); } + } catch (InterruptedException fail) { + threadUnexpectedException(fail); + } assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); } } @@ -924,9 +939,7 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { assertTrue(nanosRemaining <= 0); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.writeLock().unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -945,9 +958,7 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { assertFalse(c.await(timeoutMillis, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.writeLock().unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -967,9 +978,7 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase { assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis))); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.writeLock().unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** diff --git a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java index b72ad02..a93feea 100644 --- a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java +++ b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java @@ -6,13 +6,42 @@ package jsr166; -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ScheduledExecutorSubclassTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class CustomTask<V> implements RunnableScheduledFuture<V> { RunnableScheduledFuture<V> task; @@ -189,17 +218,27 @@ public class ScheduledExecutorSubclassTest extends JSR166TestCase { */ public void testFixedRateSequence() throws InterruptedException { CustomExecutor p = new CustomExecutor(1); - RunnableCounter counter = new RunnableCounter(); - ScheduledFuture h = - p.scheduleAtFixedRate(counter, 0, 1, MILLISECONDS); - delay(SMALL_DELAY_MS); - h.cancel(true); - int c = counter.count.get(); - // By time scaling conventions, we must have at least - // an execution per SHORT delay, but no more than one SHORT more - assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS); - assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS); - joinPool(p); + try { + for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) { + long startTime = System.nanoTime(); + int cycles = 10; + final CountDownLatch done = new CountDownLatch(cycles); + Runnable task = new CheckedRunnable() { + public void realRun() { done.countDown(); }}; + ScheduledFuture h = + p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS); + done.await(); + h.cancel(true); + double normalizedTime = + (double) millisElapsedSince(startTime) / delay; + if (normalizedTime >= cycles - 1 && + normalizedTime <= cycles) + return; + } + throw new AssertionError("unexpected execution rate"); + } finally { + joinPool(p); + } } /** @@ -207,15 +246,27 @@ public class ScheduledExecutorSubclassTest extends JSR166TestCase { */ public void testFixedDelaySequence() throws InterruptedException { CustomExecutor p = new CustomExecutor(1); - RunnableCounter counter = new RunnableCounter(); - ScheduledFuture h = - p.scheduleWithFixedDelay(counter, 0, 1, MILLISECONDS); - delay(SMALL_DELAY_MS); - h.cancel(true); - int c = counter.count.get(); - assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS); - assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS); - joinPool(p); + try { + for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) { + long startTime = System.nanoTime(); + int cycles = 10; + final CountDownLatch done = new CountDownLatch(cycles); + Runnable task = new CheckedRunnable() { + public void realRun() { done.countDown(); }}; + ScheduledFuture h = + p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS); + done.await(); + h.cancel(true); + double normalizedTime = + (double) millisElapsedSince(startTime) / delay; + if (normalizedTime >= cycles - 1 && + normalizedTime <= cycles) + return; + } + throw new AssertionError("unexpected execution rate"); + } finally { + joinPool(p); + } } /** diff --git a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java index 4eea2c9..a2e83d0 100644 --- a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java +++ b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java @@ -8,13 +8,37 @@ package jsr166; -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicInteger; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ScheduledExecutorTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * execute successfully executes a runnable @@ -137,17 +161,27 @@ public class ScheduledExecutorTest extends JSR166TestCase { */ public void testFixedRateSequence() throws InterruptedException { ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1); - RunnableCounter counter = new RunnableCounter(); - ScheduledFuture h = - p.scheduleAtFixedRate(counter, 0, 1, MILLISECONDS); - delay(SMALL_DELAY_MS); - h.cancel(true); - int c = counter.count.get(); - // By time scaling conventions, we must have at least - // an execution per SHORT delay, but no more than one SHORT more - assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS); - assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS); - joinPool(p); + try { + for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) { + long startTime = System.nanoTime(); + int cycles = 10; + final CountDownLatch done = new CountDownLatch(cycles); + Runnable task = new CheckedRunnable() { + public void realRun() { done.countDown(); }}; + ScheduledFuture h = + p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS); + done.await(); + h.cancel(true); + double normalizedTime = + (double) millisElapsedSince(startTime) / delay; + if (normalizedTime >= cycles - 1 && + normalizedTime <= cycles) + return; + } + throw new AssertionError("unexpected execution rate"); + } finally { + joinPool(p); + } } /** @@ -155,15 +189,27 @@ public class ScheduledExecutorTest extends JSR166TestCase { */ public void testFixedDelaySequence() throws InterruptedException { ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1); - RunnableCounter counter = new RunnableCounter(); - ScheduledFuture h = - p.scheduleWithFixedDelay(counter, 0, 1, MILLISECONDS); - delay(SMALL_DELAY_MS); - h.cancel(true); - int c = counter.count.get(); - assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS); - assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS); - joinPool(p); + try { + for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) { + long startTime = System.nanoTime(); + int cycles = 10; + final CountDownLatch done = new CountDownLatch(cycles); + Runnable task = new CheckedRunnable() { + public void realRun() { done.countDown(); }}; + ScheduledFuture h = + p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS); + done.await(); + h.cancel(true); + double normalizedTime = + (double) millisElapsedSince(startTime) / delay; + if (normalizedTime >= cycles - 1 && + normalizedTime <= cycles) + return; + } + throw new AssertionError("unexpected execution rate"); + } finally { + joinPool(p); + } } /** diff --git a/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java b/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java index f303285..db4f4b4 100644 --- a/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java +++ b/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java @@ -8,14 +8,26 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -public class SemaphoreTest extends JSR166TestCase { +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; +public class SemaphoreTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Subclass to expose protected methods */ @@ -608,7 +620,7 @@ public class SemaphoreTest extends JSR166TestCase { assertTrue(t2.isAlive()); s.release(); awaitTermination(t2); - } + } /** * toString indicates current number of permits diff --git a/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java b/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java index bd030cf..605a955 100644 --- a/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java @@ -8,22 +8,48 @@ package jsr166; -import junit.framework.*; -import java.util.Arrays; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.Queue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.SynchronousQueue; -import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import junit.framework.Test; public class SynchronousQueueTest extends JSR166TestCase { + // android-note: These tests have been moved into their own separate + // classes to work around CTS issues. + // + // public static class Fair extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new SynchronousQueue(true); + // } + // } + // + // public static class NonFair extends BlockingQueueTest { + // protected BlockingQueue emptyCollection() { + // return new SynchronousQueue(false); + // } + // } + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // + // public static Test suite() { + // return newTestSuite(SynchronousQueueTest.class, + // new Fair().testSuite(), + // new NonFair().testSuite()); + // } + /** * Any SynchronousQueue is both empty and full */ @@ -402,7 +428,7 @@ public class SynchronousQueueTest extends JSR166TestCase { public void testToArray_null(boolean fair) { final SynchronousQueue q = new SynchronousQueue(fair); try { - Object o[] = q.toArray(null); + Object[] o = q.toArray(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -413,13 +439,7 @@ public class SynchronousQueueTest extends JSR166TestCase { public void testIterator() { testIterator(false); } public void testIterator_fair() { testIterator(true); } public void testIterator(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - Iterator it = q.iterator(); - assertFalse(it.hasNext()); - try { - Object x = it.next(); - shouldThrow(); - } catch (NoSuchElementException success) {} + assertIteratorExhausted(new SynchronousQueue(fair).iterator()); } /** @@ -586,4 +606,13 @@ public class SynchronousQueueTest extends JSR166TestCase { awaitTermination(t2); } + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection<?> q = new SynchronousQueue(); + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } + } diff --git a/jsr166-tests/src/test/java/jsr166/SystemTest.java b/jsr166-tests/src/test/java/jsr166/SystemTest.java index 32caec2..6918374 100644 --- a/jsr166-tests/src/test/java/jsr166/SystemTest.java +++ b/jsr166-tests/src/test/java/jsr166/SystemTest.java @@ -8,9 +8,19 @@ package jsr166; -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestSuite; public class SystemTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Worst case rounding for millisecs; set for 60 cycle millis clock. diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java index 665a2b7..4ae141d 100644 --- a/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java +++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java @@ -6,14 +6,25 @@ package jsr166; -import junit.framework.*; -import java.util.*; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import junit.framework.Test; +import junit.framework.TestSuite; + public class ThreadLocalRandomTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } + /* * Testing coverage notes: * @@ -23,15 +34,18 @@ public class ThreadLocalRandomTest extends JSR166TestCase { * across multiples of primes. */ - // + // max numbers of calls to detect getting stuck on one value static final int NCALLS = 10000; // max sampled int bound static final int MAX_INT_BOUND = (1 << 28); - // Max sampled long bound + // max sampled long bound static final long MAX_LONG_BOUND = (1L << 42); + // Number of replications for other checks + static final int REPS = 20; + /** * setSeed throws UnsupportedOperationException */ @@ -43,7 +57,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * Repeated calls to nextInt produce at least one different result + * Repeated calls to nextInt produce at least two distinct results */ public void testNextInt() { int f = ThreadLocalRandom.current().nextInt(); @@ -54,7 +68,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * Repeated calls to nextLong produce at least one different result + * Repeated calls to nextLong produce at least two distinct results */ public void testNextLong() { long f = ThreadLocalRandom.current().nextLong(); @@ -65,7 +79,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * Repeated calls to nextBoolean produce at least one different result + * Repeated calls to nextBoolean produce at least two distinct results */ public void testNextBoolean() { boolean f = ThreadLocalRandom.current().nextBoolean(); @@ -76,7 +90,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * Repeated calls to nextFloat produce at least one different result + * Repeated calls to nextFloat produce at least two distinct results */ public void testNextFloat() { float f = ThreadLocalRandom.current().nextFloat(); @@ -87,18 +101,18 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * Repeated calls to nextDouble produce at least one different result + * Repeated calls to nextDouble produce at least two distinct results */ public void testNextDouble() { double f = ThreadLocalRandom.current().nextDouble(); - double i = 0; + int i = 0; while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f) ++i; assertTrue(i < NCALLS); } /** - * Repeated calls to nextGaussian produce at least one different result + * Repeated calls to nextGaussian produce at least two distinct results */ public void testNextGaussian() { double f = ThreadLocalRandom.current().nextGaussian(); @@ -109,28 +123,39 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * nextInt(negative) throws IllegalArgumentException; + * nextInt(non-positive) throws IllegalArgumentException */ - public void testNextIntBoundedNeg() { - try { - int f = ThreadLocalRandom.current().nextInt(-17); - shouldThrow(); - } catch (IllegalArgumentException success) {} + public void testNextIntBoundNonPositive() { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (int bound : new int[] { 0, -17, Integer.MIN_VALUE }) { + try { + rnd.nextInt(bound); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } } /** - * nextInt(least >= bound) throws IllegalArgumentException; + * nextInt(least >= bound) throws IllegalArgumentException */ public void testNextIntBadBounds() { - try { - int f = ThreadLocalRandom.current().nextInt(17, 2); - shouldThrow(); - } catch (IllegalArgumentException success) {} + int[][] badBoundss = { + { 17, 2 }, + { -42, -42 }, + { Integer.MAX_VALUE, Integer.MIN_VALUE }, + }; + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (int[] badBounds : badBoundss) { + try { + rnd.nextInt(badBounds[0], badBounds[1]); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } } /** * nextInt(bound) returns 0 <= value < bound; - * repeated calls produce at least one different result + * repeated calls produce at least two distinct results */ public void testNextIntBounded() { // sample bound space across prime number increments @@ -150,7 +175,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { /** * nextInt(least, bound) returns least <= value < bound; - * repeated calls produce at least one different result + * repeated calls produce at least two distinct results */ public void testNextIntBounded2() { for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) { @@ -170,28 +195,39 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** - * nextLong(negative) throws IllegalArgumentException; + * nextLong(non-positive) throws IllegalArgumentException */ - public void testNextLongBoundedNeg() { - try { - long f = ThreadLocalRandom.current().nextLong(-17); - shouldThrow(); - } catch (IllegalArgumentException success) {} + public void testNextLongBoundNonPositive() { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (long bound : new long[] { 0L, -17L, Long.MIN_VALUE }) { + try { + rnd.nextLong(bound); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } } /** - * nextLong(least >= bound) throws IllegalArgumentException; + * nextLong(least >= bound) throws IllegalArgumentException */ public void testNextLongBadBounds() { - try { - long f = ThreadLocalRandom.current().nextLong(17, 2); - shouldThrow(); - } catch (IllegalArgumentException success) {} + long[][] badBoundss = { + { 17L, 2L }, + { -42L, -42L }, + { Long.MAX_VALUE, Long.MIN_VALUE }, + }; + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (long[] badBounds : badBoundss) { + try { + rnd.nextLong(badBounds[0], badBounds[1]); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } } /** * nextLong(bound) returns 0 <= value < bound; - * repeated calls produce at least one different result + * repeated calls produce at least two distinct results */ public void testNextLongBounded() { for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) { @@ -210,7 +246,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { /** * nextLong(least, bound) returns least <= value < bound; - * repeated calls produce at least one different result + * repeated calls produce at least two distinct results */ public void testNextLongBounded2() { for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) { @@ -230,8 +266,28 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } /** + * nextDouble(non-positive) throws IllegalArgumentException + */ + public void testNextDoubleBoundNonPositive() { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + double[] badBounds = { + 0.0d, + -17.0d, + -Double.MIN_VALUE, + Double.NEGATIVE_INFINITY, + Double.NaN, + }; + for (double bound : badBounds) { + try { + rnd.nextDouble(bound); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + } + + /** * nextDouble(least, bound) returns least <= value < bound; - * repeated calls produce at least one different result + * repeated calls produce at least two distinct results */ public void testNextDoubleBounded2() { for (double least = 0.0001; least < 1.0e20; least *= 8) { @@ -263,7 +319,7 @@ public class ThreadLocalRandomTest extends JSR166TestCase { long firstRand = 0; ThreadLocalRandom firstThreadLocalRandom = null; - final CheckedRunnable getRandomState = new CheckedRunnable() { + Runnable getRandomState = new CheckedRunnable() { public void realRun() { ThreadLocalRandom current = ThreadLocalRandom.current(); assertSame(current, ThreadLocalRandom.current()); diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java index 885c2b2..7f5f072 100644 --- a/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java +++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java @@ -8,10 +8,19 @@ package jsr166; -import junit.framework.*; -import java.util.concurrent.Semaphore; +import junit.framework.Test; +import junit.framework.TestSuite; public class ThreadLocalTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() { public Integer initialValue() { @@ -85,7 +94,7 @@ public class ThreadLocalTest extends JSR166TestCase { */ public void testGenericITL() throws InterruptedException { final int threadCount = 10; - final int x[] = new int[threadCount]; + final int[] x = new int[threadCount]; Thread progenitor = new ITLThread(x); progenitor.start(); progenitor.join(); diff --git a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java index f16f422..5f38d39 100644 --- a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java +++ b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java @@ -8,14 +8,44 @@ package jsr166; -import junit.framework.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; -import java.util.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ThreadPoolExecutorSubclassTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class CustomTask<V> implements RunnableFuture<V> { final Callable<V> callable; @@ -33,7 +63,7 @@ public class ThreadPoolExecutorSubclassTest extends JSR166TestCase { CustomTask(final Runnable r, final V res) { if (r == null) throw new NullPointerException(); callable = new Callable<V>() { - public V call() throws Exception { r.run(); return res; }}; + public V call() throws Exception { r.run(); return res; }}; } public boolean isDone() { lock.lock(); try { return done; } finally { lock.unlock() ; } @@ -1244,11 +1274,10 @@ public class ThreadPoolExecutorSubclassTest extends JSR166TestCase { CustomTPE p = new CustomTPE(); try { final CountDownLatch done = new CountDownLatch(1); - final CheckedRunnable task = new CheckedRunnable() { + p.execute(new CheckedRunnable() { public void realRun() { done.countDown(); - }}; - p.execute(task); + }}); await(p.afterCalled); assertEquals(0, done.getCount()); assertTrue(p.afterCalled()); diff --git a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java index 55f769b..52a7002 100644 --- a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java +++ b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java @@ -8,13 +8,41 @@ package jsr166; -import junit.framework.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import java.util.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ThreadPoolExecutorTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class ExtendedTPE extends ThreadPoolExecutor { final CountDownLatch beforeCalled = new CountDownLatch(1); @@ -1371,11 +1399,10 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { ExtendedTPE p = new ExtendedTPE(); try { final CountDownLatch done = new CountDownLatch(1); - final CheckedRunnable task = new CheckedRunnable() { + p.execute(new CheckedRunnable() { public void realRun() { done.countDown(); - }}; - p.execute(task); + }}); await(p.afterCalled); assertEquals(0, done.getCount()); assertTrue(p.afterCalled()); diff --git a/jsr166-tests/src/test/java/jsr166/ThreadTest.java b/jsr166-tests/src/test/java/jsr166/ThreadTest.java index 12c2f8a..27f22ca 100644 --- a/jsr166-tests/src/test/java/jsr166/ThreadTest.java +++ b/jsr166-tests/src/test/java/jsr166/ThreadTest.java @@ -8,9 +8,19 @@ package jsr166; -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestSuite; public class ThreadTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class MyHandler implements Thread.UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { @@ -28,11 +38,14 @@ public class ThreadTest extends JSR166TestCase { Thread current = Thread.currentThread(); ThreadGroup tg = current.getThreadGroup(); MyHandler eh = new MyHandler(); - assertEquals(tg, current.getUncaughtExceptionHandler()); + assertSame(tg, current.getUncaughtExceptionHandler()); current.setUncaughtExceptionHandler(eh); - assertEquals(eh, current.getUncaughtExceptionHandler()); - current.setUncaughtExceptionHandler(null); - assertEquals(tg, current.getUncaughtExceptionHandler()); + try { + assertSame(eh, current.getUncaughtExceptionHandler()); + } finally { + current.setUncaughtExceptionHandler(null); + } + assertSame(tg, current.getUncaughtExceptionHandler()); } /** @@ -40,24 +53,27 @@ public class ThreadTest extends JSR166TestCase { * setDefaultUncaughtExceptionHandler. */ public void testGetAndSetDefaultUncaughtExceptionHandler() { - // BEGIN android-remove (when running as cts the RuntimeInit will - // set a default handler) + // android-note: Removed assertion; all "normal" android apps (including CTS tests) have a + // default uncaught exception handler installed by the framework. + // // assertEquals(null, Thread.getDefaultUncaughtExceptionHandler()); - // END android-remove // failure due to securityException is OK. // Would be nice to explicitly test both ways, but cannot yet. + Thread.UncaughtExceptionHandler defaultHandler + = Thread.getDefaultUncaughtExceptionHandler(); + MyHandler eh = new MyHandler(); try { - Thread current = Thread.currentThread(); - ThreadGroup tg = current.getThreadGroup(); - MyHandler eh = new MyHandler(); Thread.setDefaultUncaughtExceptionHandler(eh); - assertEquals(eh, Thread.getDefaultUncaughtExceptionHandler()); - Thread.setDefaultUncaughtExceptionHandler(null); - } - catch (SecurityException ok) { + try { + assertSame(eh, Thread.getDefaultUncaughtExceptionHandler()); + } finally { + Thread.setDefaultUncaughtExceptionHandler(defaultHandler); + } + } catch (SecurityException ok) { + assertNotNull(System.getSecurityManager()); } - assertEquals(null, Thread.getDefaultUncaughtExceptionHandler()); + assertSame(defaultHandler, Thread.getDefaultUncaughtExceptionHandler()); } // How to test actually using UEH within junit? diff --git a/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java b/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java index 7fa9e1a..2c9529b 100644 --- a/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java +++ b/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java @@ -8,11 +8,30 @@ package jsr166; -import junit.framework.*; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import junit.framework.Test; +import junit.framework.TestSuite; + public class TimeUnitTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } // (loops to 88888 check increments at all time divisions.) @@ -22,92 +41,64 @@ public class TimeUnitTest extends JSR166TestCase { public void testConvert() { for (long t = 0; t < 88888; ++t) { assertEquals(t*60*60*24, - TimeUnit.SECONDS.convert(t, - TimeUnit.DAYS)); + SECONDS.convert(t, DAYS)); assertEquals(t*60*60, - TimeUnit.SECONDS.convert(t, - TimeUnit.HOURS)); + SECONDS.convert(t, HOURS)); assertEquals(t*60, - TimeUnit.SECONDS.convert(t, - TimeUnit.MINUTES)); + SECONDS.convert(t, MINUTES)); assertEquals(t, - TimeUnit.SECONDS.convert(t, - TimeUnit.SECONDS)); + SECONDS.convert(t, SECONDS)); assertEquals(t, - TimeUnit.SECONDS.convert(1000L*t, - TimeUnit.MILLISECONDS)); + SECONDS.convert(1000L*t, MILLISECONDS)); assertEquals(t, - TimeUnit.SECONDS.convert(1000000L*t, - TimeUnit.MICROSECONDS)); + SECONDS.convert(1000000L*t, MICROSECONDS)); assertEquals(t, - TimeUnit.SECONDS.convert(1000000000L*t, - TimeUnit.NANOSECONDS)); + SECONDS.convert(1000000000L*t, NANOSECONDS)); assertEquals(1000L*t*60*60*24, - TimeUnit.MILLISECONDS.convert(t, - TimeUnit.DAYS)); + MILLISECONDS.convert(t, DAYS)); assertEquals(1000L*t*60*60, - TimeUnit.MILLISECONDS.convert(t, - TimeUnit.HOURS)); + MILLISECONDS.convert(t, HOURS)); assertEquals(1000L*t*60, - TimeUnit.MILLISECONDS.convert(t, - TimeUnit.MINUTES)); + MILLISECONDS.convert(t, MINUTES)); assertEquals(1000L*t, - TimeUnit.MILLISECONDS.convert(t, - TimeUnit.SECONDS)); + MILLISECONDS.convert(t, SECONDS)); assertEquals(t, - TimeUnit.MILLISECONDS.convert(t, - TimeUnit.MILLISECONDS)); + MILLISECONDS.convert(t, MILLISECONDS)); assertEquals(t, - TimeUnit.MILLISECONDS.convert(1000L*t, - TimeUnit.MICROSECONDS)); + MILLISECONDS.convert(1000L*t, MICROSECONDS)); assertEquals(t, - TimeUnit.MILLISECONDS.convert(1000000L*t, - TimeUnit.NANOSECONDS)); + MILLISECONDS.convert(1000000L*t, NANOSECONDS)); assertEquals(1000000L*t*60*60*24, - TimeUnit.MICROSECONDS.convert(t, - TimeUnit.DAYS)); + MICROSECONDS.convert(t, DAYS)); assertEquals(1000000L*t*60*60, - TimeUnit.MICROSECONDS.convert(t, - TimeUnit.HOURS)); + MICROSECONDS.convert(t, HOURS)); assertEquals(1000000L*t*60, - TimeUnit.MICROSECONDS.convert(t, - TimeUnit.MINUTES)); + MICROSECONDS.convert(t, MINUTES)); assertEquals(1000000L*t, - TimeUnit.MICROSECONDS.convert(t, - TimeUnit.SECONDS)); + MICROSECONDS.convert(t, SECONDS)); assertEquals(1000L*t, - TimeUnit.MICROSECONDS.convert(t, - TimeUnit.MILLISECONDS)); + MICROSECONDS.convert(t, MILLISECONDS)); assertEquals(t, - TimeUnit.MICROSECONDS.convert(t, - TimeUnit.MICROSECONDS)); + MICROSECONDS.convert(t, MICROSECONDS)); assertEquals(t, - TimeUnit.MICROSECONDS.convert(1000L*t, - TimeUnit.NANOSECONDS)); + MICROSECONDS.convert(1000L*t, NANOSECONDS)); assertEquals(1000000000L*t*60*60*24, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.DAYS)); + NANOSECONDS.convert(t, DAYS)); assertEquals(1000000000L*t*60*60, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.HOURS)); + NANOSECONDS.convert(t, HOURS)); assertEquals(1000000000L*t*60, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.MINUTES)); + NANOSECONDS.convert(t, MINUTES)); assertEquals(1000000000L*t, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.SECONDS)); + NANOSECONDS.convert(t, SECONDS)); assertEquals(1000000L*t, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.MILLISECONDS)); + NANOSECONDS.convert(t, MILLISECONDS)); assertEquals(1000L*t, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.MICROSECONDS)); + NANOSECONDS.convert(t, MICROSECONDS)); assertEquals(t, - TimeUnit.NANOSECONDS.convert(t, - TimeUnit.NANOSECONDS)); + NANOSECONDS.convert(t, NANOSECONDS)); } } @@ -118,19 +109,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToNanos() { for (long t = 0; t < 88888; ++t) { assertEquals(t*1000000000L*60*60*24, - TimeUnit.DAYS.toNanos(t)); + DAYS.toNanos(t)); assertEquals(t*1000000000L*60*60, - TimeUnit.HOURS.toNanos(t)); + HOURS.toNanos(t)); assertEquals(t*1000000000L*60, - TimeUnit.MINUTES.toNanos(t)); + MINUTES.toNanos(t)); assertEquals(1000000000L*t, - TimeUnit.SECONDS.toNanos(t)); + SECONDS.toNanos(t)); assertEquals(1000000L*t, - TimeUnit.MILLISECONDS.toNanos(t)); + MILLISECONDS.toNanos(t)); assertEquals(1000L*t, - TimeUnit.MICROSECONDS.toNanos(t)); + MICROSECONDS.toNanos(t)); assertEquals(t, - TimeUnit.NANOSECONDS.toNanos(t)); + NANOSECONDS.toNanos(t)); } } @@ -141,19 +132,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToMicros() { for (long t = 0; t < 88888; ++t) { assertEquals(t*1000000L*60*60*24, - TimeUnit.DAYS.toMicros(t)); + DAYS.toMicros(t)); assertEquals(t*1000000L*60*60, - TimeUnit.HOURS.toMicros(t)); + HOURS.toMicros(t)); assertEquals(t*1000000L*60, - TimeUnit.MINUTES.toMicros(t)); + MINUTES.toMicros(t)); assertEquals(1000000L*t, - TimeUnit.SECONDS.toMicros(t)); + SECONDS.toMicros(t)); assertEquals(1000L*t, - TimeUnit.MILLISECONDS.toMicros(t)); + MILLISECONDS.toMicros(t)); assertEquals(t, - TimeUnit.MICROSECONDS.toMicros(t)); + MICROSECONDS.toMicros(t)); assertEquals(t, - TimeUnit.NANOSECONDS.toMicros(t*1000L)); + NANOSECONDS.toMicros(t*1000L)); } } @@ -164,19 +155,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToMillis() { for (long t = 0; t < 88888; ++t) { assertEquals(t*1000L*60*60*24, - TimeUnit.DAYS.toMillis(t)); + DAYS.toMillis(t)); assertEquals(t*1000L*60*60, - TimeUnit.HOURS.toMillis(t)); + HOURS.toMillis(t)); assertEquals(t*1000L*60, - TimeUnit.MINUTES.toMillis(t)); + MINUTES.toMillis(t)); assertEquals(1000L*t, - TimeUnit.SECONDS.toMillis(t)); + SECONDS.toMillis(t)); assertEquals(t, - TimeUnit.MILLISECONDS.toMillis(t)); + MILLISECONDS.toMillis(t)); assertEquals(t, - TimeUnit.MICROSECONDS.toMillis(t*1000L)); + MICROSECONDS.toMillis(t*1000L)); assertEquals(t, - TimeUnit.NANOSECONDS.toMillis(t*1000000L)); + NANOSECONDS.toMillis(t*1000000L)); } } @@ -187,19 +178,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToSeconds() { for (long t = 0; t < 88888; ++t) { assertEquals(t*60*60*24, - TimeUnit.DAYS.toSeconds(t)); + DAYS.toSeconds(t)); assertEquals(t*60*60, - TimeUnit.HOURS.toSeconds(t)); + HOURS.toSeconds(t)); assertEquals(t*60, - TimeUnit.MINUTES.toSeconds(t)); + MINUTES.toSeconds(t)); assertEquals(t, - TimeUnit.SECONDS.toSeconds(t)); + SECONDS.toSeconds(t)); assertEquals(t, - TimeUnit.MILLISECONDS.toSeconds(t*1000L)); + MILLISECONDS.toSeconds(t*1000L)); assertEquals(t, - TimeUnit.MICROSECONDS.toSeconds(t*1000000L)); + MICROSECONDS.toSeconds(t*1000000L)); assertEquals(t, - TimeUnit.NANOSECONDS.toSeconds(t*1000000000L)); + NANOSECONDS.toSeconds(t*1000000000L)); } } @@ -210,19 +201,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToMinutes() { for (long t = 0; t < 88888; ++t) { assertEquals(t*60*24, - TimeUnit.DAYS.toMinutes(t)); + DAYS.toMinutes(t)); assertEquals(t*60, - TimeUnit.HOURS.toMinutes(t)); + HOURS.toMinutes(t)); assertEquals(t, - TimeUnit.MINUTES.toMinutes(t)); + MINUTES.toMinutes(t)); assertEquals(t, - TimeUnit.SECONDS.toMinutes(t*60)); + SECONDS.toMinutes(t*60)); assertEquals(t, - TimeUnit.MILLISECONDS.toMinutes(t*1000L*60)); + MILLISECONDS.toMinutes(t*1000L*60)); assertEquals(t, - TimeUnit.MICROSECONDS.toMinutes(t*1000000L*60)); + MICROSECONDS.toMinutes(t*1000000L*60)); assertEquals(t, - TimeUnit.NANOSECONDS.toMinutes(t*1000000000L*60)); + NANOSECONDS.toMinutes(t*1000000000L*60)); } } @@ -233,19 +224,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToHours() { for (long t = 0; t < 88888; ++t) { assertEquals(t*24, - TimeUnit.DAYS.toHours(t)); + DAYS.toHours(t)); assertEquals(t, - TimeUnit.HOURS.toHours(t)); + HOURS.toHours(t)); assertEquals(t, - TimeUnit.MINUTES.toHours(t*60)); + MINUTES.toHours(t*60)); assertEquals(t, - TimeUnit.SECONDS.toHours(t*60*60)); + SECONDS.toHours(t*60*60)); assertEquals(t, - TimeUnit.MILLISECONDS.toHours(t*1000L*60*60)); + MILLISECONDS.toHours(t*1000L*60*60)); assertEquals(t, - TimeUnit.MICROSECONDS.toHours(t*1000000L*60*60)); + MICROSECONDS.toHours(t*1000000L*60*60)); assertEquals(t, - TimeUnit.NANOSECONDS.toHours(t*1000000000L*60*60)); + NANOSECONDS.toHours(t*1000000000L*60*60)); } } @@ -256,19 +247,19 @@ public class TimeUnitTest extends JSR166TestCase { public void testToDays() { for (long t = 0; t < 88888; ++t) { assertEquals(t, - TimeUnit.DAYS.toDays(t)); + DAYS.toDays(t)); assertEquals(t, - TimeUnit.HOURS.toDays(t*24)); + HOURS.toDays(t*24)); assertEquals(t, - TimeUnit.MINUTES.toDays(t*60*24)); + MINUTES.toDays(t*60*24)); assertEquals(t, - TimeUnit.SECONDS.toDays(t*60*60*24)); + SECONDS.toDays(t*60*60*24)); assertEquals(t, - TimeUnit.MILLISECONDS.toDays(t*1000L*60*60*24)); + MILLISECONDS.toDays(t*1000L*60*60*24)); assertEquals(t, - TimeUnit.MICROSECONDS.toDays(t*1000000L*60*60*24)); + MICROSECONDS.toDays(t*1000000L*60*60*24)); assertEquals(t, - TimeUnit.NANOSECONDS.toDays(t*1000000000L*60*60*24)); + NANOSECONDS.toDays(t*1000000000L*60*60*24)); } } @@ -278,29 +269,21 @@ public class TimeUnitTest extends JSR166TestCase { */ public void testConvertSaturate() { assertEquals(Long.MAX_VALUE, - TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2, - TimeUnit.SECONDS)); + NANOSECONDS.convert(Long.MAX_VALUE / 2, SECONDS)); assertEquals(Long.MIN_VALUE, - TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4, - TimeUnit.SECONDS)); + NANOSECONDS.convert(-Long.MAX_VALUE / 4, SECONDS)); assertEquals(Long.MAX_VALUE, - TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2, - TimeUnit.MINUTES)); + NANOSECONDS.convert(Long.MAX_VALUE / 2, MINUTES)); assertEquals(Long.MIN_VALUE, - TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4, - TimeUnit.MINUTES)); + NANOSECONDS.convert(-Long.MAX_VALUE / 4, MINUTES)); assertEquals(Long.MAX_VALUE, - TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2, - TimeUnit.HOURS)); + NANOSECONDS.convert(Long.MAX_VALUE / 2, HOURS)); assertEquals(Long.MIN_VALUE, - TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4, - TimeUnit.HOURS)); + NANOSECONDS.convert(-Long.MAX_VALUE / 4, HOURS)); assertEquals(Long.MAX_VALUE, - TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2, - TimeUnit.DAYS)); + NANOSECONDS.convert(Long.MAX_VALUE / 2, DAYS)); assertEquals(Long.MIN_VALUE, - TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4, - TimeUnit.DAYS)); + NANOSECONDS.convert(-Long.MAX_VALUE / 4, DAYS)); } /** @@ -309,23 +292,23 @@ public class TimeUnitTest extends JSR166TestCase { */ public void testToNanosSaturate() { assertEquals(Long.MAX_VALUE, - TimeUnit.MILLISECONDS.toNanos(Long.MAX_VALUE / 2)); + MILLISECONDS.toNanos(Long.MAX_VALUE / 2)); assertEquals(Long.MIN_VALUE, - TimeUnit.MILLISECONDS.toNanos(-Long.MAX_VALUE / 3)); + MILLISECONDS.toNanos(-Long.MAX_VALUE / 3)); } /** * toString returns name of unit */ public void testToString() { - assertEquals("SECONDS", TimeUnit.SECONDS.toString()); + assertEquals("SECONDS", SECONDS.toString()); } /** * name returns name of unit */ public void testName() { - assertEquals("SECONDS", TimeUnit.SECONDS.name()); + assertEquals("SECONDS", SECONDS.name()); } /** @@ -336,7 +319,7 @@ public class TimeUnitTest extends JSR166TestCase { Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { Object o = new Object(); - TimeUnit tu = TimeUnit.MILLISECONDS; + TimeUnit tu = MILLISECONDS; try { tu.timedWait(o, LONG_DELAY_MS); @@ -355,7 +338,7 @@ public class TimeUnitTest extends JSR166TestCase { Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { Object o = new Object(); - TimeUnit tu = TimeUnit.MILLISECONDS; + TimeUnit tu = MILLISECONDS; Thread.currentThread().interrupt(); try { @@ -393,7 +376,7 @@ public class TimeUnitTest extends JSR166TestCase { }}); final Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - TimeUnit tu = TimeUnit.MILLISECONDS; + TimeUnit tu = MILLISECONDS; Thread.currentThread().interrupt(); try { tu.timedJoin(s, LONG_DELAY_MS); @@ -424,7 +407,7 @@ public class TimeUnitTest extends JSR166TestCase { final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - TimeUnit tu = TimeUnit.MILLISECONDS; + TimeUnit tu = MILLISECONDS; Thread.currentThread().interrupt(); try { tu.sleep(LONG_DELAY_MS); @@ -450,7 +433,7 @@ public class TimeUnitTest extends JSR166TestCase { * a deserialized serialized unit is the same instance */ public void testSerialization() throws Exception { - TimeUnit x = TimeUnit.MILLISECONDS; + TimeUnit x = MILLISECONDS; assertSame(x, serialClone(x)); } diff --git a/jsr166-tests/src/test/java/jsr166/TreeMapTest.java b/jsr166-tests/src/test/java/jsr166/TreeMapTest.java index 87baa1a..afc73de 100644 --- a/jsr166-tests/src/test/java/jsr166/TreeMapTest.java +++ b/jsr166-tests/src/test/java/jsr166/TreeMapTest.java @@ -6,10 +6,31 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; +import java.util.TreeMap; + +import junit.framework.Test; +import junit.framework.TestSuite; public class TreeMapTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new map from Integers 1-5 to Strings "A"-"E". @@ -559,8 +580,8 @@ public class TreeMapTest extends JSR166TestCase { * get(null) of nonempty map throws NPE */ public void testGet_NullPointerException() { + TreeMap c = map5(); try { - TreeMap c = map5(); c.get(null); shouldThrow(); } catch (NullPointerException success) {} @@ -570,8 +591,8 @@ public class TreeMapTest extends JSR166TestCase { * containsKey(null) of nonempty map throws NPE */ public void testContainsKey_NullPointerException() { + TreeMap c = map5(); try { - TreeMap c = map5(); c.containsKey(null); shouldThrow(); } catch (NullPointerException success) {} @@ -581,9 +602,9 @@ public class TreeMapTest extends JSR166TestCase { * remove(null) throws NPE for nonempty map */ public void testRemove1_NullPointerException() { + TreeMap c = new TreeMap(); + c.put("sadsdf", "asdads"); try { - TreeMap c = new TreeMap(); - c.put("sadsdf", "asdads"); c.remove(null); shouldThrow(); } catch (NullPointerException success) {} @@ -819,7 +840,7 @@ public class TreeMapTest extends JSR166TestCase { // Add entries till we're back to original size while (map.size() < size) { int key = min + rnd.nextInt(rangeSize); - assertTrue(key >= min && key<= max); + assertTrue(key >= min && key <= max); put(map, key); } } @@ -844,7 +865,7 @@ public class TreeMapTest extends JSR166TestCase { // Add entries till we're back to original size while (map.size() < size) { int key = min - 5 + rnd.nextInt(rangeSize + 10); - if (key >= min && key<= max) { + if (key >= min && key <= max) { put(map, key); } else { try { diff --git a/jsr166-tests/src/test/java/jsr166/TreeSetTest.java b/jsr166-tests/src/test/java/jsr166/TreeSetTest.java index 2957019..a935637 100644 --- a/jsr166-tests/src/test/java/jsr166/TreeSetTest.java +++ b/jsr166-tests/src/test/java/jsr166/TreeSetTest.java @@ -6,7 +6,6 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; @@ -19,7 +18,19 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import junit.framework.Test; +import junit.framework.TestSuite; + public class TreeSetTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class MyReverseComparator implements Comparator { public int compare(Object x, Object y) { @@ -39,9 +50,9 @@ public class TreeSetTest extends JSR166TestCase { private TreeSet<Integer> populatedSet(int n) { TreeSet<Integer> q = new TreeSet<Integer>(); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.add(new Integer(i))); assertFalse(q.isEmpty()); assertEquals(n, q.size()); @@ -75,7 +86,7 @@ public class TreeSetTest extends JSR166TestCase { */ public void testConstructor3() { try { - TreeSet q = new TreeSet((Collection)null); + new TreeSet((Collection)null); shouldThrow(); } catch (NullPointerException success) {} } @@ -86,7 +97,7 @@ public class TreeSetTest extends JSR166TestCase { public void testConstructor4() { try { Integer[] ints = new Integer[SIZE]; - TreeSet q = new TreeSet(Arrays.asList(ints)); + new TreeSet(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -99,7 +110,7 @@ public class TreeSetTest extends JSR166TestCase { Integer[] ints = new Integer[SIZE]; for (int i = 0; i < SIZE-1; ++i) ints[i] = new Integer(i); - TreeSet q = new TreeSet(Arrays.asList(ints)); + new TreeSet(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} } @@ -164,8 +175,8 @@ public class TreeSetTest extends JSR166TestCase { * add(null) throws NPE if nonempty */ public void testAddNull() { + TreeSet q = populatedSet(SIZE); try { - TreeSet q = populatedSet(SIZE); q.add(null); shouldThrow(); } catch (NullPointerException success) {} @@ -193,9 +204,8 @@ public class TreeSetTest extends JSR166TestCase { * Add of non-Comparable throws CCE */ public void testAddNonComparable() { + TreeSet q = new TreeSet(); try { - TreeSet q = new TreeSet(); - q.add(new Object()); q.add(new Object()); q.add(new Object()); shouldThrow(); @@ -206,8 +216,8 @@ public class TreeSetTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testAddAll1() { + TreeSet q = new TreeSet(); try { - TreeSet q = new TreeSet(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -217,9 +227,9 @@ public class TreeSetTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testAddAll2() { + TreeSet q = new TreeSet(); + Integer[] ints = new Integer[SIZE]; try { - TreeSet q = new TreeSet(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -230,11 +240,11 @@ public class TreeSetTest extends JSR166TestCase { * possibly adding some elements */ public void testAddAll3() { + TreeSet q = new TreeSet(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i); try { - TreeSet q = new TreeSet(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -282,13 +292,13 @@ public class TreeSetTest extends JSR166TestCase { */ public void testRemoveElement() { TreeSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -367,8 +377,8 @@ public class TreeSetTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.pollFirst()); + assertFalse(q.contains(x)); } } } @@ -472,27 +482,19 @@ public class TreeSetTest extends JSR166TestCase { */ public void testIterator() { TreeSet q = populatedSet(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); } /** * iterator of empty set has no elements */ public void testEmptyIterator() { - TreeSet q = new TreeSet(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); + assertIteratorExhausted(new TreeSet().iterator()); } /** @@ -732,7 +734,7 @@ public class TreeSetTest extends JSR166TestCase { // Add entries till we're back to original size while (set.size() < size) { int element = min + rnd.nextInt(rangeSize); - assertTrue(element >= min && element<= max); + assertTrue(element >= min && element <= max); put(set, element); } } @@ -757,7 +759,7 @@ public class TreeSetTest extends JSR166TestCase { // Add entries till we're back to original size while (set.size() < size) { int element = min - 5 + rnd.nextInt(rangeSize + 10); - if (element >= min && element<= max) { + if (element >= min && element <= max) { put(set, element); } else { try { diff --git a/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java b/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java index 17201f3..18a9e37 100644 --- a/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java +++ b/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java @@ -6,10 +6,29 @@ package jsr166; -import junit.framework.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +import junit.framework.Test; +import junit.framework.TestSuite; public class TreeSubMapTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } /** * Returns a new map from Integers 1-5 to Strings "A"-"E". @@ -378,8 +397,8 @@ public class TreeSubMapTest extends JSR166TestCase { * get(null) of nonempty map throws NPE */ public void testGet_NullPointerException() { + NavigableMap c = map5(); try { - NavigableMap c = map5(); c.get(null); shouldThrow(); } catch (NullPointerException success) {} @@ -389,8 +408,8 @@ public class TreeSubMapTest extends JSR166TestCase { * containsKey(null) of nonempty map throws NPE */ public void testContainsKey_NullPointerException() { + NavigableMap c = map5(); try { - NavigableMap c = map5(); c.containsKey(null); shouldThrow(); } catch (NullPointerException success) {} @@ -400,8 +419,8 @@ public class TreeSubMapTest extends JSR166TestCase { * put(null,x) throws NPE */ public void testPut1_NullPointerException() { + NavigableMap c = map5(); try { - NavigableMap c = map5(); c.put(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} @@ -411,8 +430,8 @@ public class TreeSubMapTest extends JSR166TestCase { * remove(null) throws NPE */ public void testRemove1_NullPointerException() { + NavigableMap c = map5(); try { - NavigableMap c = map5(); c.remove(null); shouldThrow(); } catch (NullPointerException success) {} @@ -927,8 +946,8 @@ public class TreeSubMapTest extends JSR166TestCase { * get(null) of nonempty map throws NPE */ public void testDescendingGet_NullPointerException() { + NavigableMap c = dmap5(); try { - NavigableMap c = dmap5(); c.get(null); shouldThrow(); } catch (NullPointerException success) {} @@ -938,8 +957,8 @@ public class TreeSubMapTest extends JSR166TestCase { * put(null,x) throws NPE */ public void testDescendingPut1_NullPointerException() { + NavigableMap c = dmap5(); try { - NavigableMap c = dmap5(); c.put(null, "whatever"); shouldThrow(); } catch (NullPointerException success) {} diff --git a/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java b/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java index ba61748..5398c4e 100644 --- a/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java +++ b/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java @@ -6,16 +6,27 @@ package jsr166; -import junit.framework.*; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.NavigableSet; -import java.util.SortedSet; import java.util.Set; +import java.util.SortedSet; import java.util.TreeSet; +import junit.framework.Test; +import junit.framework.TestSuite; + public class TreeSubSetTest extends JSR166TestCase { + // android-note: Removed because the CTS runner does a bad job of + // retrying tests that have suite() declarations. + // + // public static void main(String[] args) { + // main(suite(), args); + // } + // public static Test suite() { + // return new TestSuite(...); + // } static class MyReverseComparator implements Comparator { public int compare(Object x, Object y) { @@ -31,9 +42,9 @@ public class TreeSubSetTest extends JSR166TestCase { TreeSet<Integer> q = new TreeSet<Integer>(); assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) + for (int i = n-1; i >= 0; i -= 2) assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) + for (int i = (n & 1); i < n; i += 2) assertTrue(q.add(new Integer(i))); assertTrue(q.add(new Integer(-n))); assertTrue(q.add(new Integer(n))); @@ -126,8 +137,8 @@ public class TreeSubSetTest extends JSR166TestCase { * add(null) throws NPE */ public void testAddNull() { + NavigableSet q = set0(); try { - NavigableSet q = set0(); q.add(null); shouldThrow(); } catch (NullPointerException success) {} @@ -154,9 +165,8 @@ public class TreeSubSetTest extends JSR166TestCase { * Add of non-Comparable throws CCE */ public void testAddNonComparable() { + NavigableSet q = set0(); try { - NavigableSet q = set0(); - q.add(new Object()); q.add(new Object()); q.add(new Object()); shouldThrow(); @@ -167,8 +177,8 @@ public class TreeSubSetTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testAddAll1() { + NavigableSet q = set0(); try { - NavigableSet q = set0(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -178,9 +188,9 @@ public class TreeSubSetTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testAddAll2() { + NavigableSet q = set0(); + Integer[] ints = new Integer[SIZE]; try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -191,11 +201,11 @@ public class TreeSubSetTest extends JSR166TestCase { * possibly adding some elements */ public void testAddAll3() { + NavigableSet q = set0(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i+SIZE); try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -232,13 +242,13 @@ public class TreeSubSetTest extends JSR166TestCase { */ public void testRemoveElement() { NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); assertTrue(q.contains(i-1)); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.contains(i)); assertTrue(q.remove(i)); assertFalse(q.contains(i)); @@ -317,8 +327,8 @@ public class TreeSubSetTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.pollFirst()); + assertFalse(q.contains(x)); } } } @@ -422,27 +432,19 @@ public class TreeSubSetTest extends JSR166TestCase { */ public void testIterator() { NavigableSet q = populatedSet(SIZE); - int i = 0; Iterator it = q.iterator(); - while (it.hasNext()) { + int i; + for (i = 0; it.hasNext(); i++) assertTrue(q.contains(it.next())); - ++i; - } assertEquals(i, SIZE); + assertIteratorExhausted(it); } /** * iterator of empty set has no elements */ public void testEmptyIterator() { - NavigableSet q = set0(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); + assertIteratorExhausted(set0().iterator()); } /** @@ -648,9 +650,8 @@ public class TreeSubSetTest extends JSR166TestCase { * Add of non-Comparable throws CCE */ public void testDescendingAddNonComparable() { + NavigableSet q = dset0(); try { - NavigableSet q = dset0(); - q.add(new Object()); q.add(new Object()); q.add(new Object()); shouldThrow(); @@ -661,8 +662,8 @@ public class TreeSubSetTest extends JSR166TestCase { * addAll(null) throws NPE */ public void testDescendingAddAll1() { + NavigableSet q = dset0(); try { - NavigableSet q = dset0(); q.addAll(null); shouldThrow(); } catch (NullPointerException success) {} @@ -672,9 +673,9 @@ public class TreeSubSetTest extends JSR166TestCase { * addAll of a collection with null elements throws NPE */ public void testDescendingAddAll2() { + NavigableSet q = dset0(); + Integer[] ints = new Integer[SIZE]; try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -685,11 +686,11 @@ public class TreeSubSetTest extends JSR166TestCase { * possibly adding some elements */ public void testDescendingAddAll3() { + NavigableSet q = dset0(); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE-1; ++i) + ints[i] = new Integer(i+SIZE); try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); q.addAll(Arrays.asList(ints)); shouldThrow(); } catch (NullPointerException success) {} @@ -726,10 +727,10 @@ public class TreeSubSetTest extends JSR166TestCase { */ public void testDescendingRemoveElement() { NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { + for (int i = 1; i < SIZE; i += 2) { assertTrue(q.remove(new Integer(i))); } - for (int i = 0; i < SIZE; i+=2) { + for (int i = 0; i < SIZE; i += 2) { assertTrue(q.remove(new Integer(i))); assertFalse(q.remove(new Integer(i+1))); } @@ -805,8 +806,8 @@ public class TreeSubSetTest extends JSR166TestCase { assertTrue(q.removeAll(p)); assertEquals(SIZE-i, q.size()); for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); + Integer x = (Integer)(p.pollFirst()); + assertFalse(q.contains(x)); } } } diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java index b885ed2..aa3f154 100644 --- a/libart/src/main/java/dalvik/system/VMRuntime.java +++ b/libart/src/main/java/dalvik/system/VMRuntime.java @@ -16,6 +16,7 @@ package dalvik.system; +import java.lang.ref.FinalizerReference; import java.util.HashMap; import java.util.Map; @@ -301,6 +302,30 @@ public final class VMRuntime { */ public native void registerNativeFree(int bytes); + /** + * Wait for objects to be finalized. + * + * If finalization takes longer than timeout, then the function returns before all objects are + * finalized. + * + * @param timeout + * timeout in nanoseconds of the maximum time to wait until all pending finalizers + * are run. If timeout is 0, then there is no timeout. Note that the timeout does + * not stop the finalization process, it merely stops the wait. + * + * @see #Runtime.runFinalization() + * @see #wait(long,int) + */ + public static void runFinalization(long timeout) { + try { + FinalizerReference.finalizeAllEnqueued(timeout); + } catch (InterruptedException e) { + // Interrupt the current thread without actually throwing the InterruptionException + // for the caller. + Thread.currentThread().interrupt(); + } + } + public native void requestConcurrentGC(); public native void concurrentGC(); public native void requestHeapTrim(); diff --git a/luni/src/main/java/java/lang/AbstractStringBuilder.java b/libart/src/main/java/java/lang/AbstractStringBuilder.java index 4d84078..c8c8c5a 100644 --- a/luni/src/main/java/java/lang/AbstractStringBuilder.java +++ b/libart/src/main/java/java/lang/AbstractStringBuilder.java @@ -87,7 +87,7 @@ abstract class AbstractStringBuilder { count = string.length(); shared = false; value = new char[count + INITIAL_CAPACITY]; - string._getChars(0, count, value, 0); + string.getCharsNoCheck(0, count, value, 0); } private void enlargeBuffer(int min) { @@ -145,7 +145,7 @@ abstract class AbstractStringBuilder { if (newCount > value.length) { enlargeBuffer(newCount); } - string._getChars(0, length, value, count); + string.getCharsNoCheck(0, length, value, count); count = newCount; } @@ -167,7 +167,7 @@ abstract class AbstractStringBuilder { } if (s instanceof String) { - ((String) s)._getChars(start, end, value, count); + ((String) s).getCharsNoCheck(start, end, value, count); } else if (s instanceof AbstractStringBuilder) { AbstractStringBuilder other = (AbstractStringBuilder) s; System.arraycopy(other.value, start, value, count, length); @@ -345,7 +345,7 @@ abstract class AbstractStringBuilder { int min = string.length(); if (min != 0) { move(min, index); - string._getChars(0, min, value, index); + string.getCharsNoCheck(0, min, value, index); count += min; } } else { @@ -422,7 +422,7 @@ abstract class AbstractStringBuilder { value = value.clone(); shared = false; } - string._getChars(0, stringLength, value, start); + string.getCharsNoCheck(0, stringLength, value, start); count -= diff; return; } @@ -626,14 +626,7 @@ abstract class AbstractStringBuilder { if (count == 0) { return ""; } - // Optimize String sharing for more performance - int wasted = value.length - count; - if (wasted >= 256 - || (wasted >= INITIAL_CAPACITY && wasted >= (count >> 1))) { - return new String(value, 0, count); - } - shared = true; - return new String(0, count, value); + return StringFactory.newStringFromChars(0, count, value); } /** diff --git a/luni/src/main/java/java/lang/CaseMapper.java b/libart/src/main/java/java/lang/CaseMapper.java index 1da621c..f23a4ef 100644 --- a/luni/src/main/java/java/lang/CaseMapper.java +++ b/libart/src/main/java/java/lang/CaseMapper.java @@ -34,17 +34,15 @@ class CaseMapper { /** * Our current GC makes short-lived objects more expensive than we'd like. When that's fixed, * this class should be changed so that you instantiate it with the String and its value, - * offset, and count fields. + * and count fields. */ private CaseMapper() { } /** - * Implements String.toLowerCase. We need 's' so that we can return the original String instance - * if nothing changes. We need 'value', 'offset', and 'count' because they're not otherwise - * accessible. + * Implements String.toLowerCase. The original String instance is returned if nothing changes. */ - public static String toLowerCase(Locale locale, String s, char[] value, int offset, int count) { + public static String toLowerCase(Locale locale, String s) { // Punt hard cases to ICU4C. // Note that Greek isn't a particularly hard case for toLowerCase, only toUpperCase. String languageCode = locale.getLanguage(); @@ -52,29 +50,26 @@ class CaseMapper { return ICU.toLowerCase(s, locale); } - char[] newValue = null; - int newCount = 0; - for (int i = offset, end = offset + count; i < end; ++i) { - char ch = value[i]; + String newString = null; + for (int i = 0, end = s.length(); i < end; ++i) { + char ch = s.charAt(i); char newCh; if (ch == LATIN_CAPITAL_I_WITH_DOT || Character.isHighSurrogate(ch)) { // Punt these hard cases. return ICU.toLowerCase(s, locale); - } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(value, offset, count, i)) { + } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(s, i)) { newCh = GREEK_SMALL_FINAL_SIGMA; } else { newCh = Character.toLowerCase(ch); } - if (newValue == null && ch != newCh) { - newValue = new char[count]; // The result can't be longer than the input. - newCount = i - offset; - System.arraycopy(value, offset, newValue, 0, newCount); - } - if (newValue != null) { - newValue[newCount++] = newCh; + if (ch != newCh) { + if (newString == null) { + newString = StringFactory.newStringFromString(s); + } + newString.setCharAt(i, newCh); } } - return newValue != null ? new String(0, newCount, newValue) : s; + return newString != null ? newString : s; } /** @@ -82,20 +77,20 @@ class CaseMapper { * sequence, and 'index' is not followed by a sequence consisting of an ignorable sequence and * then a cased letter. */ - private static boolean isFinalSigma(char[] value, int offset, int count, int index) { + private static boolean isFinalSigma(String s, int index) { // TODO: we don't skip case-ignorable sequences like we should. // TODO: we should add a more direct way to test for a cased letter. - if (index <= offset) { + if (index <= 0) { return false; } - char previous = value[index - 1]; + char previous = s.charAt(index - 1); if (!(Character.isLowerCase(previous) || Character.isUpperCase(previous) || Character.isTitleCase(previous))) { return false; } - if (index + 1 >= offset + count) { + if (index + 1 >= s.length()) { return true; } - char next = value[index + 1]; + char next = s.charAt(index + 1); if (Character.isLowerCase(next) || Character.isUpperCase(next) || Character.isTitleCase(next)) { return false; } @@ -147,7 +142,7 @@ class CaseMapper { } }; - public static String toUpperCase(Locale locale, String s, char[] value, int offset, int count) { + public static String toUpperCase(Locale locale, String s, int count) { String languageCode = locale.getLanguage(); if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) { return ICU.toUpperCase(s, locale); @@ -157,9 +152,10 @@ class CaseMapper { } char[] output = null; + String newString = null; int i = 0; - for (int o = offset, end = offset + count; o < end; o++) { - char ch = value[o]; + for (int o = 0, end = count; o < end; o++) { + char ch = s.charAt(o); if (Character.isHighSurrogate(ch)) { return ICU.toUpperCase(s, locale); } @@ -171,23 +167,25 @@ class CaseMapper { output = newoutput; } char upch = Character.toUpperCase(ch); - if (ch != upch) { - if (output == null) { - output = new char[count]; - i = o - offset; - System.arraycopy(value, offset, output, 0, i); - } + if (output != null) { output[i++] = upch; - } else if (output != null) { - output[i++] = ch; + } else if (ch != upch) { + if (newString == null) { + newString = StringFactory.newStringFromString(s); + } + newString.setCharAt(o, upch); } } else { int target = index * 3; char val3 = upperValues[target + 2]; if (output == null) { output = new char[count + (count / 6) + 2]; - i = o - offset; - System.arraycopy(value, offset, output, 0, i); + i = o; + if (newString != null) { + System.arraycopy(newString.toCharArray(), 0, output, 0, i); + } else { + System.arraycopy(s.toCharArray(), 0, output, 0, i); + } } else if (i + (val3 == 0 ? 1 : 2) >= output.length) { char[] newoutput = new char[output.length + (count / 6) + 3]; System.arraycopy(output, 0, newoutput, 0, output.length); @@ -204,7 +202,11 @@ class CaseMapper { } } if (output == null) { - return s; + if (newString != null) { + return newString; + } else { + return s; + } } return output.length == i || output.length - i < 8 ? new String(0, i, output) : new String(output, 0, i); } diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java index 99c562f..fc6a0f8 100644 --- a/libart/src/main/java/java/lang/Class.java +++ b/libart/src/main/java/java/lang/Class.java @@ -39,7 +39,6 @@ import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.ArtMethod; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; @@ -141,9 +140,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe /** Short-cut to dexCache.strings */ private transient String[] dexCacheStrings; - /** static, private, and <init> methods. */ - private transient ArtMethod[] directMethods; - /** * The interface table (iftable_) contains pairs of a interface class and an array of the * interface methods. There is one pair per interface supported by this class. That @@ -169,20 +165,20 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe /** If class verify fails, we must return same error on subsequent tries. */ private transient Class<?> verifyErrorClass; - /** Virtual methods defined in this class; invoked through vtable. */ - private transient ArtMethod[] virtualMethods; - /** * Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass * is copied in, and virtual methods from our class either replace those from the super or are * appended. For abstract classes, methods may be created in the vtable that aren't in * virtual_ methods_ for miranda methods. */ - private transient ArtMethod[] vtable; + private transient Object vtable; /** access flags; low 16 bits are defined by VM spec */ private transient int accessFlags; + /** static, private, and <init> methods. */ + private transient long directMethods; + /** * Instance fields. These describe the layout of the contents of an Object. Note that only the * fields directly declared by this class are listed in iFields; fields declared by a @@ -196,6 +192,8 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe /** Static fields */ private transient long sFields; + /** Virtual methods defined in this class; invoked through vtable. */ + private transient long virtualMethods; /** * Total size of the Class instance; used when allocating storage on GC heap. @@ -222,6 +220,9 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe */ private transient volatile int dexTypeIndex; + /** Number of direct methods. */ + private transient int numDirectMethods; + /** Number of instance fields. */ private transient int numInstanceFields; @@ -234,6 +235,9 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe /** Number of static fields. */ private transient int numStaticFields; + /** Number of virtual methods. */ + private transient int numVirtualMethods; + /** * Total object size; used when allocating storage on GC heap. For interfaces and abstract * classes this will be zero. See also {@link Class#classSize}. @@ -1272,8 +1276,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe Object[] iftable = c.ifTable; if (iftable != null) { for (int i = 0; i < iftable.length; i += 2) { - Class<?> ifc = (Class<?>) iftable[i]; - if (ifc == this) { + if (iftable[i] == this) { return true; } } diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java index 43066e1..a6ac449 100644 --- a/libart/src/main/java/java/lang/Daemons.java +++ b/libart/src/main/java/java/lang/Daemons.java @@ -16,6 +16,8 @@ package java.lang; +import android.system.Os; +import android.system.OsConstants; import dalvik.system.VMRuntime; import java.lang.ref.FinalizerReference; import java.lang.ref.Reference; @@ -295,6 +297,14 @@ public final class Daemons { // 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); + // Sleep a few seconds to let the stack traces print. + Thread.sleep(5000); + } catch (Exception e) { + System.logE("failed to send SIGQUIT", e); + } if (h == null) { // If we have no handler, log and exit. System.logE(message, syntheticException); diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java index c047018..73e35cd 100644 --- a/libart/src/main/java/java/lang/DexCache.java +++ b/libart/src/main/java/java/lang/DexCache.java @@ -33,7 +33,6 @@ package java.lang; import com.android.dex.Dex; -import java.lang.reflect.ArtMethod; /** * A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile. @@ -49,7 +48,7 @@ final class DexCache { * References to methods as they become resolved following interpreter semantics. May refer to * methods defined in other dex files. */ - ArtMethod[] resolvedMethods; + Object resolvedMethods; /** * References to fields as they become resolved following interpreter semantics. May refer to diff --git a/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java index a5bf34c..0875d1a 100644 --- a/libart/src/main/java/java/lang/String.java +++ b/libart/src/main/java/java/lang/String.java @@ -35,23 +35,6 @@ import libcore.util.EmptyArray; * See {@link Character} for details about the relationship between {@code char} and * Unicode code points. * - * <a name="backing_array"><h3>Backing Arrays</h3></a> - * This class is implemented using a {@code char[]}. The length of the array may exceed - * the length of the string. For example, the string "Hello" may be backed by - * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with - * offset 0 and length 5. - * - * <p>Multiple strings can share the same {@code char[]} because strings are immutable. - * The {@link #substring} method <strong>always</strong> returns a string that - * shares the backing array of its source string. Generally this is an - * optimization: fewer {@code char[]}s need to be allocated, and less copying - * is necessary. But this can also lead to unwanted heap retention. Taking a - * short substring of long string means that the long shared {@code char[]} won't be - * garbage until both strings are garbage. This typically happens when parsing - * small substrings out of a large input. To avoid this where necessary, call - * {@code new String(longString.subString(...))}. The string copy constructor - * always ensures that the backing array is no larger than necessary. - * * @see StringBuffer * @see StringBuilder * @see Charset @@ -93,10 +76,6 @@ public final class String implements Serializable, Comparable<String>, CharSeque } } - private final char[] value; - - private final int offset; - private final int count; private int hashCode; @@ -105,9 +84,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque * Creates an empty string. */ public String() { - value = EmptyArray.CHAR; - offset = 0; - count = 0; + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -116,7 +93,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque */ @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING") public String(byte[] data) { - this(data, 0, data.length); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -133,7 +110,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque */ @Deprecated public String(byte[] data, int high) { - this(data, high, 0, data.length); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -146,7 +123,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}. */ public String(byte[] data, int offset, int byteCount) { - this(data, offset, byteCount, Charset.defaultCharset()); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -162,16 +139,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque */ @Deprecated public String(byte[] data, int high, int offset, int byteCount) { - if ((offset | byteCount) < 0 || byteCount > data.length - offset) { - throw failedBoundsCheck(data.length, offset, byteCount); - } - this.offset = 0; - this.value = new char[byteCount]; - this.count = byteCount; - high <<= 8; - for (int i = 0; i < count; i++) { - value[i] = (char) (high + (data[offset++] & 0xff)); - } + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -188,7 +156,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque * if the named charset is not supported. */ public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException { - this(data, offset, byteCount, Charset.forNameUEE(charsetName)); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -203,7 +171,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque * if {@code charsetName} is not supported. */ public String(byte[] data, String charsetName) throws UnsupportedEncodingException { - this(data, 0, data.length, Charset.forNameUEE(charsetName)); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -221,144 +189,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque * @since 1.6 */ public String(byte[] data, int offset, int byteCount, Charset charset) { - if ((offset | byteCount) < 0 || byteCount > data.length - offset) { - throw failedBoundsCheck(data.length, offset, byteCount); - } - - // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and - // 'value' are final. - String canonicalCharsetName = charset.name(); - if (canonicalCharsetName.equals("UTF-8")) { - byte[] d = data; - char[] v = new char[byteCount]; - - int idx = offset; - int last = offset + byteCount; - int s = 0; -outer: - while (idx < last) { - byte b0 = d[idx++]; - if ((b0 & 0x80) == 0) { - // 0xxxxxxx - // Range: U-00000000 - U-0000007F - int val = b0 & 0xff; - v[s++] = (char) val; - } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) || - ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) { - int utfCount = 1; - if ((b0 & 0xf0) == 0xe0) utfCount = 2; - else if ((b0 & 0xf8) == 0xf0) utfCount = 3; - else if ((b0 & 0xfc) == 0xf8) utfCount = 4; - else if ((b0 & 0xfe) == 0xfc) utfCount = 5; - - // 110xxxxx (10xxxxxx)+ - // Range: U-00000080 - U-000007FF (count == 1) - // Range: U-00000800 - U-0000FFFF (count == 2) - // Range: U-00010000 - U-001FFFFF (count == 3) - // Range: U-00200000 - U-03FFFFFF (count == 4) - // Range: U-04000000 - U-7FFFFFFF (count == 5) - - if (idx + utfCount > last) { - v[s++] = REPLACEMENT_CHAR; - continue; - } - - // Extract usable bits from b0 - int val = b0 & (0x1f >> (utfCount - 1)); - for (int i = 0; i < utfCount; ++i) { - byte b = d[idx++]; - if ((b & 0xc0) != 0x80) { - v[s++] = REPLACEMENT_CHAR; - idx--; // Put the input char back - continue outer; - } - // Push new bits in from the right side - val <<= 6; - val |= b & 0x3f; - } - - // Note: Java allows overlong char - // specifications To disallow, check that val - // is greater than or equal to the minimum - // value for each count: - // - // count min value - // ----- ---------- - // 1 0x80 - // 2 0x800 - // 3 0x10000 - // 4 0x200000 - // 5 0x4000000 - - // Allow surrogate values (0xD800 - 0xDFFF) to - // be specified using 3-byte UTF values only - if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) { - v[s++] = REPLACEMENT_CHAR; - continue; - } - - // Reject chars greater than the Unicode maximum of U+10FFFF. - if (val > 0x10FFFF) { - v[s++] = REPLACEMENT_CHAR; - continue; - } - - // Encode chars from U+10000 up as surrogate pairs - if (val < 0x10000) { - v[s++] = (char) val; - } else { - int x = val & 0xffff; - int u = (val >> 16) & 0x1f; - int w = (u - 1) & 0xffff; - int hi = 0xd800 | (w << 6) | (x >> 10); - int lo = 0xdc00 | (x & 0x3ff); - v[s++] = (char) hi; - v[s++] = (char) lo; - } - } else { - // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff - v[s++] = REPLACEMENT_CHAR; - } - } - - if (s == byteCount) { - // We guessed right, so we can use our temporary array as-is. - this.offset = 0; - this.value = v; - this.count = s; - } else { - // Our temporary array was too big, so reallocate and copy. - this.offset = 0; - this.value = new char[s]; - this.count = s; - System.arraycopy(v, 0, value, 0, s); - } - } else if (canonicalCharsetName.equals("ISO-8859-1")) { - this.offset = 0; - this.value = new char[byteCount]; - this.count = byteCount; - CharsetUtils.isoLatin1BytesToChars(data, offset, byteCount, value); - } else if (canonicalCharsetName.equals("US-ASCII")) { - this.offset = 0; - this.value = new char[byteCount]; - this.count = byteCount; - CharsetUtils.asciiBytesToChars(data, offset, byteCount, value); - } else { - CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount)); - this.offset = 0; - this.count = cb.length(); - if (count > 0) { - // We could use cb.array() directly, but that would mean we'd have to trust - // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later, - // which would break String's immutability guarantee. It would also tend to - // mean that we'd be wasting memory because CharsetDecoder doesn't trim the - // array. So we copy. - this.value = new char[count]; - System.arraycopy(cb.array(), 0, value, 0, count); - } else { - this.value = EmptyArray.CHAR; - } - } + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -368,7 +199,7 @@ outer: * @since 1.6 */ public String(byte[] data, Charset charset) { - this(data, 0, data.length, charset); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -379,7 +210,7 @@ outer: * @throws NullPointerException if {@code data == null} */ public String(char[] data) { - this(data, 0, data.length); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -393,36 +224,25 @@ outer: * if {@code charCount < 0 || offset < 0 || offset + charCount > data.length} */ public String(char[] data, int offset, int charCount) { - if ((offset | charCount) < 0 || charCount > data.length - offset) { - throw failedBoundsCheck(data.length, offset, charCount); - } - this.offset = 0; - this.value = new char[charCount]; - this.count = charCount; - System.arraycopy(data, offset, value, 0, count); + throw new UnsupportedOperationException("Use StringFactory instead."); } /* * Internal version of the String(char[], int, int) constructor. - * Does not range check, null check, or copy the array. + * Does not range check or null check. */ + // TODO: Replace calls to this with calls to StringFactory, will require + // splitting other files in java.lang. String(int offset, int charCount, char[] chars) { - this.value = chars; - this.offset = offset; - this.count = charCount; + throw new UnsupportedOperationException("Use StringFactory instead."); } /** - * Constructs a copy of the given string. - * The returned string's <a href="#backing_array">backing array</a> - * is no larger than necessary. + * Constructs a new string with the same sequence of characters as {@code + * toCopy}. */ public String(String toCopy) { - value = (toCopy.value.length == toCopy.count) - ? toCopy.value - : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length()); - offset = 0; - count = value.length; + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -430,11 +250,7 @@ outer: * {@code StringBuffer}. */ public String(StringBuffer stringBuffer) { - offset = 0; - synchronized (stringBuffer) { - value = stringBuffer.shareValue(); - count = stringBuffer.length(); - } + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -451,20 +267,7 @@ outer: * @since 1.5 */ public String(int[] codePoints, int offset, int count) { - if (codePoints == null) { - throw new NullPointerException("codePoints == null"); - } - if ((offset | count) < 0 || count > codePoints.length - offset) { - throw failedBoundsCheck(codePoints.length, offset, count); - } - this.offset = 0; - this.value = new char[count * 2]; - int end = offset + count; - int c = 0; - for (int i = offset; i < end; i++) { - c += Character.toChars(codePoints[i], this.value, c); - } - this.count = c; + throw new UnsupportedOperationException("Use StringFactory instead."); } /** @@ -476,25 +279,16 @@ outer: * @since 1.5 */ public String(StringBuilder stringBuilder) { - if (stringBuilder == null) { - throw new NullPointerException("stringBuilder == null"); - } - this.offset = 0; - this.count = stringBuilder.length(); - this.value = new char[this.count]; - stringBuilder.getChars(0, this.count, this.value, 0); + throw new UnsupportedOperationException("Use StringFactory instead."); } /** * Returns the {@code char} at {@code index}. * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}. */ - public char charAt(int index) { - if (index < 0 || index >= count) { - throw indexAndLength(index); - } - return value[offset + index]; - } + public native char charAt(int index); + + native void setCharAt(int index, char c); private StringIndexOutOfBoundsException indexAndLength(int index) { throw new StringIndexOutOfBoundsException(this, index); @@ -557,12 +351,11 @@ outer: * if {@code string} is {@code null}. */ public int compareToIgnoreCase(String string) { - int o1 = offset, o2 = string.offset, result; - int end = offset + (count < string.count ? count : string.count); + int result; + int end = count < string.count ? count : string.count; char c1, c2; - char[] target = string.value; - while (o1 < end) { - if ((c1 = value[o1++]) == (c2 = target[o2++])) { + for (int i = 0; i < end; ++i) { + if ((c1 = charAt(i)) == (c2 = string.charAt(i))) { continue; } c1 = foldCase(c1); @@ -582,15 +375,7 @@ outer: * @return a new string which is the concatenation of this string and the * specified string. */ - public String concat(String string) { - if (string.count > 0 && count > 0) { - char[] buffer = new char[count + string.count]; - System.arraycopy(value, offset, buffer, 0, count); - System.arraycopy(string.value, string.offset, buffer, count, string.count); - return new String(0, buffer.length, buffer); - } - return count == 0 ? string : this; - } + public native String concat(String string); /** * Creates a new string by copying the given {@code char[]}. @@ -601,7 +386,7 @@ outer: * if {@code data} is {@code null}. */ public static String copyValueOf(char[] data) { - return new String(data, 0, data.length); + return StringFactory.newStringFromChars(data, 0, data.length); } /** @@ -616,7 +401,7 @@ outer: * data.length}. */ public static String copyValueOf(char[] data, int start, int length) { - return new String(data, start, length); + return StringFactory.newStringFromChars(data, start, length); } /** @@ -654,16 +439,10 @@ outer: if (hashCode() != s.hashCode()) { return false; } - char[] value1 = value; - int offset1 = offset; - char[] value2 = s.value; - int offset2 = s.offset; - for (int end = offset1 + count; offset1 < end; ) { - if (value1[offset1] != value2[offset2]) { + for (int i = 0; i < count; ++i) { + if (charAt(i) != s.charAt(i)) { return false; } - offset1++; - offset2++; } return true; } else { @@ -686,12 +465,9 @@ outer: if (string == null || count != string.count) { return false; } - int o1 = offset, o2 = string.offset; - int end = offset + count; - char[] target = string.value; - while (o1 < end) { - char c1 = value[o1++]; - char c2 = target[o2++]; + for (int i = 0; i < count; ++i) { + char c1 = charAt(i); + char c2 = string.charAt(i); if (c1 != c2 && foldCase(c1) != foldCase(c2)) { return false; } @@ -721,10 +497,9 @@ outer: @Deprecated public void getBytes(int start, int end, byte[] data, int index) { if (start >= 0 && start <= end && end <= count) { - end += offset; try { - for (int i = offset + start; i < end; i++) { - data[index++] = (byte) value[i]; + for (int i = start; i < end; ++i) { + data[index++] = (byte) charAt(i); } } catch (ArrayIndexOutOfBoundsException ignored) { throw failedBoundsCheck(data.length, index, end - start); @@ -772,16 +547,15 @@ outer: public byte[] getBytes(Charset charset) { String canonicalCharsetName = charset.name(); if (canonicalCharsetName.equals("UTF-8")) { - return CharsetUtils.toUtf8Bytes(value, offset, count); + return CharsetUtils.toUtf8Bytes(this, 0, count); } else if (canonicalCharsetName.equals("ISO-8859-1")) { - return CharsetUtils.toIsoLatin1Bytes(value, offset, count); + return CharsetUtils.toIsoLatin1Bytes(this, 0, count); } else if (canonicalCharsetName.equals("US-ASCII")) { - return CharsetUtils.toAsciiBytes(value, offset, count); + return CharsetUtils.toAsciiBytes(this, 0, count); } else if (canonicalCharsetName.equals("UTF-16BE")) { - return CharsetUtils.toBigEndianUtf16Bytes(value, offset, count); + return CharsetUtils.toBigEndianUtf16Bytes(this, 0, count); } else { - CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count); - ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer()); + ByteBuffer buffer = charset.encode(this); byte[] bytes = new byte[buffer.limit()]; buffer.get(bytes); return bytes; @@ -809,7 +583,16 @@ outer: */ public void getChars(int start, int end, char[] buffer, int index) { if (start >= 0 && start <= end && end <= count) { - System.arraycopy(value, start + offset, buffer, index, end - start); + if (buffer == null) { + throw new NullPointerException("buffer == null"); + } + if (index < 0) { + throw new IndexOutOfBoundsException("index < 0"); + } + if (end - start > buffer.length - index) { + throw new ArrayIndexOutOfBoundsException("end - start > buffer.length - index"); + } + getCharsNoCheck(start, end, buffer, index); } else { // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE. throw startEndAndLength(start, end); @@ -821,9 +604,7 @@ outer: * within the java.lang package only. The caller is responsible for * ensuring that start >= 0 && start <= end && end <= count. */ - void _getChars(int start, int end, char[] buffer, int index) { - System.arraycopy(value, start + offset, buffer, index, end - start); - } + native void getCharsNoCheck(int start, int end, char[] buffer, int index); @Override public int hashCode() { int hash = hashCode; @@ -831,10 +612,8 @@ outer: if (count == 0) { return 0; } - final int end = count + offset; - final char[] chars = value; - for (int i = offset; i < end; ++i) { - hash = 31*hash + chars[i]; + for (int i = 0; i < count; ++i) { + hash = 31 * hash + charAt(i); } hashCode = hash; } @@ -893,21 +672,17 @@ outer: if (subCount > _count) { return -1; } - char[] target = string.value; - int subOffset = string.offset; - char firstChar = target[subOffset]; - int end = subOffset + subCount; + char firstChar = string.charAt(0); while (true) { int i = indexOf(firstChar, start); if (i == -1 || subCount + i > _count) { return -1; // handles subCount > count || start >= count } - int o1 = offset + i, o2 = subOffset; - char[] _value = value; - while (++o2 < end && _value[++o1] == target[o2]) { + int o1 = i, o2 = 0; + while (++o2 < subCount && charAt(++o1) == string.charAt(o2)) { // Intentionally empty } - if (o2 == end) { + if (o2 == subCount) { return i; } start = i + 1; @@ -934,21 +709,17 @@ outer: if (subCount + start > _count) { return -1; } - char[] target = subString.value; - int subOffset = subString.offset; - char firstChar = target[subOffset]; - int end = subOffset + subCount; + char firstChar = subString.charAt(0); while (true) { int i = indexOf(firstChar, start); if (i == -1 || subCount + i > _count) { return -1; // handles subCount > count || start >= count } - int o1 = offset + i, o2 = subOffset; - char[] _value = value; - while (++o2 < end && _value[++o1] == target[o2]) { + int o1 = i, o2 = 0; + while (++o2 < subCount && charAt(++o1) == subString.charAt(o2)) { // Intentionally empty } - if (o2 == end) { + if (o2 == subCount) { return i; } start = i + 1; @@ -991,11 +762,9 @@ outer: return lastIndexOfSupplementary(c, Integer.MAX_VALUE); } int _count = count; - int _offset = offset; - char[] _value = value; - for (int i = _offset + _count - 1; i >= _offset; --i) { - if (_value[i] == c) { - return i - _offset; + for (int i = _count - 1; i >= 0; --i) { + if (charAt(i) == c) { + return i; } } return -1; @@ -1011,15 +780,13 @@ outer: return lastIndexOfSupplementary(c, start); } int _count = count; - int _offset = offset; - char[] _value = value; if (start >= 0) { if (start >= _count) { start = _count - 1; } - for (int i = _offset + start; i >= _offset; --i) { - if (_value[i] == c) { - return i - _offset; + for (int i = start; i >= 0; --i) { + if (charAt(i) == c) { + return i; } } } @@ -1031,7 +798,7 @@ outer: return -1; } char[] chars = Character.toChars(c); - String needle = new String(0, chars.length, chars); + String needle = StringFactory.newStringFromChars(0, chars.length, chars); return lastIndexOf(needle, start); } @@ -1065,20 +832,17 @@ outer: start = count - subCount; } // count and subCount are both >= 1 - char[] target = subString.value; - int subOffset = subString.offset; - char firstChar = target[subOffset]; - int end = subOffset + subCount; + char firstChar = subString.charAt(0); while (true) { int i = lastIndexOf(firstChar, start); if (i == -1) { return -1; } - int o1 = offset + i, o2 = subOffset; - while (++o2 < end && value[++o1] == target[o2]) { + int o1 = i, o2 = 0; + while (++o2 < subCount && charAt(++o1) == subString.charAt(o2)) { // Intentionally empty } - if (o2 == end) { + if (o2 == subCount) { return i; } start = i - 1; @@ -1121,11 +885,8 @@ outer: if (length <= 0) { return true; } - int o1 = offset + thisStart, o2 = string.offset + start; - char[] value1 = value; - char[] value2 = string.value; for (int i = 0; i < length; ++i) { - if (value1[o1 + i] != value2[o2 + i]) { + if (charAt(thisStart + i) != string.charAt(start + i)) { return false; } } @@ -1164,13 +925,10 @@ outer: if (start < 0 || length > string.count - start) { return false; } - thisStart += offset; - start += string.offset; int end = thisStart + length; - char[] target = string.value; while (thisStart < end) { - char c1 = value[thisStart++]; - char c2 = target[start++]; + char c1 = charAt(thisStart++); + char c2 = string.charAt(start++); if (c1 != c2 && foldCase(c1) != foldCase(c2)) { return false; } @@ -1182,29 +940,20 @@ outer: * Returns a copy of this string after replacing occurrences of the given {@code char} with another. */ public String replace(char oldChar, char newChar) { - char[] buffer = value; - int _offset = offset; + String s = null; int _count = count; - - int idx = _offset; - int last = _offset + _count; boolean copied = false; - while (idx < last) { - if (buffer[idx] == oldChar) { + for (int i = 0; i < _count; ++i) { + if (charAt(i) == oldChar) { if (!copied) { - char[] newBuffer = new char[_count]; - System.arraycopy(buffer, _offset, newBuffer, 0, _count); - buffer = newBuffer; - idx -= _offset; - last -= _offset; + s = StringFactory.newStringFromString(this); copied = true; } - buffer[idx] = newChar; + s.setCharAt(i, newChar); } - idx++; } - return copied ? new String(0, count, buffer) : this; + return copied ? s : this; } /** @@ -1241,9 +990,8 @@ outer: int resultLength = count + (count + 1) * replacementString.length(); StringBuilder result = new StringBuilder(resultLength); result.append(replacementString); - int end = offset + count; - for (int i = offset; i != end; ++i) { - result.append(value[i]); + for (int i = 0; i != count; ++i) { + result.append(charAt(i)); result.append(replacementString); } return result.toString(); @@ -1252,15 +1000,21 @@ outer: StringBuilder result = new StringBuilder(count); int searchStart = 0; do { - // Copy chars before the match... - result.append(value, offset + searchStart, matchStart - searchStart); + // Copy characters before the match... + // TODO: Perform this faster than one char at a time? + for (int i = searchStart; i < matchStart; ++i) { + result.append(charAt(i)); + } // Insert the replacement... result.append(replacementString); // And skip over the match... searchStart = matchStart + targetLength; } while ((matchStart = indexOf(targetString, searchStart)) != -1); // Copy any trailing chars... - result.append(value, offset + searchStart, count - searchStart); + // TODO: Perform this faster than one char at a time? + for (int i = searchStart; i < count; ++i) { + result.append(charAt(i)); + } return result.toString(); } @@ -1308,7 +1062,7 @@ outer: return this; } if (start >= 0 && start <= count) { - return new String(offset + start, count - start, value); + return fastSubstring(start, count - start); } throw indexAndLength(start); } @@ -1328,21 +1082,19 @@ outer: } // Fast range check. if (start >= 0 && start <= end && end <= count) { - return new String(offset + start, end - start, value); + return fastSubstring(start, end - start); } throw startEndAndLength(start, end); } + private native String fastSubstring(int start, int length); + /** * Returns a new {@code char} array containing a copy of the {@code char}s in this string. * This is expensive and rarely useful. If you just want to iterate over the {@code char}s in * the string, use {@link #charAt} instead. */ - public char[] toCharArray() { - char[] buffer = new char[count]; - System.arraycopy(value, offset, buffer, 0, count); - return buffer; - } + public native char[] toCharArray(); /** * Converts this string to lower case, using the rules of the user's default locale. @@ -1351,7 +1103,7 @@ outer: * @return a new lower case string, or {@code this} if it's already all lower case. */ public String toLowerCase() { - return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count); + return CaseMapper.toLowerCase(Locale.getDefault(), this); } /** @@ -1368,7 +1120,7 @@ outer: * @return a new lower case string, or {@code this} if it's already all lower case. */ public String toLowerCase(Locale locale) { - return CaseMapper.toLowerCase(locale, this, value, offset, count); + return CaseMapper.toLowerCase(locale, this); } /** @@ -1386,7 +1138,7 @@ outer: * @return a new upper case string, or {@code this} if it's already all upper case. */ public String toUpperCase() { - return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count); + return CaseMapper.toUpperCase(Locale.getDefault(), this, count); } /** @@ -1403,7 +1155,7 @@ outer: * @return a new upper case string, or {@code this} if it's already all upper case. */ public String toUpperCase(Locale locale) { - return CaseMapper.toUpperCase(locale, this, value, offset, count); + return CaseMapper.toUpperCase(locale, this, count); } /** @@ -1411,18 +1163,18 @@ outer: * the beginning or end. */ public String trim() { - int start = offset, last = offset + count - 1; + int start = 0, last = count - 1; int end = last; - while ((start <= end) && (value[start] <= ' ')) { + while ((start <= end) && (charAt(start) <= ' ')) { start++; } - while ((end >= start) && (value[end] <= ' ')) { + while ((end >= start) && (charAt(end) <= ' ')) { end--; } - if (start == offset && end == last) { + if (start == 0 && end == last) { return this; } - return new String(start, end - start + 1, value); + return fastSubstring(start, end - start + 1); } /** @@ -1434,7 +1186,7 @@ outer: * if {@code data} is {@code null}. */ public static String valueOf(char[] data) { - return new String(data, 0, data.length); + return StringFactory.newStringFromChars(data, 0, data.length); } /** @@ -1448,7 +1200,7 @@ outer: * if {@code data} is {@code null}. */ public static String valueOf(char[] data, int start, int length) { - return new String(data, start, length); + return StringFactory.newStringFromChars(data, start, length); } /** @@ -1457,9 +1209,9 @@ outer: public static String valueOf(char value) { String s; if (value < 128) { - s = new String(value, 1, ASCII); + s = StringFactory.newStringFromChars(value, 1, ASCII); } else { - s = new String(0, 1, new char[] { value }); + s = StringFactory.newStringFromChars(0, 1, new char[] { value }); } s.hashCode = value; return s; @@ -1533,7 +1285,8 @@ outer: if (count != size) { return false; } - return regionMatches(0, new String(0, size, sb.getValue()), 0, size); + String s = StringFactory.newStringFromChars(0, size, sb.getValue()); + return regionMatches(0, s, 0, size); } } @@ -1682,7 +1435,7 @@ outer: if (index < 0 || index >= count) { throw indexAndLength(index); } - return Character.codePointAt(value, offset + index, offset + count); + return Character.codePointAt(this, index); } /** @@ -1696,7 +1449,7 @@ outer: if (index < 1 || index > count) { throw indexAndLength(index); } - return Character.codePointBefore(value, offset + index, offset); + return Character.codePointBefore(this, index); } /** @@ -1717,7 +1470,7 @@ outer: if (start < 0 || end > count || start > end) { throw startEndAndLength(start, end); } - return Character.codePointCount(value, offset + start, end - start); + return Character.codePointCount(this, start, end); } /** @@ -1748,9 +1501,7 @@ outer: * @since 1.5 */ public int offsetByCodePoints(int index, int codePointOffset) { - int s = index + offset; - int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset); - return r - offset; + return Character.offsetByCodePoints(this, index, codePointOffset); } /** @@ -1816,31 +1567,26 @@ outer: @SuppressWarnings("unused") private static int indexOf(String haystackString, String needleString, int cache, int md2, char lastChar) { - char[] haystack = haystackString.value; - int haystackOffset = haystackString.offset; int haystackLength = haystackString.count; - char[] needle = needleString.value; - int needleOffset = needleString.offset; int needleLength = needleString.count; int needleLengthMinus1 = needleLength - 1; - int haystackEnd = haystackOffset + haystackLength; - outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) { - if (lastChar == haystack[i]) { + outer_loop: for (int i = needleLengthMinus1; i < haystackLength;) { + if (lastChar == haystackString.charAt(i)) { for (int j = 0; j < needleLengthMinus1; ++j) { - if (needle[j + needleOffset] != haystack[i + j - - needleLengthMinus1]) { + if (needleString.charAt(j) != + haystackString.charAt(i + j - needleLengthMinus1)) { int skip = 1; - if ((cache & (1 << haystack[i])) == 0) { + if ((cache & (1 << haystackString.charAt(i))) == 0) { skip += j; } i += Math.max(md2, skip); continue outer_loop; } } - return i - needleLengthMinus1 - haystackOffset; + return i - needleLengthMinus1; } - if ((cache & (1 << haystack[i])) == 0) { + if ((cache & (1 << haystackString.charAt(i))) == 0) { i += needleLengthMinus1; } i++; diff --git a/libart/src/main/java/java/lang/StringFactory.java b/libart/src/main/java/java/lang/StringFactory.java new file mode 100644 index 0000000..4fc3eba --- /dev/null +++ b/libart/src/main/java/java/lang/StringFactory.java @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 java.lang; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Comparator; +import libcore.util.CharsetUtils; +import libcore.util.EmptyArray; + +/** + * Class used to generate strings instead of calling String.<init>. + * + * @hide + */ +public final class StringFactory { + + // TODO: Remove once native methods are in place. + private static final char REPLACEMENT_CHAR = (char) 0xfffd; + + public static String newEmptyString() { + return newStringFromChars(EmptyArray.CHAR, 0, 0); + } + + public static String newStringFromBytes(byte[] data) { + return newStringFromBytes(data, 0, data.length); + } + + public static String newStringFromBytes(byte[] data, int high) { + return newStringFromBytes(data, high, 0, data.length); + } + + public static String newStringFromBytes(byte[] data, int offset, int byteCount) { + return newStringFromBytes(data, offset, byteCount, Charset.defaultCharset()); + } + + public static native String newStringFromBytes(byte[] data, int high, int offset, int byteCount); + + public static String newStringFromBytes(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException { + return newStringFromBytes(data, offset, byteCount, Charset.forNameUEE(charsetName)); + } + + public static String newStringFromBytes(byte[] data, String charsetName) throws UnsupportedEncodingException { + return newStringFromBytes(data, 0, data.length, Charset.forNameUEE(charsetName)); + } + + // TODO: Implement this method natively. + public static String newStringFromBytes(byte[] data, int offset, int byteCount, Charset charset) { + if ((offset | byteCount) < 0 || byteCount > data.length - offset) { + throw new StringIndexOutOfBoundsException(data.length, offset, byteCount); + } + + char[] value; + int length; + + // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed. + String canonicalCharsetName = charset.name(); + if (canonicalCharsetName.equals("UTF-8")) { + byte[] d = data; + char[] v = new char[byteCount]; + + int idx = offset; + int last = offset + byteCount; + int s = 0; +outer: + while (idx < last) { + byte b0 = d[idx++]; + if ((b0 & 0x80) == 0) { + // 0xxxxxxx + // Range: U-00000000 - U-0000007F + int val = b0 & 0xff; + v[s++] = (char) val; + } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) || + ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) { + int utfCount = 1; + if ((b0 & 0xf0) == 0xe0) utfCount = 2; + else if ((b0 & 0xf8) == 0xf0) utfCount = 3; + else if ((b0 & 0xfc) == 0xf8) utfCount = 4; + else if ((b0 & 0xfe) == 0xfc) utfCount = 5; + + // 110xxxxx (10xxxxxx)+ + // Range: U-00000080 - U-000007FF (count == 1) + // Range: U-00000800 - U-0000FFFF (count == 2) + // Range: U-00010000 - U-001FFFFF (count == 3) + // Range: U-00200000 - U-03FFFFFF (count == 4) + // Range: U-04000000 - U-7FFFFFFF (count == 5) + + if (idx + utfCount > last) { + v[s++] = REPLACEMENT_CHAR; + continue; + } + + // Extract usable bits from b0 + int val = b0 & (0x1f >> (utfCount - 1)); + for (int i = 0; i < utfCount; ++i) { + byte b = d[idx++]; + if ((b & 0xc0) != 0x80) { + v[s++] = REPLACEMENT_CHAR; + idx--; // Put the input char back + continue outer; + } + // Push new bits in from the right side + val <<= 6; + val |= b & 0x3f; + } + + // Note: Java allows overlong char + // specifications To disallow, check that val + // is greater than or equal to the minimum + // value for each count: + // + // count min value + // ----- ---------- + // 1 0x80 + // 2 0x800 + // 3 0x10000 + // 4 0x200000 + // 5 0x4000000 + + // Allow surrogate values (0xD800 - 0xDFFF) to + // be specified using 3-byte UTF values only + if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) { + v[s++] = REPLACEMENT_CHAR; + continue; + } + + // Reject chars greater than the Unicode maximum of U+10FFFF. + if (val > 0x10FFFF) { + v[s++] = REPLACEMENT_CHAR; + continue; + } + + // Encode chars from U+10000 up as surrogate pairs + if (val < 0x10000) { + v[s++] = (char) val; + } else { + int x = val & 0xffff; + int u = (val >> 16) & 0x1f; + int w = (u - 1) & 0xffff; + int hi = 0xd800 | (w << 6) | (x >> 10); + int lo = 0xdc00 | (x & 0x3ff); + v[s++] = (char) hi; + v[s++] = (char) lo; + } + } else { + // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff + v[s++] = REPLACEMENT_CHAR; + } + } + + if (s == byteCount) { + // We guessed right, so we can use our temporary array as-is. + value = v; + length = s; + } else { + // Our temporary array was too big, so reallocate and copy. + value = new char[s]; + length = s; + System.arraycopy(v, 0, value, 0, s); + } + } else if (canonicalCharsetName.equals("ISO-8859-1")) { + value = new char[byteCount]; + length = byteCount; + CharsetUtils.isoLatin1BytesToChars(data, offset, byteCount, value); + } else if (canonicalCharsetName.equals("US-ASCII")) { + value = new char[byteCount]; + length = byteCount; + CharsetUtils.asciiBytesToChars(data, offset, byteCount, value); + } else { + CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount)); + length = cb.length(); + if (length > 0) { + // We could use cb.array() directly, but that would mean we'd have to trust + // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later, + // which would break String's immutability guarantee. It would also tend to + // mean that we'd be wasting memory because CharsetDecoder doesn't trim the + // array. So we copy. + value = new char[length]; + System.arraycopy(cb.array(), 0, value, 0, length); + } else { + value = EmptyArray.CHAR; + } + } + return newStringFromChars(value, 0, length); + } + + public static String newStringFromBytes(byte[] data, Charset charset) { + return newStringFromBytes(data, 0, data.length, charset); + } + + public static String newStringFromChars(char[] data) { + return newStringFromChars(data, 0, data.length); + } + + public static String newStringFromChars(char[] data, int offset, int charCount) { + if ((offset | charCount) < 0 || charCount > data.length - offset) { + throw new StringIndexOutOfBoundsException(data.length, offset, charCount); + } + return newStringFromChars(offset, charCount, data); + } + + static native String newStringFromChars(int offset, int charCount, char[] data); + + public static native String newStringFromString(String toCopy); + + public static String newStringFromStringBuffer(StringBuffer stringBuffer) { + synchronized (stringBuffer) { + return newStringFromChars(stringBuffer.getValue(), 0, stringBuffer.length()); + } + } + + // TODO: Implement this method natively. + public static String newStringFromCodePoints(int[] codePoints, int offset, int count) { + if (codePoints == null) { + throw new NullPointerException("codePoints == null"); + } + if ((offset | count) < 0 || count > codePoints.length - offset) { + throw new StringIndexOutOfBoundsException(codePoints.length, offset, count); + } + char[] value = new char[count * 2]; + int end = offset + count; + int length = 0; + for (int i = offset; i < end; i++) { + length += Character.toChars(codePoints[i], value, length); + } + return newStringFromChars(value, 0, length); + } + + public static String newStringFromStringBuilder(StringBuilder stringBuilder) { + return newStringFromChars(stringBuilder.getValue(), 0, stringBuilder.length()); + } +} diff --git a/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java index 0ac15f9..95d90cc 100644 --- a/libart/src/main/java/java/lang/reflect/AbstractMethod.java +++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java @@ -51,10 +51,11 @@ public abstract class AbstractMethod extends AccessibleObject { /** * The ArtMethod associated with this Method, requried for dispatching due to entrypoints + * Classloader is held live by the declaring class. * Hidden to workaround b/16828157. * @hide */ - protected ArtMethod artMethod; + protected long artMethod; /** Method's declaring class */ protected Class<?> declaringClass; diff --git a/libart/src/main/java/java/lang/reflect/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java deleted file mode 100644 index 84e6b48..0000000 --- a/libart/src/main/java/java/lang/reflect/ArtMethod.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -/* - * Copyright (C) 2012 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 java.lang.reflect; - -import com.android.dex.Dex; -import java.lang.annotation.Annotation; -import libcore.reflect.AnnotationAccess; -import libcore.util.EmptyArray; - -/** - * This class represents methods and constructors. - * @hide - */ -public final class ArtMethod { - /* A note on the field order here, it reflects the same field order as laid out by ART. */ - - /** Method's declaring class */ - private Class<?> declaringClass; - - /** Short-cut to declaringClass.dexCache.resolvedMethods */ - private ArtMethod[] dexCacheResolvedMethods; - - /** Short-cut to declaringClass.dexCache.resolvedTypes */ - /* package */ Class<?>[] dexCacheResolvedTypes; - - /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */ - private int accessFlags; - - /* Dex file fields. The defining dex file is available via declaringClass.dexCache */ - - /** The offset of the code item associated with this method within its defining dex file */ - private int dexCodeItemOffset; - - /** The method index of this method within its defining dex file */ - private int dexMethodIndex; - - /* End of dex file fields. */ - - /** - * Entry within a dispatch table for this method. For static/direct methods the index is - * into the declaringClass.directMethods, for virtual methods the vtable and for - * interface methods the ifTable. - */ - private int methodIndex; - - /** Only created by ART directly. */ - private ArtMethod() {} -} diff --git a/luni/src/main/files/cacerts/0d188d89.0 b/luni/src/main/files/cacerts/0d188d89.0 deleted file mode 100644 index 07a14ef..0000000 --- a/luni/src/main/files/cacerts/0d188d89.0 +++ /dev/null @@ -1,80 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp -Z2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp -a2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx -MzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg -R3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU -MZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT -L/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H -5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC -90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1 -c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE -VtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP -qk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S -/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj -/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X -KWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 44:99:8d:3c:c0:03:27:bd:9c:76:95:b9:ea:db:ac:b5 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi - Validity - Not Before: Jan 4 11:32:48 2007 GMT - Not After : Jan 4 11:32:48 2017 GMT - Subject: C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c3:12:20:9e:b0:5e:00:65:8d:4e:46:bb:80:5c: - e9:2c:06:97:d5:f3:72:c9:70:b9:e7:4b:65:80:c1: - 4b:be:7e:3c:d7:54:31:94:de:d5:12:ba:53:16:02: - ea:58:63:ef:5b:d8:f3:ed:2a:1a:aa:71:48:a3:dc: - 10:2d:5f:5f:eb:5c:4b:9c:96:08:42:25:28:11:cc: - 8a:5a:62:01:50:d5:eb:09:53:2f:f8:c3:8f:fe:b3: - fc:fd:9d:a2:e3:5f:7d:be:ed:0b:e0:60:eb:69:ec: - 33:ed:d8:8d:fb:12:49:83:00:c9:8b:97:8c:3b:73: - 2a:32:b3:12:f7:b9:4d:f2:f4:4d:6d:c7:e6:d6:26: - 37:08:f2:d9:fd:6b:5c:a3:e5:48:5c:58:bc:42:be: - 03:5a:81:ba:1c:35:0c:00:d3:f5:23:7e:71:30:08: - 26:38:dc:25:11:47:2d:f3:ba:23:10:a5:bf:bc:02: - f7:43:5e:c7:fe:b0:37:50:99:7b:0f:93:ce:e6:43: - 2c:c3:7e:0d:f2:1c:43:66:60:cb:61:31:47:87:a3: - 4f:ae:bd:56:6c:4c:bc:bc:f8:05:ca:64:f4:e9:34: - a1:2c:b5:73:e1:c2:3e:e8:c8:c9:34:25:08:5c:f3: - ed:a6:c7:94:9f:ad:88:43:25:d7:e1:39:60:fe:ac: - 39:59 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Subject Key Identifier: - 9F:EE:44:B3:94:D5:FA:91:4F:2E:D9:55:9A:04:56:DB:2D:C4:DB:A5 - Signature Algorithm: sha1WithRSAEncryption - 7f:5f:b9:53:5b:63:3d:75:32:e7:fa:c4:74:1a:cb:46:df:46: - 69:1c:52:cf:aa:4f:c2:68:eb:ff:80:a9:51:e8:3d:62:77:89: - 3d:0a:75:39:f1:6e:5d:17:87:6f:68:05:c1:94:6c:d9:5d:df: - da:b2:59:cb:a5:10:8a:ca:cc:39:cd:9f:eb:4e:de:52:ff:0c: - f0:f4:92:a9:f2:6c:53:ab:9b:d2:47:a0:1f:74:f7:9b:9a:f1: - 2f:15:9f:7a:64:30:18:07:3c:2a:0f:67:ca:fc:0f:89:61:9d: - 65:a5:3c:e5:bc:13:5b:08:db:e3:ff:ed:bb:06:bb:6a:06:b1: - 7a:4f:65:c6:82:fd:1e:9c:8b:b5:0d:ee:48:bb:b8:bd:aa:08: - b4:fb:a3:7c:cb:9f:cd:90:76:5c:86:96:78:57:0a:66:f9:58: - 1a:9d:fd:97:29:60:de:11:a6:90:1c:19:1c:ee:01:96:22:34: - 34:2e:91:f9:b7:c4:27:d1:7b:e6:bf:fb:80:44:5a:16:e5:eb: - e0:d4:0a:38:bc:e4:91:e3:d5:eb:5c:c1:ac:df:1b:6a:7c:9e: - e5:75:d2:b6:97:87:db:cc:87:2b:43:3a:84:08:af:ab:3c:db: - f7:3c:66:31:86:b0:9d:53:79:ed:f8:23:de:42:e3:2d:82:f1: - 0f:e5:fa:97 -SHA1 Fingerprint=DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 diff --git a/luni/src/main/files/cacerts/0d5a4e1c.0 b/luni/src/main/files/cacerts/0d5a4e1c.0 new file mode 100644 index 0000000..2a40cf6 --- /dev/null +++ b/luni/src/main/files/cacerts/0d5a4e1c.0 @@ -0,0 +1,82 @@ +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE +BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn +aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg +QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0 +MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD +VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom +/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR +Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3 +4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z +5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0 +hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID +AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX +SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l +VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf +peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF +Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW ++qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 156233699172481 (0x8e17fe242081) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E., CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H5 + Validity + Not Before: Apr 30 08:07:01 2013 GMT + Not After : Apr 28 08:07:01 2023 GMT + Subject: C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E., CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H5 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a4:25:19:e1:65:9e:eb:48:21:50:4a:08:e5:11: + f0:5a:ba:26:ff:83:59:ce:44:2a:2f:fe:e1:ce:60: + 03:fc:8d:03:a5:ed:ff:6b:a8:ba:cc:34:06:9f:59: + 35:f6:ec:2c:bb:9d:fb:8d:52:69:e3:9c:27:10:53: + f3:a4:02:c5:a7:f9:11:1a:69:75:6e:c3:1d:8b:d1: + 98:8d:93:87:a7:71:97:0d:21:c7:99:f9:52:d3:2c: + 63:5d:55:bc:e8:1f:01:48:b9:60:fe:42:4a:f6:c8: + 80:ae:cd:66:7a:9e:45:8a:68:77:e2:48:68:9f:a2: + da:f1:e1:c1:10:9f:eb:3c:29:81:a7:e1:32:08:d4: + a0:05:b1:8c:fb:8d:96:00:0e:3e:25:df:53:86:22: + 3b:fc:f4:bd:f3:09:7e:77:ec:86:eb:0f:33:e5:43: + 4f:f4:54:75:6d:29:99:2e:66:5a:43:df:cb:5c:ca: + c8:e5:38:f1:7e:3b:35:9d:0f:f4:c5:5a:a1:cc:f3: + 20:80:24:d3:57:ec:15:ba:75:25:9b:e8:64:4b:b3: + 34:84:ef:04:b8:f6:c9:6c:aa:02:3e:b6:55:e2:32: + 37:5f:fc:66:97:5f:cd:d6:9e:c7:20:bf:4d:c6:ac: + 3f:75:5f:1c:ed:32:9c:7c:69:00:69:91:e3:23:18: + 53:e9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 56:99:07:1E:D3:AC:0C:69:64:B4:0C:50:47:DE:43:2C:BE:20:C0:FB + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + 9e:45:76:7b:17:48:32:f2:38:8b:29:bd:ee:96:4a:4e:81:18: + b1:51:47:20:cd:d0:64:b1:0e:c9:d9:01:d9:09:ce:c8:99:dc: + 68:25:13:d4:5c:f2:a3:e8:04:fe:72:09:c7:0b:aa:1d:25:55: + 7e:96:9a:57:b7:ba:c5:11:7a:19:e6:a7:7e:3d:85:0e:f5:f9: + 2e:29:2f:e7:f9:6c:58:16:57:50:25:f6:3e:2e:3e:aa:ed:77: + 71:aa:aa:99:96:46:0a:ae:8e:ec:2a:51:16:b0:5e:cd:ea:67: + 04:1c:58:30:f5:60:8a:bd:a6:bd:4d:e5:96:b4:fc:42:89:01: + 6b:f6:70:c8:50:39:0c:2d:d5:66:d9:c8:d2:b3:32:b7:1b:19: + 6d:cb:33:f9:df:a5:e6:15:84:37:f0:c2:f2:65:96:92:90:77: + f0:ad:f4:90:e9:11:78:d7:93:89:c0:3d:0b:ba:29:f4:e8:99: + 9d:72:8e:ed:9d:2f:ee:92:7d:a1:f1:ff:5d:ba:33:60:85:62: + fe:07:02:a1:84:56:46:be:96:0a:9a:13:d7:21:4c:b7:7c:07: + 9f:4e:4e:3f:91:74:fb:27:9d:11:cc:dd:e6:b1:ca:71:4d:13: + 17:39:26:c5:29:21:2b:93:29:6a:96:fa:ab:41:e1:4b:b6:35: + 0b:c0:9b:15 +SHA1 Fingerprint=C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB diff --git a/luni/src/main/files/cacerts/2afc57aa.0 b/luni/src/main/files/cacerts/2afc57aa.0 deleted file mode 100644 index aefb4ad..0000000 --- a/luni/src/main/files/cacerts/2afc57aa.0 +++ /dev/null @@ -1,91 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf -tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg -uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J -XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK -8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 -5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 -kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS -GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt -ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 -au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV -hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI -dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 2e:6a:00:01:00:02:1f:d7:52:21:2c:11:5c:3b - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 2 CA, CN=TC TrustCenter Class 2 CA II - Validity - Not Before: Jan 12 14:38:43 2006 GMT - Not After : Dec 31 22:59:59 2025 GMT - Subject: C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 2 CA, CN=TC TrustCenter Class 2 CA II - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:ab:80:87:9b:8e:f0:c3:7c:87:d7:e8:24:82:11: - b3:3c:dd:43:62:ee:f8:c3:45:da:e8:e1:a0:5f:d1: - 2a:b2:ea:93:68:df:b4:c8:d6:43:e9:c4:75:59:7f: - fc:e1:1d:f8:31:70:23:1b:88:9e:27:b9:7b:fd:3a: - d2:c9:a9:e9:14:2f:90:be:03:52:c1:49:cd:f6:fd: - e4:08:66:0b:57:8a:a2:42:a0:b8:d5:7f:69:5c:90: - 32:b2:97:0d:ca:4a:dc:46:3e:02:55:89:53:e3:1a: - 5a:cb:36:c6:07:56:f7:8c:cf:11:f4:4c:bb:30:70: - 04:95:a5:f6:39:8c:fd:73:81:08:7d:89:5e:32:1e: - 22:a9:22:45:4b:b0:66:2e:30:cc:9f:65:fd:fc:cb: - 81:a9:f1:e0:3b:af:a3:86:d1:89:ea:c4:45:79:50: - 5d:ae:e9:21:74:92:4d:8b:59:82:8f:94:e3:e9:4a: - f1:e7:49:b0:14:e3:f5:62:cb:d5:72:bd:1f:b9:d2: - 9f:a0:cd:a8:fa:01:c8:d9:0d:df:da:fc:47:9d:b3: - c8:54:df:49:4a:f1:21:a9:fe:18:4e:ee:48:d4:19: - bb:ef:7d:e4:e2:9d:cb:5b:b6:6e:ff:e3:cd:5a:e7: - 74:82:05:ba:80:25:38:cb:e4:69:9e:af:41:aa:1a: - 84:f5 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - E3:AB:54:4C:80:A1:DB:56:43:B7:91:4A:CB:F3:82:7A:13:5C:08:AB - X509v3 CRL Distribution Points: - - Full Name: - URI:http://www.trustcenter.de/crl/v2/tc_class_2_ca_II.crl - URI:ldap://www.trustcenter.de/CN=TC%20TrustCenter%20Class%202%20CA%20II,O=TC%20TrustCenter%20GmbH,OU=rootcerts,DC=trustcenter,DC=de?certificateRevocationList?base? - - Signature Algorithm: sha1WithRSAEncryption - 8c:d7:df:7e:ee:1b:80:10:b3:83:f5:db:11:ea:6b:4b:a8:92: - 18:d9:f7:07:39:f5:2c:be:06:75:7a:68:53:15:1c:ea:4a:ed: - 5e:fc:23:b2:13:a0:d3:09:ff:f6:f6:2e:6b:41:71:79:cd:e2: - 6d:fd:ae:59:6b:85:1d:b8:4e:22:9a:ed:66:39:6e:4b:94:e6: - 55:fc:0b:1b:8b:77:c1:53:13:66:89:d9:28:d6:8b:f3:45:4a: - 63:b7:fd:7b:0b:61:5d:b8:6d:be:c3:dc:5b:79:d2:ed:86:e5: - a2:4d:be:5e:74:7c:6a:ed:16:38:1f:7f:58:81:5a:1a:eb:32: - 88:2d:b2:f3:39:77:80:af:5e:b6:61:75:29:db:23:4d:88:ca: - 50:28:cb:85:d2:d3:10:a2:59:6e:d3:93:54:00:7a:a2:46:95: - 86:05:9c:a9:19:98:e5:31:72:0c:00:e2:67:d9:40:e0:24:33: - 7b:6f:2c:b9:5c:ab:65:9d:2c:ac:76:ea:35:99:f5:97:b9:0f: - 24:ec:c7:76:21:28:65:ae:57:e8:07:88:75:4a:56:a0:d2:05: - 3a:a4:e6:8d:92:88:2c:f3:f2:e1:c1:c6:61:db:41:c5:c7:9b: - f7:0e:1a:51:45:c2:61:6b:dc:64:27:17:8c:5a:b7:da:74:28: - cd:97:e4:bd -SHA1 Fingerprint=AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E diff --git a/luni/src/main/files/cacerts/2fb1850a.0 b/luni/src/main/files/cacerts/2fb1850a.0 deleted file mode 100644 index 20dd1ee..0000000 --- a/luni/src/main/files/cacerts/2fb1850a.0 +++ /dev/null @@ -1,124 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP -bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2 -MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft -ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC -206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci -KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2 -JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9 -BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e -Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B -PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67 -Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq -Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ -o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3 -+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj -YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj -FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn -xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2 -LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc -obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8 -CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe -IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA -DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F -AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX -Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb -AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl -Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw -RY8mkaKO/qk= ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1 (0x1) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=America Online Inc., CN=America Online Root Certification Authority 2 - Validity - Not Before: May 28 06:00:00 2002 GMT - Not After : Sep 29 14:08:00 2037 GMT - Subject: C=US, O=America Online Inc., CN=America Online Root Certification Authority 2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (4096 bit) - Modulus: - 00:cc:41:45:1d:e9:3d:4d:10:f6:8c:b1:41:c9:e0: - 5e:cb:0d:b7:bf:47:73:d3:f0:55:4d:dd:c6:0c:fa: - b1:66:05:6a:cd:78:b4:dc:02:db:4e:81:f3:d7:a7: - 7c:71:bc:75:63:a0:5d:e3:07:0c:48:ec:25:c4:03: - 20:f4:ff:0e:3b:12:ff:9b:8d:e1:c6:d5:1b:b4:6d: - 22:e3:b1:db:7f:21:64:af:86:bc:57:22:2a:d6:47: - 81:57:44:82:56:53:bd:86:14:01:0b:fc:7f:74:a4: - 5a:ae:f1:ba:11:b5:9b:58:5a:80:b4:37:78:09:33: - 7c:32:47:03:5c:c4:a5:83:48:f4:57:56:6e:81:36: - 27:18:4f:ec:9b:28:c2:d4:b4:d7:7c:0c:3e:0c:2b: - df:ca:04:d7:c6:8e:ea:58:4e:a8:a4:a5:18:1c:6c: - 45:98:a3:41:d1:2d:d2:c7:6d:8d:19:f1:ad:79:b7: - 81:3f:bd:06:82:27:2d:10:58:05:b5:78:05:b9:2f: - db:0c:6b:90:90:7e:14:59:38:bb:94:24:13:e5:d1: - 9d:14:df:d3:82:4d:46:f0:80:39:52:32:0f:e3:84: - b2:7a:43:f2:5e:de:5f:3f:1d:dd:e3:b2:1b:a0:a1: - 2a:23:03:6e:2e:01:15:87:5c:a6:75:75:c7:97:61: - be:de:86:dc:d4:48:db:bd:2a:bf:4a:55:da:e8:7d: - 50:fb:b4:80:17:b8:94:bf:01:3d:ea:da:ba:7c:e0: - 58:67:17:b9:58:e0:88:86:46:67:6c:9d:10:47:58: - 32:d0:35:7c:79:2a:90:a2:5a:10:11:23:35:ad:2f: - cc:e4:4a:5b:a7:c8:27:f2:83:de:5e:bb:5e:77:e7: - e8:a5:6e:63:c2:0d:5d:61:d0:8c:d2:6c:5a:21:0e: - ca:28:a3:ce:2a:e9:95:c7:48:cf:96:6f:1d:92:25: - c8:c6:c6:c1:c1:0c:05:ac:26:c4:d2:75:d2:e1:2a: - 67:c0:3d:5b:a5:9a:eb:cf:7b:1a:a8:9d:14:45:e5: - 0f:a0:9a:65:de:2f:28:bd:ce:6f:94:66:83:48:29: - d8:ea:65:8c:af:93:d9:64:9f:55:57:26:bf:6f:cb: - 37:31:99:a3:60:bb:1c:ad:89:34:32:62:b8:43:21: - 06:72:0c:a1:5c:6d:46:c5:fa:29:cf:30:de:89:dc: - 71:5b:dd:b6:37:3e:df:50:f5:b8:07:25:26:e5:bc: - b5:fe:3c:02:b3:b7:f8:be:43:c1:87:11:94:9e:23: - 6c:17:8a:b8:8a:27:0c:54:47:f0:a9:b3:c0:80:8c: - a0:27:eb:1d:19:e3:07:8e:77:70:ca:2b:f4:7d:76: - e0:78:67 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Subject Key Identifier: - 4D:45:C1:68:38:BB:73:A9:69:A1:20:E7:ED:F5:22:A1:23:14:D7:9E - X509v3 Authority Key Identifier: - keyid:4D:45:C1:68:38:BB:73:A9:69:A1:20:E7:ED:F5:22:A1:23:14:D7:9E - - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - Signature Algorithm: sha1WithRSAEncryption - 67:6b:06:b9:5f:45:3b:2a:4b:33:b3:e6:1b:6b:59:4e:22:cc: - b9:b7:a4:25:c9:a7:c4:f0:54:96:0b:64:f3:b1:58:4f:5e:51: - fc:b2:97:7b:27:65:c2:e5:ca:e7:0d:0c:25:7b:62:e3:fa:9f: - b4:87:b7:45:46:af:83:a5:97:48:8c:a5:bd:f1:16:2b:9b:76: - 2c:7a:35:60:6c:11:80:97:cc:a9:92:52:e6:2b:e6:69:ed:a9: - f8:36:2d:2c:77:bf:61:48:d1:63:0b:b9:5b:52:ed:18:b0:43: - 42:22:a6:b1:77:ae:de:69:c5:cd:c7:1c:a1:b1:a5:1c:10:fb: - 18:be:1a:70:dd:c1:92:4b:be:29:5a:9d:3f:35:be:e5:7d:51: - f8:55:e0:25:75:23:87:1e:5c:dc:ba:9d:b0:ac:b3:69:db:17: - 83:c9:f7:de:0c:bc:08:dc:91:9e:a8:d0:d7:15:37:73:a5:35: - b8:fc:7e:c5:44:40:06:c3:eb:f8:22:80:5c:47:ce:02:e3:11: - 9f:44:ff:fd:9a:32:cc:7d:64:51:0e:eb:57:26:76:3a:e3:1e: - 22:3c:c2:a6:36:dd:19:ef:a7:fc:12:f3:26:c0:59:31:85:4c: - 9c:d8:cf:df:a4:cc:cc:29:93:ff:94:6d:76:5c:13:08:97:f2: - ed:a5:0b:4d:dd:e8:c9:68:0e:66:d3:00:0e:33:12:5b:bc:95: - e5:32:90:a8:b3:c6:6c:83:ad:77:ee:8b:7e:7e:b1:a9:ab:d3: - e1:f1:b6:c0:b1:ea:88:c0:e7:d3:90:e9:28:92:94:7b:68:7b: - 97:2a:0a:67:2d:85:02:38:10:e4:03:61:d4:da:25:36:c7:08: - 58:2d:a1:a7:51:af:30:0a:49:f5:a6:69:87:07:2d:44:46:76: - 8e:2a:e5:9a:3b:d7:18:a2:fc:9c:38:10:cc:c6:3b:d2:b5:17: - 3a:6f:fd:ae:25:bd:f5:72:59:64:b1:74:2a:38:5f:18:4c:df: - cf:71:04:5a:36:d4:bf:2f:99:9c:e8:d9:ba:b1:95:e6:02:4b: - 21:a1:5b:d5:c1:4f:8f:ae:69:6d:53:db:01:93:b5:5c:1e:18: - dd:64:5a:ca:18:28:3e:63:04:11:fd:1c:8d:00:0f:b8:37:df: - 67:8a:9d:66:a9:02:6a:91:ff:13:ca:2f:5d:83:bc:87:93:6c: - dc:24:51:16:04:25:66:fa:b3:d9:c2:ba:29:be:9a:48:38:82: - 99:f4:bf:3b:4a:31:19:f9:bf:8e:21:33:14:ca:4f:54:5f:fb: - ce:fb:8f:71:7f:fd:5e:19:a0:0f:4b:91:b8:c4:54:bc:06:b0: - 45:8f:26:91:a2:8e:fe:a9 -SHA1 Fingerprint=85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 diff --git a/luni/src/main/files/cacerts/3c6676aa.0 b/luni/src/main/files/cacerts/3c6676aa.0 new file mode 100644 index 0000000..2905a24 --- /dev/null +++ b/luni/src/main/files/cacerts/3c6676aa.0 @@ -0,0 +1,120 @@ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 10000013 (0x98968d) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden EV Root CA + Validity + Not Before: Dec 8 11:19:29 2010 GMT + Not After : Dec 8 11:10:28 2022 GMT + Subject: C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden EV Root CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:e3:c7:7e:89:f9:24:4b:3a:d2:33:83:35:2c:69: + ec:dc:09:a4:e3:51:a8:25:2b:79:b8:08:3d:e0:91: + ba:84:85:c6:85:a4:ca:e6:c9:2e:53:a4:c9:24:1e: + fd:55:66:71:5d:2c:c5:60:68:04:b7:d9:c2:52:26: + 38:88:a4:d6:3b:40:a6:c2:cd:3f:cd:98:93:b3:54: + 14:58:96:55:d5:50:fe:86:ad:a4:63:7f:5c:87:f6: + 8e:e6:27:92:67:17:92:02:03:2c:dc:d6:66:74:ed: + dd:67:ff:c1:61:8d:63:4f:0f:9b:6d:17:30:26:ef: + ab:d2:1f:10:a0:f9:c5:7f:16:69:81:03:47:ed:1e: + 68:8d:72:a1:4d:b2:26:c6:ba:6c:5f:6d:d6:af:d1: + b1:13:8e:a9:ad:f3:5e:69:75:26:18:3e:41:2b:21: + 7f:ee:8b:5d:07:06:9d:43:c4:29:0a:2b:fc:2a:3e: + 86:cb:3c:83:3a:f9:c9:0d:da:c5:99:e2:bc:78:41: + 33:76:e1:bf:2f:5d:e5:a4:98:50:0c:15:dd:e0:fa: + 9c:7f:38:68:d0:b2:a6:7a:a7:d1:31:bd:7e:8a:58: + 27:43:b3:ba:33:91:d3:a7:98:15:5c:9a:e6:d3:0f: + 75:d9:fc:41:98:97:3e:aa:25:db:8f:92:2e:b0:7b: + 0c:5f:f1:63:a9:37:f9:9b:75:69:4c:28:26:25:da: + d5:f2:12:70:45:55:e3:df:73:5e:37:f5:21:6c:90: + 8e:35:5a:c9:d3:23:eb:d3:c0:be:78:ac:42:28:58: + 66:a5:46:6d:70:02:d7:10:f9:4b:54:fc:5d:86:4a: + 87:cf:7f:ca:45:ac:11:5a:b5:20:51:8d:2f:88:47: + 97:39:c0:cf:ba:c0:42:01:40:99:48:21:0b:6b:a7: + d2:fd:96:d5:d1:be:46:9d:49:e0:0b:a6:a0:22:4e: + 38:d0:c1:3c:30:bc:70:8f:2c:75:cc:d0:c5:8c:51: + 3b:3d:94:08:64:26:61:7d:b9:c3:65:8f:14:9c:21: + d0:aa:fd:17:72:03:8f:bd:9b:8c:e6:5e:53:9e:b9: + 9d:ef:82:bb:e1:bc:e2:72:41:5b:21:94:d3:45:37: + 94:d1:df:09:39:5d:e7:23:aa:9a:1d:ca:6d:a8:0a: + 86:85:8a:82:be:42:07:d6:f2:38:82:73:da:87:5b: + e5:3c:d3:9e:3e:a7:3b:9e:f4:03:b3:f9:f1:7d:13: + 74:02:ff:bb:a1:e5:fa:00:79:1c:a6:66:41:88:5c: + 60:57:a6:2e:09:c4:ba:fd:9a:cf:a7:1f:40:c3:bb: + cc:5a:0a:55:4b:3b:38:76:51:b8:63:8b:84:94:16: + e6:56:f3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + FE:AB:00:90:98:9E:24:FC:A9:CC:1A:8A:FB:27:B8:BF:30:6E:A8:3B + Signature Algorithm: sha256WithRSAEncryption + cf:77:2c:6e:56:be:4e:b3:b6:84:00:94:ab:47:c9:0d:d2:76: + c7:86:9f:1d:07:d3:b6:b4:bb:08:78:af:69:d2:0b:49:de:33: + c5:ac:ad:c2:88:02:7d:06:b7:35:02:c1:60:c9:bf:c4:e8:94: + de:d4:d3:a9:13:25:5a:fe:6e:a2:ae:7d:05:dc:7d:f3:6c:f0: + 7e:a6:8d:ee:d9:d7:ce:58:17:e8:a9:29:ae:73:48:87:e7:9b: + ca:6e:29:a1:64:5f:19:13:f7:ae:06:10:ff:51:c6:9b:4d:55: + 25:4f:93:99:10:01:53:75:f1:13:ce:c7:a6:41:41:d2:bf:88: + a5:7f:45:fc:ac:b8:a5:b5:33:0c:82:c4:fb:07:f6:6a:e5:25: + 84:5f:06:ca:c1:86:39:11:db:58:cd:77:3b:2c:c2:4c:0f:5e: + 9a:e3:f0:ab:3e:61:1b:50:24:c2:c0:f4:f1:19:f0:11:29:b6: + a5:18:02:9b:d7:63:4c:70:8c:47:a3:03:43:5c:b9:5d:46:a0: + 0d:6f:ff:59:8e:be:dd:9f:72:c3:5b:2b:df:8c:5b:ce:e5:0c: + 46:6c:92:b2:0a:a3:4c:54:42:18:15:12:18:bd:da:fc:ba:74: + 6e:ff:c1:b6:a0:64:d8:a9:5f:55:ae:9f:5c:6a:76:96:d8:73: + 67:87:fb:4d:7f:5c:ee:69:ca:73:10:fb:8a:a9:fd:9e:bd:36: + 38:49:49:87:f4:0e:14:f0:e9:87:b8:3f:a7:4f:7a:5a:8e:79: + d4:93:e4:bb:68:52:84:ac:6c:e9:f3:98:70:55:72:32:f9:34: + ab:2b:49:b5:cd:20:62:e4:3a:7a:67:63:ab:96:dc:6d:ae:97: + ec:fc:9f:76:56:88:2e:66:cf:5b:b6:c9:a4:b0:d7:05:ba:e1: + 27:2f:93:bb:26:2a:a2:93:b0:1b:f3:8e:be:1d:40:a3:b9:36: + 8f:3e:82:1a:1a:5e:88:ea:50:f8:59:e2:83:46:29:0b:e3:44: + 5c:e1:95:b6:69:90:9a:14:6f:97:ae:81:cf:68:ef:99:9a:be: + b5:e7:e1:7f:f8:fa:13:47:16:4c:cc:6d:08:40:e7:8b:78:6f: + 50:82:44:50:3f:66:06:8a:ab:43:84:56:4a:0f:20:2d:86:0e: + f5:d2:db:d2:7a:8a:4b:cd:a5:e8:4e:f1:5e:26:25:01:59:23: + a0:7e:d2:f6:7e:21:57:d7:27:bc:15:57:4c:a4:46:c1:e0:83: + 1e:0c:4c:4d:1f:4f:06:19:e2:f9:a8:f4:3a:82:a1:b2:79:43: + 79:d6:ad:6f:7a:27:90:03:a4:ea:24:87:3f:d9:bd:d9:e9:f2: + 5f:50:49:1c:ee:ec:d7:2e +SHA1 Fingerprint=76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB diff --git a/luni/src/main/files/cacerts/4be590e0.0 b/luni/src/main/files/cacerts/4be590e0.0 new file mode 100644 index 0000000..788aff7 --- /dev/null +++ b/luni/src/main/files/cacerts/4be590e0.0 @@ -0,0 +1,120 @@ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=IdenTrust, CN=IdenTrust Public Sector Root CA 1 + Validity + Not Before: Jan 16 17:53:32 2014 GMT + Not After : Jan 16 17:53:32 2034 GMT + Subject: C=US, O=IdenTrust, CN=IdenTrust Public Sector Root CA 1 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:b6:22:94:fc:a4:48:af:e8:47:6b:0a:fb:27:76: + e4:f2:3f:8a:3b:7a:4a:2c:31:2a:8c:8d:b0:a9:c3: + 31:6b:a8:77:76:84:26:b6:ac:81:42:0d:08:eb:55: + 58:bb:7a:f8:bc:65:7d:f2:a0:6d:8b:a8:47:e9:62: + 76:1e:11:ee:08:14:d1:b2:44:16:f4:ea:d0:fa:1e: + 2f:5e:db:cb:73:41:ae:bc:00:b0:4a:2b:40:b2:ac: + e1:3b:4b:c2:2d:9d:e4:a1:9b:ec:1a:3a:1e:f0:08: + b3:d0:e4:24:35:07:9f:9c:b4:c9:52:6d:db:07:ca: + 8f:b5:5b:f0:83:f3:4f:c7:2d:a5:c8:ad:cb:95:20: + a4:31:28:57:58:5a:e4:8d:1b:9a:ab:9e:0d:0c:f2: + 0a:33:39:22:39:0a:97:2e:f3:53:77:b9:44:45:fd: + 84:cb:36:20:81:59:2d:9a:6f:6d:48:48:61:ca:4c: + df:53:d1:af:52:bc:44:9f:ab:2f:6b:83:72:ef:75: + 80:da:06:33:1b:5d:c8:da:63:c6:4d:cd:ac:66:31: + cd:d1:de:3e:87:10:36:e1:b9:a4:7a:ef:60:50:b2: + cb:ca:a6:56:e0:37:af:ab:34:13:39:25:e8:39:66: + e4:98:7a:aa:12:98:9c:59:66:86:3e:ad:f1:b0:ca: + 3e:06:0f:7b:f0:11:4b:37:a0:44:6d:7b:cb:a8:8c: + 71:f4:d5:b5:91:36:cc:f0:15:c6:2b:de:51:17:b1: + 97:4c:50:3d:b1:95:59:7c:05:7d:2d:21:d5:00:bf: + 01:67:a2:5e:7b:a6:5c:f2:f7:22:f1:90:0d:93:db: + aa:44:51:66:cc:7d:76:03:eb:6a:a8:2a:38:19:97: + 76:0d:6b:8a:61:f9:bc:f6:ee:76:fd:70:2b:dd:29: + 3c:f8:0a:1e:5b:42:1c:8b:56:2f:55:1b:1c:a1:2e: + b5:c7:16:e6:f8:aa:3c:92:8e:69:b6:01:c1:b5:86: + 9d:89:0f:0b:38:94:54:e8:ea:dc:9e:3d:25:bc:53: + 26:ed:d5:ab:39:aa:c5:40:4c:54:ab:b2:b4:d9:d9: + f8:d7:72:db:1c:bc:6d:bd:65:5f:ef:88:35:2a:66: + 2f:ee:f6:b3:65:f0:33:8d:7c:98:41:69:46:0f:43: + 1c:69:fa:9b:b5:d0:61:6a:cd:ca:4b:d9:4c:90:46: + ab:15:59:a1:47:54:29:2e:83:28:5f:1c:c2:a2:ab: + 72:17:00:06:8e:45:ec:8b:e2:33:3d:7f:da:19:44: + e4:62:72:c3:df:22:c6:f2:56:d4:dd:5f:95:72:ed: + 6d:5f:f7:48:03:5b:fd:c5:2a:a0:f6:73:23:84:10: + 1b:01:e7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + E3:71:E0:9E:D8:A7:42:D9:DB:71:91:6B:94:93:EB:C3:A3:D1:14:A3 + Signature Algorithm: sha256WithRSAEncryption + 47:fa:dd:0a:b0:11:91:38:ad:4d:5d:f7:e5:0e:97:54:19:82: + 48:87:54:8c:aa:64:99:d8:5a:fe:88:01:c5:58:a5:99:b1:23: + 54:23:b7:6a:1d:20:57:e5:01:62:41:17:d3:09:db:75:cb:6e: + 54:90:75:fe:1a:9f:81:0a:c2:dd:d7:f7:09:d0:5b:72:15:e4: + 1e:09:6a:3d:33:f3:21:9a:e6:15:7e:ad:51:d5:0d:10:ed:7d: + 42:c0:8f:ee:c0:9a:08:d5:41:d6:5c:0e:21:69:6e:80:61:0e: + 15:c0:b8:cf:c5:49:12:52:cc:be:3a:cc:d4:2e:38:05:de:35: + fd:1f:6f:b8:80:68:98:3d:4d:a0:ca:40:65:d2:73:7c:f5:8b: + d9:0a:95:3f:d8:3f:23:6d:1a:d1:2a:24:19:d9:85:b3:17:ef: + 78:6e:a9:58:d1:23:d3:c7:13:ed:72:25:7f:5d:b1:73:70:d0: + 7f:06:97:09:84:29:80:61:1d:fa:5e:ff:73:ac:a0:e3:89:b8: + 1c:71:15:c6:de:31:7f:12:dc:e1:6d:9b:af:e7:e8:9f:75:78: + 4c:ab:46:3b:9a:ce:bf:05:18:5d:4d:15:3c:16:9a:19:50:04: + 9a:b2:9a:6f:65:8b:52:5f:3c:58:04:28:25:c0:66:61:31:7e: + b9:e0:75:b9:1a:a8:81:d6:72:17:b3:c5:03:31:35:11:78:78: + a2:e0:e9:30:8c:7f:80:df:58:df:3c:ba:27:96:e2:80:34:6d: + e3:98:d3:64:27:ac:48:7e:28:77:5c:c6:25:61:25:f8:85:0c: + 65:fa:c4:32:2f:a5:98:05:e4:f8:0b:67:16:16:c6:82:b8:32: + 19:f9:f9:b9:79:dc:1f:cd:eb:af:ab:0e:dd:1b:db:45:e4:7a: + e7:02:e2:95:5d:fc:69:f0:53:69:61:95:75:79:0b:5e:55:e6: + 38:1c:94:a9:59:33:9e:c8:71:74:79:7f:51:89:b6:c8:6a:b8: + 30:c8:6a:38:c3:6e:9e:e1:37:16:ea:05:62:4c:5b:12:47:ed: + a7:b4:b3:58:56:c7:49:f3:7f:12:68:09:31:71:f0:6d:f8:4e: + 47:fb:d6:85:ee:c5:58:40:19:a4:1d:a7:f9:4b:43:37:dc:68: + 5a:4f:cf:eb:c2:64:74:de:b4:15:d9:f4:54:54:1a:2f:1c:d7: + 97:71:54:90:8e:d9:20:9d:53:2b:7f:ab:8f:e2:ea:30:bc:50: + 37:ef:f1:47:b5:7d:7c:2c:04:ec:68:9d:b4:49:44:10:f4:72: + 4b:1c:64:e7:fc:e6:6b:90:dd:69:7d:69:fd:00:56:a5:b7:ac: + b6:ad:b7:ca:3e:01:ef:9c +SHA1 Fingerprint=BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD diff --git a/luni/src/main/files/cacerts/5021a0a2.0 b/luni/src/main/files/cacerts/5021a0a2.0 deleted file mode 100644 index 15f5213..0000000 --- a/luni/src/main/files/cacerts/5021a0a2.0 +++ /dev/null @@ -1,84 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV -BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 -c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx -MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg -R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD -VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR -JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T -fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu -jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z -wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ -fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD -VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G -CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 -7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn -8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs -ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ -2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 1d:a2:00:01:00:02:ec:b7:60:80:78:8d:b6:06 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC TrustCenter Universal CA I - Validity - Not Before: Mar 22 15:54:28 2006 GMT - Not After : Dec 31 22:59:59 2025 GMT - Subject: C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC TrustCenter Universal CA I - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a4:77:23:96:44:af:90:f4:31:a7:10:f4:26:87: - 9c:f3:38:d9:0f:5e:de:cf:41:e8:31:ad:c6:74:91: - 24:96:78:1e:09:a0:9b:9a:95:4a:4a:f5:62:7c:02: - a8:ca:ac:fb:5a:04:76:39:de:5f:f1:f9:b3:bf:f3: - 03:58:55:d2:aa:b7:e3:04:22:d1:f8:94:da:22:08: - 00:8d:d3:7c:26:5d:cc:77:79:e7:2c:78:39:a8:26: - 73:0e:a2:5d:25:69:85:4f:55:0e:9a:ef:c6:b9:44: - e1:57:3d:df:1f:54:22:e5:6f:65:aa:33:84:3a:f3: - ce:7a:be:55:97:ae:8d:12:0f:14:33:e2:50:70:c3: - 49:87:13:bc:51:de:d7:98:12:5a:ef:3a:83:33:92: - 06:75:8b:92:7c:12:68:7b:70:6a:0f:b5:9b:b6:77: - 5b:48:59:9d:e4:ef:5a:ad:f3:c1:9e:d4:d7:45:4e: - ca:56:34:21:bc:3e:17:5b:6f:77:0c:48:01:43:29: - b0:dd:3f:96:6e:e6:95:aa:0c:c0:20:b6:fd:3e:36: - 27:9c:e3:5c:cf:4e:81:dc:19:bb:91:90:7d:ec:e6: - 97:04:1e:93:cc:22:49:d7:97:86:b6:13:0a:3c:43: - 23:77:7e:f0:dc:e6:cd:24:1f:3b:83:9b:34:3a:83: - 34:e3 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:92:A4:75:2C:A4:9E:BE:81:44:EB:79:FC:8A:C5:95:A5:EB:10:75:73 - - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 92:A4:75:2C:A4:9E:BE:81:44:EB:79:FC:8A:C5:95:A5:EB:10:75:73 - Signature Algorithm: sha1WithRSAEncryption - 28:d2:e0:86:d5:e6:f8:7b:f0:97:dc:22:6b:3b:95:14:56:0f: - 11:30:a5:9a:4f:3a:b0:3a:e0:06:cb:65:f5:ed:c6:97:27:fe: - 25:f2:57:e6:5e:95:8c:3e:64:60:15:5a:7f:2f:0d:01:c5:b1: - 60:fd:45:35:cf:f0:b2:bf:06:d9:ef:5a:be:b3:62:21:b4:d7: - ab:35:7c:53:3e:a6:27:f1:a1:2d:da:1a:23:9d:cc:dd:ec:3c: - 2d:9e:27:34:5d:0f:c2:36:79:bc:c9:4a:62:2d:ed:6b:d9:7d: - 41:43:7c:b6:aa:ca:ed:61:b1:37:82:15:09:1a:8a:16:30:d8: - ec:c9:d6:47:72:78:4b:10:46:14:8e:5f:0e:af:ec:c7:2f:ab: - 10:d7:b6:f1:6e:ec:86:b2:c2:e8:0d:92:73:dc:a2:f4:0f:3a: - bf:61:23:10:89:9c:48:40:6e:70:00:b3:d3:ba:37:44:58:11: - 7a:02:6a:88:f0:37:34:f0:19:e9:ac:d4:65:73:f6:69:8c:64: - 94:3a:79:85:29:b0:16:2b:0c:82:3f:06:9c:c7:fd:10:2b:9e: - 0f:2c:b6:9e:e3:15:bf:d9:36:1c:ba:25:1a:52:3d:1a:ec:22: - 0c:1c:e0:a4:a2:3d:f0:e8:39:cf:81:c0:7b:ed:5d:1f:6f:c5: - d0:0b:d7:98 -SHA1 Fingerprint=6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 diff --git a/luni/src/main/files/cacerts/5a250ea7.0 b/luni/src/main/files/cacerts/5a250ea7.0 new file mode 100644 index 0000000..4561d51 --- /dev/null +++ b/luni/src/main/files/cacerts/5a250ea7.0 @@ -0,0 +1,120 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 10003001 (0x98a239) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA - G3 + Validity + Not Before: Nov 14 11:28:42 2013 GMT + Not After : Nov 13 23:00:00 2028 GMT + Subject: C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:be:32:a2:54:0f:70:fb:2c:5c:59:eb:6c:c4:a4: + 51:e8:85:2a:b3:cc:4a:34:f2:b0:5f:f3:0e:c7:1c: + 3d:53:1e:88:08:68:d8:6f:3d:ad:c2:9e:cc:82:67: + 07:27:87:68:71:3a:9f:75:96:22:46:05:b0:ed:ad: + c7:5b:9e:2a:de:9c:fc:3a:c6:95:a7:f5:17:67:18: + e7:2f:49:08:0c:5c:cf:e6:cc:34:ed:78:fb:50:b1: + dc:6b:32:f0:a2:fe:b6:3c:e4:ec:5a:97:c7:3f:1e: + 70:08:30:a0:dc:c5:b3:6d:6f:d0:82:72:11:ab:d2: + 81:68:59:82:17:b7:78:92:60:fa:cc:de:3f:84:eb: + 8d:38:33:90:0a:72:23:fa:35:cc:26:71:31:d1:72: + 28:92:d9:5b:23:6d:66:b5:6d:07:42:eb:a6:33:ce: + 92:db:c0:f6:6c:63:78:cd:ca:4e:3d:b5:e5:52:9b: + f1:be:3b:e6:54:60:b0:66:1e:09:ab:07:fe:54:89: + 11:42:d1:f7:24:ba:60:78:1a:98:f7:c9:11:fd:16: + c1:35:1a:54:75:ef:43:d3:e5:ae:4e:ce:e7:7b:c3: + c6:4e:61:51:4b:ab:9a:45:4b:a1:1f:41:bd:48:53: + 15:71:64:0b:86:b3:e5:2e:be:ce:a4:1b:c1:29:84: + a2:b5:cb:08:23:76:43:22:24:1f:17:04:d4:6e:9c: + c6:fc:7f:2b:66:1a:ec:8a:e5:d6:cf:4d:f5:63:09: + b7:15:39:d6:7b:ac:eb:e3:7c:e9:4e:fc:75:42:c8: + ed:58:95:0c:06:42:a2:9c:f7:e4:70:b3:df:72:6f: + 5a:37:40:89:d8:85:a4:d7:f1:0b:de:43:19:d4:4a: + 58:2c:8c:8a:39:9e:bf:84:87:f1:16:3b:36:0c:e9: + d3:b4:ca:6c:19:41:52:09:a1:1d:b0:6a:bf:82:ef: + 70:51:21:32:dc:05:76:8c:cb:f7:64:e4:03:50:af: + 8c:91:67:ab:c5:f2:ee:58:d8:de:be:f7:e7:31:cf: + 6c:c9:3b:71:c1:d5:88:b5:65:bc:c0:e8:17:17:07: + 12:b5:5c:d2:ab:20:93:b4:e6:82:83:70:36:c5:cd: + a3:8d:ad:8b:ec:a3:c1:43:87:e6:43:e2:34:be:95: + 8b:35:ed:07:39:da:a8:1d:7a:9f:36:9e:12:b0:0c: + 65:12:90:15:60:d9:26:40:44:e3:56:60:a5:10:d4: + 6a:3c:fd:41:dc:0e:5a:47:b6:ef:97:61:75:4f:d9: + fe:c7:b2:1d:d4:ed:5d:49:b3:a9:6a:cb:66:84:13: + d5:5c:a0:dc:df:6e:77:06:d1:71:75:c8:57:6f:af: + 0f:77:5b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 54:AD:FA:C7:92:57:AE:CA:35:9C:2E:12:FB:E4:BA:5D:20:DC:94:57 + Signature Algorithm: sha256WithRSAEncryption + 30:99:9d:05:32:c8:5e:0e:3b:98:01:3a:8a:a4:e7:07:f7:7a: + f8:e7:9a:df:50:43:53:97:2a:3d:ca:3c:47:98:2e:e1:15:7b: + f1:92:f3:61:da:90:25:16:65:c0:9f:54:5d:0e:03:3b:5b:77: + 02:9c:84:b6:0d:98:5f:34:dd:3b:63:c2:c3:28:81:c2:9c:29: + 2e:29:e2:c8:c3:01:f2:33:ea:2a:aa:cc:09:08:f7:65:67:c6: + cd:df:d3:b6:2b:a7:bd:cc:d1:0e:70:5f:b8:23:d1:cb:91:4e: + 0a:f4:c8:7a:e5:d9:63:36:c1:d4:df:fc:22:97:f7:60:5d:ea: + 29:2f:58:b2:bd:58:bd:8d:96:4f:10:75:bf:48:7b:3d:51:87: + a1:3c:74:22:c2:fc:07:7f:80:dc:c4:ac:fe:6a:c1:70:30:b0: + e9:8e:69:e2:2c:69:81:94:09:ba:dd:fe:4d:c0:83:8c:94:58: + c0:46:20:af:9c:1f:02:f8:35:55:49:2f:46:d4:c0:f0:a0:96: + 02:0f:33:c5:71:f3:9e:23:7d:94:b7:fd:3a:d3:09:83:06:21: + fd:60:3d:ae:32:c0:d2:ee:8d:a6:f0:e7:b4:82:7c:0a:cc:70: + c9:79:80:f8:fe:4c:f7:35:84:19:8a:31:fb:0a:d9:d7:7f:9b: + f0:a2:9a:6b:c3:05:4a:ed:41:60:14:30:d1:aa:11:42:6e:d3: + 23:02:04:0b:c6:65:dd:dd:52:77:da:81:6b:b2:a8:fa:01:38: + b9:96:ea:2a:6c:67:97:89:94:9e:bc:e1:54:d5:e4:6a:78:ef: + 4a:bd:2b:9a:3d:40:7e:c6:c0:75:d2:6e:fb:68:30:ec:ec:8b: + 9d:f9:49:35:9a:1a:2c:d9:b3:95:39:d5:1e:92:f7:a6:b9:65: + 2f:e5:3d:6d:3a:48:4c:08:dc:e4:28:12:28:be:7d:35:5c:ea: + e0:16:7e:13:1b:6a:d7:3e:d7:9e:fc:2d:75:b2:c1:14:d5:23: + 03:db:5b:6f:0b:3e:78:2f:0d:de:33:8d:16:b7:48:e7:83:9a: + 81:0f:7b:c1:43:4d:55:04:17:38:4a:51:d5:59:a2:89:74:d3: + 9f:be:1e:4b:d7:c6:6d:b7:88:24:6f:60:91:a4:82:85:5b:56: + 41:bc:d0:44:ab:6a:13:be:d1:2c:58:b7:12:33:58:b2:37:63: + dc:13:f5:94:1d:3f:40:51:f5:4f:f5:3a:ed:c8:c5:eb:c2:1e: + 1d:16:95:7a:c7:7e:42:71:93:6e:4b:15:b7:30:df:aa:ed:57: + 85:48:ac:1d:6a:dd:39:69:e4:e1:79:78:be:ce:05:bf:a1:0c: + f7:80:7b:21:67:27:30:59 +SHA1 Fingerprint=D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC diff --git a/luni/src/main/files/cacerts/6645de82.0 b/luni/src/main/files/cacerts/6645de82.0 new file mode 100644 index 0000000..4b1ee7b --- /dev/null +++ b/luni/src/main/files/cacerts/6645de82.0 @@ -0,0 +1,82 @@ +-----BEGIN CERTIFICATE----- +MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQG +EwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdp +IMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBB +LsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBI +aXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5MDQxMFoXDTIzMTIx +NjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBLBgNV +BAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2 +ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVs +ZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdsGjW6L0UlqMACprx9MfMkU1x +eHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a2uqsxgbPJQ1BgfbBOCK9 ++bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EEDwnS3/faA +z1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0p +u5FbHH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6p +lVxiSvgNZ1GpryHV+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMB +AAGjQjBAMB0GA1UdDgQWBBTdVRcT9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb1gNl0Oq +FlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3RfdCaqaXKGDsC +QC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy +o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKID +gI6tflEATseWhvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm +9ocJV612ph1jmv3XZch4gyt1O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsG +tAuYSyher4hYyw== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 138134509972618 (0x7da1f265ec8a) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E., CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H6 + Validity + Not Before: Dec 18 09:04:10 2013 GMT + Not After : Dec 16 09:04:10 2023 GMT + Subject: C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E., CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H6 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:9d:b0:68:d6:e8:bd:14:96:a3:00:0a:9a:f1:f4: + c7:cc:91:4d:71:78:77:b9:f7:21:26:15:73:51:16: + 94:09:47:05:e2:33:f5:68:9a:35:ff:dc:4b:2f:32: + c7:b0:ed:e2:82:e5:6f:da:da:ea:ac:c6:06:cf:25: + 0d:41:81:f6:c1:38:22:bd:f9:b1:a5:a6:b3:01:bc: + 3f:50:17:2b:f6:e9:66:55:d4:33:b3:5c:f8:43:20: + 78:93:55:16:70:19:32:e6:89:d7:64:eb:bd:48:50: + fd:f6:d0:41:03:c2:74:b7:fd:f6:80:cf:5b:c5:ab: + a4:d6:95:12:9b:e7:97:13:32:03:e9:d4:ab:43:5b: + 16:ed:33:22:64:29:b6:d2:93:ad:2f:6c:d8:3d:b6: + f6:1d:0e:34:ee:d2:7d:a9:55:0f:20:f4:fd:29:bb: + 91:5b:1c:7d:c6:42:38:6d:42:28:6d:d4:01:fb:cd: + 88:97:49:7e:b8:f3:83:f8:b5:98:2f:b3:27:0b:48: + 5e:56:e7:4e:a3:33:b3:44:d6:a5:f2:18:94:ed:1c: + 1e:a9:95:5c:62:4a:f8:0d:67:51:a9:af:21:d5:f8: + 32:9d:79:ba:1a:5f:e5:04:55:4d:13:46:ff:f2:cf: + 74:c7:1a:63:6d:c3:1f:17:12:c3:1e:10:3e:60:08: + b3:31 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + DD:55:17:13:F6:AC:E8:48:21:CA:EF:B5:AF:D1:00:32:ED:9E:8C:B5 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + 6f:58:0d:97:43:aa:16:54:3e:bf:a9:df:92:45:3f:85:0b:bb: + 56:d3:0c:52:cc:c8:bf:76:67:5e:e6:aa:b3:a7:ef:b9:ac:b4: + 10:14:0d:74:7e:3d:6d:ad:d1:7d:d0:9a:a9:a5:ca:18:3b:02: + 40:2e:2a:9c:50:14:8b:fe:57:7e:57:5c:11:09:4b:36:45:52: + f7:3d:ac:14:fd:44:df:8b:97:23:d4:c3:c1:ee:d4:53:95:fe: + 2c:4a:fe:0d:70:aa:bb:8b:2f:2d:cb:32:a3:82:f2:54:df:d8: + f2:dd:d7:48:72:ee:4a:a3:29:96:c3:44:ce:6e:b5:92:87:76: + a4:bb:f4:92:6c:ce:2c:14:09:66:8e:8d:ad:16:b5:c7:1b:09: + 61:3b:e3:20:a2:03:80:8e:ad:7e:51:00:4e:c7:96:86:fb:43: + 98:77:7d:28:c7:8f:d8:2a:6e:e7:84:6f:97:41:29:00:16:5e: + 4d:e2:13:ea:59:c0:63:67:3a:44:fb:98:fc:04:d3:30:72:a6: + f6:87:09:57:ad:76:a6:1d:63:9a:fd:d7:65:c8:78:83:2b:75: + 3b:a5:5b:b8:0d:5d:7f:be:23:ae:56:55:94:58:ef:1f:81:8c: + 2a:b2:cd:e6:9b:63:9e:18:bc:e5:6b:06:b4:0b:98:4b:28:5e: + af:88:58:cb +SHA1 Fingerprint=8A:5C:8C:EE:A5:03:E6:05:56:BA:D8:1B:D4:F6:C9:B0:ED:E5:2F:E0 diff --git a/luni/src/main/files/cacerts/72fa7371.0 b/luni/src/main/files/cacerts/72fa7371.0 deleted file mode 100644 index d7a34be..0000000 --- a/luni/src/main/files/cacerts/72fa7371.0 +++ /dev/null @@ -1,54 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh -c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy -MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp -emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X -DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw -FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg -UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo -YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 -MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB -AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 -pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 -13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID -AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk -U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i -F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY -oJ2daZH9 ------END CERTIFICATE----- -Certificate: - Data: - Version: 1 (0x0) - Serial Number: - 7d:d9:fe:07:cf:a8:1e:b7:10:79:67:fb:a7:89:34:c6 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign Trust Network - Validity - Not Before: May 18 00:00:00 1998 GMT - Not After : Aug 1 23:59:59 2028 GMT - Subject: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign Trust Network - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (1024 bit) - Modulus: - 00:cc:5e:d1:11:5d:5c:69:d0:ab:d3:b9:6a:4c:99: - 1f:59:98:30:8e:16:85:20:46:6d:47:3f:d4:85:20: - 84:e1:6d:b3:f8:a4:ed:0c:f1:17:0f:3b:f9:a7:f9: - 25:d7:c1:cf:84:63:f2:7c:63:cf:a2:47:f2:c6:5b: - 33:8e:64:40:04:68:c1:80:b9:64:1c:45:77:c7:d8: - 6e:f5:95:29:3c:50:e8:34:d7:78:1f:a8:ba:6d:43: - 91:95:8f:45:57:5e:7e:c5:fb:ca:a4:04:eb:ea:97: - 37:54:30:6f:bb:01:47:32:33:cd:dc:57:9b:64:69: - 61:f8:9b:1d:1c:89:4f:5c:67 - Exponent: 65537 (0x10001) - Signature Algorithm: sha1WithRSAEncryption - 51:4d:cd:be:5c:cb:98:19:9c:15:b2:01:39:78:2e:4d:0f:67: - 70:70:99:c6:10:5a:94:a4:53:4d:54:6d:2b:af:0d:5d:40:8b: - 64:d3:d7:ee:de:56:61:92:5f:a6:c4:1d:10:61:36:d3:2c:27: - 3c:e8:29:09:b9:11:64:74:cc:b5:73:9f:1c:48:a9:bc:61:01: - ee:e2:17:a6:0c:e3:40:08:3b:0e:e7:eb:44:73:2a:9a:f1:69: - 92:ef:71:14:c3:39:ac:71:a7:91:09:6f:e4:71:06:b3:ba:59: - 57:26:79:00:f6:f8:0d:a2:33:30:28:d4:aa:58:a0:9d:9d:69: - 91:fd -SHA1 Fingerprint=85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F diff --git a/luni/src/main/files/cacerts/74c26bd0.0 b/luni/src/main/files/cacerts/74c26bd0.0 deleted file mode 100644 index 55903f6..0000000 --- a/luni/src/main/files/cacerts/74c26bd0.0 +++ /dev/null @@ -1,60 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT -ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw -MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj -dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l -c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC -UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc -58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ -o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr -aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA -A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA -Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv -8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1 (0x1) - Signature Algorithm: md5WithRSAEncryption - Issuer: C=US, O=Equifax Secure Inc., CN=Equifax Secure Global eBusiness CA-1 - Validity - Not Before: Jun 21 04:00:00 1999 GMT - Not After : Jun 21 04:00:00 2020 GMT - Subject: C=US, O=Equifax Secure Inc., CN=Equifax Secure Global eBusiness CA-1 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (1024 bit) - Modulus: - 00:ba:e7:17:90:02:65:b1:34:55:3c:49:c2:51:d5: - df:a7:d1:37:8f:d1:e7:81:73:41:52:60:9b:9d:a1: - 17:26:78:ad:c7:b1:e8:26:94:32:b5:de:33:8d:3a: - 2f:db:f2:9a:7a:5a:73:98:a3:5c:e9:fb:8a:73:1b: - 5c:e7:c3:bf:80:6c:cd:a9:f4:d6:2b:c0:f7:f9:99: - aa:63:a2:b1:47:02:0f:d4:e4:51:3a:12:3c:6c:8a: - 5a:54:84:70:db:c1:c5:90:cf:72:45:cb:a8:59:c0: - cd:33:9d:3f:a3:96:eb:85:33:21:1c:3e:1e:3e:60: - 6e:76:9c:67:85:c5:c8:c3:61 - Exponent: 65537 (0x10001) - X509v3 extensions: - Netscape Cert Type: - SSL CA, S/MIME CA, Object Signing CA - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Authority Key Identifier: - keyid:BE:A8:A0:74:72:50:6B:44:B7:C9:23:D8:FB:A8:FF:B3:57:6B:68:6C - - X509v3 Subject Key Identifier: - BE:A8:A0:74:72:50:6B:44:B7:C9:23:D8:FB:A8:FF:B3:57:6B:68:6C - Signature Algorithm: md5WithRSAEncryption - 30:e2:01:51:aa:c7:ea:5f:da:b9:d0:65:0f:30:d6:3e:da:0d: - 14:49:6e:91:93:27:14:31:ef:c4:f7:2d:45:f8:ec:c7:bf:a2: - 41:0d:23:b4:92:f9:19:00:67:bd:01:af:cd:e0:71:fc:5a:cf: - 64:c4:e0:96:98:d0:a3:40:e2:01:8a:ef:27:07:f1:65:01:8a: - 44:2d:06:65:75:52:c0:86:10:20:21:5f:6c:6b:0f:6c:ae:09: - 1c:af:f2:a2:18:34:c4:75:a4:73:1c:f1:8d:dc:ef:ad:f9:b3: - 76:b4:92:bf:dc:95:10:1e:be:cb:c8:3b:5a:84:60:19:56:94: - a9:55 -SHA1 Fingerprint=7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45 diff --git a/luni/src/main/files/cacerts/7a481e66.0 b/luni/src/main/files/cacerts/7a481e66.0 deleted file mode 100644 index d40dfea..0000000 --- a/luni/src/main/files/cacerts/7a481e66.0 +++ /dev/null @@ -1,91 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW -Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q -Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 -1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq -ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 -Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX -XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN -irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 -TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 -g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB -95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj -S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 4a:47:00:01:00:02:e5:a0:5d:d6:3f:00:51:bf - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 3 CA, CN=TC TrustCenter Class 3 CA II - Validity - Not Before: Jan 12 14:41:57 2006 GMT - Not After : Dec 31 22:59:59 2025 GMT - Subject: C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 3 CA, CN=TC TrustCenter Class 3 CA II - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b4:e0:bb:51:bb:39:5c:8b:04:c5:4c:79:1c:23: - 86:31:10:63:43:55:27:3f:c6:45:c7:a4:3d:ec:09: - 0d:1a:1e:20:c2:56:1e:de:1b:37:07:30:22:2f:6f: - f1:06:f1:ab:ad:d6:c8:ab:61:a3:2f:43:c4:b0:b2: - 2d:fc:c3:96:69:7b:7e:8a:e4:cc:c0:39:12:90:42: - 60:c9:cc:35:68:ee:da:5f:90:56:5f:cd:1c:4d:5b: - 58:49:eb:0e:01:4f:64:fa:2c:3c:89:58:d8:2f:2e: - e2:b0:68:e9:22:3b:75:89:d6:44:1a:65:f2:1b:97: - 26:1d:28:6d:ac:e8:bd:59:1d:2b:24:f6:d6:84:03: - 66:88:24:00:78:60:f1:f8:ab:fe:02:b2:6b:fb:22: - fb:35:e6:16:d1:ad:f6:2e:12:e4:fa:35:6a:e5:19: - b9:5d:db:3b:1e:1a:fb:d3:ff:15:14:08:d8:09:6a: - ba:45:9d:14:79:60:7d:af:40:8a:07:73:b3:93:96: - d3:74:34:8d:3a:37:29:de:5c:ec:f5:ee:2e:31:c2: - 20:dc:be:f1:4f:7f:23:52:d9:5b:e2:64:d9:9c:aa: - 07:08:b5:45:bd:d1:d0:31:c1:ab:54:9f:a9:d2:c3: - 62:60:03:f1:bb:39:4a:92:4a:3d:0a:b9:9d:c5:a0: - fe:37 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - D4:A2:FC:9F:B3:C3:D8:03:D3:57:5C:07:A4:D0:24:A7:C0:F2:00:D4 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://www.trustcenter.de/crl/v2/tc_class_3_ca_II.crl - URI:ldap://www.trustcenter.de/CN=TC%20TrustCenter%20Class%203%20CA%20II,O=TC%20TrustCenter%20GmbH,OU=rootcerts,DC=trustcenter,DC=de?certificateRevocationList?base? - - Signature Algorithm: sha1WithRSAEncryption - 36:60:e4:70:f7:06:20:43:d9:23:1a:42:f2:f8:a3:b2:b9:4d: - 8a:b4:f3:c2:9a:55:31:7c:c4:3b:67:9a:b4:df:4d:0e:8a:93: - 4a:17:8b:1b:8d:ca:89:e1:cf:3a:1e:ac:1d:f1:9c:32:b4:8e: - 59:76:a2:41:85:25:37:a0:13:d0:f5:7c:4e:d5:ea:96:e2:6e: - 72:c1:bb:2a:fe:6c:6e:f8:91:98:46:fc:c9:1b:57:5b:ea:c8: - 1a:3b:3f:b0:51:98:3c:07:da:2c:59:01:da:8b:44:e8:e1:74: - fd:a7:68:dd:54:ba:83:46:ec:c8:46:b5:f8:af:97:c0:3b:09: - 1c:8f:ce:72:96:3d:33:56:70:bc:96:cb:d8:d5:7d:20:9a:83: - 9f:1a:dc:39:f1:c5:72:a3:11:03:fd:3b:42:52:29:db:e8:01: - f7:9b:5e:8c:d6:8d:86:4e:19:fa:bc:1c:be:c5:21:a5:87:9e: - 78:2e:36:db:09:71:a3:72:34:f8:6c:e3:06:09:f2:5e:56:a5: - d3:dd:98:fa:d4:e6:06:f4:f0:b6:20:63:4b:ea:29:bd:aa:82: - 66:1e:fb:81:aa:a7:37:ad:13:18:e6:92:c3:81:c1:33:bb:88: - 1e:a1:e7:e2:b4:bd:31:6c:0e:51:3d:6f:fb:96:56:80:e2:36: - 17:d1:dc:e4 -SHA1 Fingerprint=80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5 diff --git a/luni/src/main/files/cacerts/9282e51c.0 b/luni/src/main/files/cacerts/9282e51c.0 new file mode 100644 index 0000000..f2a9f94 --- /dev/null +++ b/luni/src/main/files/cacerts/9282e51c.0 @@ -0,0 +1,123 @@ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 407555286 (0x184accd6) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, O=China Financial Certification Authority, CN=CFCA EV ROOT + Validity + Not Before: Aug 8 03:07:01 2012 GMT + Not After : Dec 31 03:07:01 2029 GMT + Subject: C=CN, O=China Financial Certification Authority, CN=CFCA EV ROOT + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:d7:5d:6b:cd:10:3f:1f:05:59:d5:05:4d:37:b1: + 0e:ec:98:2b:8e:15:1d:fa:93:4b:17:82:21:71:10: + 52:d7:51:64:70:16:c2:55:69:4d:8e:15:6d:9f:bf: + 0c:1b:c2:e0:a3:67:d6:0c:ac:cf:22:ae:af:77:54: + 2a:4b:4c:8a:53:52:7a:c3:ee:2e:de:b3:71:25:c1: + e9:5d:3d:ee:a1:2f:a3:f7:2a:3c:c9:23:1d:6a:ab: + 1d:a1:a7:f1:f3:ec:a0:d5:44:cf:15:cf:72:2f:1d: + 63:97:e8:99:f9:fd:93:a4:54:80:4c:52:d4:52:ab: + 2e:49:df:90:cd:b8:5f:be:3f:de:a1:ca:4d:20:d4: + 25:e8:84:29:53:b7:b1:88:1f:ff:fa:da:90:9f:0a: + a9:2d:41:3f:b1:f1:18:29:ee:16:59:2c:34:49:1a: + a8:06:d7:a8:88:d2:03:72:7a:32:e2:ea:68:4d:6e: + 2c:96:65:7b:ca:59:fa:f2:e2:dd:ee:30:2c:fb:cc: + 46:ac:c4:63:eb:6f:7f:36:2b:34:73:12:94:7f:df: + cc:26:9e:f1:72:5d:50:65:59:8f:69:b3:87:5e:32: + 6f:c3:18:8a:b5:95:8f:b0:7a:37:de:5a:45:3b:c7: + 36:e1:ef:67:d1:39:d3:97:5b:73:62:19:48:2d:87: + 1c:06:fb:74:98:20:49:73:f0:05:d2:1b:b1:a0:a3: + b7:1b:70:d3:88:69:b9:5a:d6:38:f4:62:dc:25:8b: + 78:bf:f8:e8:7e:b8:5c:c9:95:4f:5f:a7:2d:b9:20: + 6b:cf:6b:dd:f5:0d:f4:82:b7:f4:b2:66:2e:10:28: + f6:97:5a:7b:96:16:8f:01:19:2d:6c:6e:7f:39:58: + 06:64:83:01:83:83:c3:4d:92:dd:32:c6:87:a4:37: + e9:16:ce:aa:2d:68:af:0a:81:65:3a:70:c1:9b:ad: + 4d:6d:54:ca:2a:2d:4b:85:1b:b3:80:e6:70:45:0d: + 6b:5e:35:f0:7f:3b:b8:9c:e4:04:70:89:12:25:93: + da:0a:99:22:60:6a:63:60:4e:76:06:98:4e:bd:83: + ad:1d:58:8a:25:85:d2:c7:65:1e:2d:8e:c6:df:b6: + c6:e1:7f:8a:04:21:15:29:74:f0:3e:9c:90:9d:0c: + 2e:f1:8a:3e:5a:aa:0c:09:1e:c7:d5:3c:a3:ed:97: + c3:1e:34:fa:38:f9:08:0e:e3:c0:5d:2b:83:d1:56: + 6a:c9:b6:a8:54:53:2e:78:32:67:3d:82:7f:74:d0: + fb:e1:b6:05:60:b9:70:db:8e:0b:f9:13:58:6f:71: + 60:10:52:10:b9:c1:41:09:ef:72:1f:67:31:78:ff: + 96:05:8d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:E3:FE:2D:FD:28:D0:0B:B5:BA:B6:A2:C4:BF:06:AA:05:8C:93:FB:2F + + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + E3:FE:2D:FD:28:D0:0B:B5:BA:B6:A2:C4:BF:06:AA:05:8C:93:FB:2F + Signature Algorithm: sha256WithRSAEncryption + 25:c6:ba:6b:eb:87:cb:de:82:39:96:3d:f0:44:a7:6b:84:73: + 03:de:9d:2b:4f:ba:20:7f:bc:78:b2:cf:97:b0:1b:9c:f3:d7: + 79:2e:f5:48:b6:d2:fb:17:88:e6:d3:7a:3f:ed:53:13:d0:e2: + 2f:6a:79:cb:00:23:28:e6:1e:37:57:35:89:84:c2:76:4f:34: + 36:ad:67:c3:ce:41:06:88:c5:f7:ee:d8:1a:b8:d6:0b:7f:50: + ff:93:aa:17:4b:8c:ec:ed:52:60:b2:a4:06:ea:4e:eb:f4:6b: + 19:fd:eb:f5:1a:e0:25:2a:9a:dc:c7:41:36:f7:c8:74:05:84: + 39:95:39:d6:0b:3b:a4:27:fa:08:d8:5c:1e:f8:04:60:52:11: + 28:28:03:ff:ef:53:66:00:a5:4a:34:16:66:7c:fd:09:a4:ae: + 9e:67:1a:6f:41:0b:6b:06:13:9b:8f:86:71:05:b4:2f:8d:89: + 66:33:29:76:54:9a:11:f8:27:fa:b2:3f:91:e0:ce:0d:1b:f3: + 30:1a:ad:bf:22:5d:1b:d3:bf:25:05:4d:e1:92:1a:7f:99:9f: + 3c:44:93:ca:d4:40:49:6c:80:87:d7:04:3a:c3:32:52:35:0e: + 56:f8:a5:dd:7d:c4:8b:0d:11:1f:53:cb:1e:b2:17:b6:68:77: + 5a:e0:d4:cb:c8:07:ae:f5:3a:2e:8e:37:b7:d0:01:4b:43:29: + 77:8c:39:97:8f:82:5a:f8:51:e5:89:a0:18:e7:68:7f:5d:0a: + 2e:fb:a3:47:0e:3d:a6:23:7a:c6:01:c7:8f:c8:5e:bf:6d:80: + 56:be:8a:24:ba:33:ea:9f:e1:32:11:9e:f1:d2:4f:80:f6:1b: + 40:af:38:9e:11:50:79:73:12:12:cd:e6:6c:9d:2c:88:72:3c: + 30:81:06:91:22:ea:59:ad:da:19:2e:22:c2:8d:b9:8c:87:e0: + 66:bc:73:23:5f:21:64:63:80:48:f5:a0:3c:18:3d:94:c8:48: + 41:1d:40:ba:5e:fe:fe:56:39:a1:c8:cf:5e:9e:19:64:46:10: + da:17:91:b7:05:80:ac:8b:99:92:7d:e7:a2:d8:07:0b:36:27: + e7:48:79:60:8a:c3:d7:13:5c:f8:72:40:df:4a:cb:cf:99:00: + 0a:00:0b:11:95:da:56:45:03:88:0a:9f:67:d0:d5:79:b1:a8: + 8d:40:6d:0d:c2:7a:40:fa:f3:5f:64:47:92:cb:53:b9:bb:59: + ce:4f:fd:d0:15:53:01:d8:df:eb:d9:e6:76:ef:d0:23:bb:3b: + a9:79:b3:d5:02:29:cd:89:a3:96:0f:4a:35:e7:4e:42:c0:75: + cd:07:cf:e6:2c:eb:7b:2e +SHA1 Fingerprint=E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 diff --git a/luni/src/main/files/cacerts/bda4cc84.0 b/luni/src/main/files/cacerts/bda4cc84.0 deleted file mode 100644 index 4dac2ad..0000000 --- a/luni/src/main/files/cacerts/bda4cc84.0 +++ /dev/null @@ -1,82 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP -bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2 -MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft -ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk -hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym -1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW -OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb -2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko -O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU -AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF -Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb -LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir -oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C -MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds -sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1 (0x1) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=America Online Inc., CN=America Online Root Certification Authority 1 - Validity - Not Before: May 28 06:00:00 2002 GMT - Not After : Nov 19 20:43:00 2037 GMT - Subject: C=US, O=America Online Inc., CN=America Online Root Certification Authority 1 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a8:2f:e8:a4:69:06:03:47:c3:e9:2a:98:ff:19: - a2:70:9a:c6:50:b2:7e:a5:df:68:4d:1b:7c:0f:b6: - 97:68:7d:2d:a6:8b:97:e9:64:86:c9:a3:ef:a0:86: - bf:60:65:9c:4b:54:88:c2:48:c5:4a:39:bf:14:e3: - 59:55:e5:19:b4:74:c8:b4:05:39:5c:16:a5:e2:95: - 05:e0:12:ae:59:8b:a2:33:68:58:1c:a6:d4:15:b7: - d8:9f:d7:dc:71:ab:7e:9a:bf:9b:8e:33:0f:22:fd: - 1f:2e:e7:07:36:ef:62:39:c5:dd:cb:ba:25:14:23: - de:0c:c6:3d:3c:ce:82:08:e6:66:3e:da:51:3b:16: - 3a:a3:05:7f:a0:dc:87:d5:9c:fc:72:a9:a0:7d:78: - e4:b7:31:55:1e:65:bb:d4:61:b0:21:60:ed:10:32: - 72:c5:92:25:1e:f8:90:4a:18:78:47:df:7e:30:37: - 3e:50:1b:db:1c:d3:6b:9a:86:53:07:b0:ef:ac:06: - 78:f8:84:99:fe:21:8d:4c:80:b6:0c:82:f6:66:70: - 79:1a:d3:4f:a3:cf:f1:cf:46:b0:4b:0f:3e:dd:88: - 62:b8:8c:a9:09:28:3b:7a:c7:97:e1:1e:e5:f4:9f: - c0:c0:ae:24:a0:c8:a1:d9:0f:d6:7b:26:82:69:32: - 3d:a7 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Subject Key Identifier: - 00:AD:D9:A3:F6:79:F6:6E:74:A9:7F:33:3D:81:17:D7:4C:CF:33:DE - X509v3 Authority Key Identifier: - keyid:00:AD:D9:A3:F6:79:F6:6E:74:A9:7F:33:3D:81:17:D7:4C:CF:33:DE - - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - Signature Algorithm: sha1WithRSAEncryption - 7c:8a:d1:1f:18:37:82:e0:b8:b0:a3:ed:56:95:c8:62:61:9c: - 05:a2:cd:c2:62:26:61:cd:10:16:d7:cc:b4:65:34:d0:11:8a: - ad:a8:a9:05:66:ef:74:f3:6d:5f:9d:99:af:f6:8b:fb:eb:52: - b2:05:98:a2:6f:2a:c5:54:bd:25:bd:5f:ae:c8:86:ea:46:2c: - c1:b3:bd:c1:e9:49:70:18:16:97:08:13:8c:20:e0:1b:2e:3a: - 47:cb:1e:e4:00:30:95:5b:f4:45:a3:c0:1a:b0:01:4e:ab:bd: - c0:23:6e:63:3f:80:4a:c5:07:ed:dc:e2:6f:c7:c1:62:f1:e3: - 72:d6:04:c8:74:67:0b:fa:88:ab:a1:01:c8:6f:f0:14:af:d2: - 99:cd:51:93:7e:ed:2e:38:c7:bd:ce:46:50:3d:72:e3:79:25: - 9d:9b:88:2b:10:20:dd:a5:b8:32:9f:8d:e0:29:df:21:74:86: - 82:db:2f:82:30:c6:c7:35:86:b3:f9:96:5f:46:db:0c:45:fd: - f3:50:c3:6f:c6:c3:48:ad:46:a6:e1:27:47:0a:1d:0e:9b:b6: - c2:77:7f:63:f2:e0:7d:1a:be:fc:e0:df:d7:c7:a7:6c:b0:f9: - ae:ba:3c:fd:74:b4:11:e8:58:0d:80:bc:d3:a8:80:3a:99:ed: - 75:cc:46:7b -SHA1 Fingerprint=39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A diff --git a/luni/src/main/files/cacerts/c33a80d4.0 b/luni/src/main/files/cacerts/c33a80d4.0 deleted file mode 100644 index 8225654..0000000 --- a/luni/src/main/files/cacerts/c33a80d4.0 +++ /dev/null @@ -1,58 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDNjCCAp+gAwIBAgIQNhIilsXjOKUgodJfTNcJVDANBgkqhkiG9w0BAQUFADCB -zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ -Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE -CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh -d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl -cnZlckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIxMDEwMTIzNTk1OVow -gc4xCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcT -CUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNV -BAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRo -YXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1z -ZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 -aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560 -ZXUCTe/LCaIhUdib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j -+ao6hnO2RlNYyIkFvYMRuHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/ -BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBlkKyID1bZ5jA01CbH0FDxkt5r1DmI -CSLGpmODA/eZd9iy5Ri4XWPz1HP7bJyZePFLeH0ZJMMrAoT4vCLZiiLXoPxx7JGH -IPG47LHlVYCsPVLIOQ7C8MAFT9aCdYy9X9LcdpoFEsmvcsPcJX6kTY4XpeCHf+Ga -WuFg3GQjPEIuTQ== ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 36:12:22:96:c5:e3:38:a5:20:a1:d2:5f:4c:d7:09:54 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com - Validity - Not Before: Aug 1 00:00:00 1996 GMT - Not After : Jan 1 23:59:59 2021 GMT - Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (1024 bit) - Modulus: - 00:d2:36:36:6a:8b:d7:c2:5b:9e:da:81:41:62:8f: - 38:ee:49:04:55:d6:d0:ef:1c:1b:95:16:47:ef:18: - 48:35:3a:52:f4:2b:6a:06:8f:3b:2f:ea:56:e3:af: - 86:8d:9e:17:f7:9e:b4:65:75:02:4d:ef:cb:09:a2: - 21:51:d8:9b:d0:67:d0:ba:0d:92:06:14:73:d4:93: - cb:97:2a:00:9c:5c:4e:0c:bc:fa:15:52:fc:f2:44: - 6e:da:11:4a:6e:08:9f:2f:2d:e3:f9:aa:3a:86:73: - b6:46:53:58:c8:89:05:bd:83:11:b8:73:3f:aa:07: - 8d:f4:42:4d:e7:40:9d:1c:37 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - Signature Algorithm: sha1WithRSAEncryption - 65:90:ac:88:0f:56:d9:e6:30:34:d4:26:c7:d0:50:f1:92:de: - 6b:d4:39:88:09:22:c6:a6:63:83:03:f7:99:77:d8:b2:e5:18: - b8:5d:63:f3:d4:73:fb:6c:9c:99:78:f1:4b:78:7d:19:24:c3: - 2b:02:84:f8:bc:22:d9:8a:22:d7:a0:fc:71:ec:91:87:20:f1: - b8:ec:b1:e5:55:80:ac:3d:52:c8:39:0e:c2:f0:c0:05:4f:d6: - 82:75:8c:bd:5f:d2:dc:76:9a:05:12:c9:af:72:c3:dc:25:7e: - a4:4d:8e:17:a5:e0:87:7f:e1:9a:5a:e1:60:dc:64:23:3c:42: - 2e:4d -SHA1 Fingerprint=E0:AB:05:94:20:72:54:93:05:60:62:02:36:70:F7:CD:2E:FC:66:66 diff --git a/luni/src/main/files/cacerts/d18e9066.0 b/luni/src/main/files/cacerts/d18e9066.0 new file mode 100644 index 0000000..fd686a6 --- /dev/null +++ b/luni/src/main/files/cacerts/d18e9066.0 @@ -0,0 +1,120 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=IdenTrust, CN=IdenTrust Commercial Root CA 1 + Validity + Not Before: Jan 16 18:12:23 2014 GMT + Not After : Jan 16 18:12:23 2034 GMT + Subject: C=US, O=IdenTrust, CN=IdenTrust Commercial Root CA 1 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:a7:50:19:de:3f:99:3d:d4:33:46:f1:6f:51:61: + 82:b2:a9:4f:8f:67:89:5d:84:d9:53:dd:0c:28:d9: + d7:f0:ff:ae:95:43:72:99:f9:b5:5d:7c:8a:c1:42: + e1:31:50:74:d1:81:0d:7c:cd:9b:21:ab:43:e2:ac: + ad:5e:86:6e:f3:09:8a:1f:5a:32:bd:a2:eb:94:f9: + e8:5c:0a:ec:ff:98:d2:af:71:b3:b4:53:9f:4e:87: + ef:92:bc:bd:ec:4f:32:30:88:4b:17:5e:57:c4:53: + c2:f6:02:97:8d:d9:62:2b:bf:24:1f:62:8d:df:c3: + b8:29:4b:49:78:3c:93:60:88:22:fc:99:da:36:c8: + c2:a2:d4:2c:54:00:67:35:6e:73:bf:02:58:f0:a4: + dd:e5:b0:a2:26:7a:ca:e0:36:a5:19:16:f5:fd:b7: + ef:ae:3f:40:f5:6d:5a:04:fd:ce:34:ca:24:dc:74: + 23:1b:5d:33:13:12:5d:c4:01:25:f6:30:dd:02:5d: + 9f:e0:d5:47:bd:b4:eb:1b:a1:bb:49:49:d8:9f:5b: + 02:f3:8a:e4:24:90:e4:62:4f:4f:c1:af:8b:0e:74: + 17:a8:d1:72:88:6a:7a:01:49:cc:b4:46:79:c6:17: + b1:da:98:1e:07:59:fa:75:21:85:65:dd:90:56:ce: + fb:ab:a5:60:9d:c4:9d:f9:52:b0:8b:bd:87:f9:8f: + 2b:23:0a:23:76:3b:f7:33:e1:c9:00:f3:69:f9:4b: + a2:e0:4e:bc:7e:93:39:84:07:f7:44:70:7e:fe:07: + 5a:e5:b1:ac:d1:18:cc:f2:35:e5:49:49:08:ca:56: + c9:3d:fb:0f:18:7d:8b:3b:c1:13:c2:4d:8f:c9:4f: + 0e:37:e9:1f:a1:0e:6a:df:62:2e:cb:35:06:51:79: + 2c:c8:25:38:f4:fa:4b:a7:89:5c:9c:d2:e3:0d:39: + 86:4a:74:7c:d5:59:87:c2:3f:4e:0c:5c:52:f4:3d: + f7:52:82:f1:ea:a3:ac:fd:49:34:1a:28:f3:41:88: + 3a:13:ee:e8:de:ff:99:1d:5f:ba:cb:e8:1e:f2:b9: + 50:60:c0:31:d3:73:e5:ef:be:a0:ed:33:0b:74:be: + 20:20:c4:67:6c:f0:08:03:7a:55:80:7f:46:4e:96: + a7:f4:1e:3e:e1:f6:d8:09:e1:33:64:2b:63:d7:32: + 5e:9f:f9:c0:7b:0f:78:6f:97:bc:93:9a:f9:9c:12: + 90:78:7a:80:87:15:d7:72:74:9c:55:74:78:b1:ba: + e1:6e:70:04:ba:4f:a0:ba:68:c3:7b:ff:31:f0:73: + 3d:3d:94:2a:b1:0b:41:0e:a0:fe:4d:88:65:6b:79: + 33:b4:d7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + ED:44:19:C0:D3:F0:06:8B:EE:A4:7B:BE:42:E7:26:54:C8:8E:36:76 + Signature Algorithm: sha256WithRSAEncryption + 0d:ae:90:32:f6:a6:4b:7c:44:76:19:61:1e:27:28:cd:5e:54: + ef:25:bc:e3:08:90:f9:29:d7:ae:68:08:e1:94:00:58:ef:2e: + 2e:7e:53:52:8c:b6:5c:07:ea:88:ba:99:8b:50:94:d7:82:80: + df:61:09:00:93:ad:0d:14:e6:ce:c1:f2:37:94:78:b0:5f:9c: + b3:a2:73:b8:8f:05:93:38:cd:8d:3e:b0:b8:fb:c0:cf:b1:f2: + ec:2d:2d:1b:cc:ec:aa:9a:b3:aa:60:82:1b:2d:3b:c3:84:3d: + 57:8a:96:1e:9c:75:b8:d3:30:cd:60:08:83:90:d3:8e:54:f1: + 4d:66:c0:5d:74:03:40:a3:ee:85:7e:c2:1f:77:9c:06:e8:c1: + a7:18:5d:52:95:ed:c9:dd:25:9e:6d:fa:a9:ed:a3:3a:34:d0: + 59:7b:da:ed:50:f3:35:bf:ed:eb:14:4d:31:c7:60:f4:da:f1: + 87:9c:e2:48:e2:c6:c5:37:fb:06:10:fa:75:59:66:31:47:29: + da:76:9a:1c:e9:82:ae:ef:9a:b9:51:f7:88:23:9a:69:95:62: + 3c:e5:55:80:36:d7:54:02:ff:f1:b9:5d:ce:d4:23:6f:d8:45: + 84:4a:5b:65:ef:89:0c:dd:14:a7:20:cb:18:a5:25:b4:0d:f9: + 01:f0:a2:d2:f4:00:c8:74:8e:a1:2a:48:8e:65:db:13:c4:e2: + 25:17:7d:eb:be:87:5b:17:20:54:51:93:4a:53:03:0b:ec:5d: + ca:33:ed:62:fd:45:c7:2f:5b:dc:58:a0:80:39:e6:fa:d7:fe: + 13:14:a6:ed:3d:94:4a:42:74:d4:c3:77:59:73:cd:8f:46:be: + 55:38:ef:fa:e8:91:32:ea:97:58:04:22:de:38:c3:cc:bc:6d: + c9:33:3a:6a:0a:69:3f:a0:c8:ea:72:8f:8c:63:86:23:bd:6d: + 3c:96:9e:95:e0:49:4c:aa:a2:b9:2a:1b:9c:36:81:78:ed:c3: + e8:46:e2:26:59:44:75:1e:d9:75:89:51:cd:10:84:9d:61:60: + cb:5d:f9:97:22:4d:8e:98:e6:e3:7f:f6:5b:bb:ae:cd:ca:4a: + 81:6b:5e:0b:f3:51:e1:74:2b:e9:7e:27:a7:d9:99:49:4e:f8: + a5:80:db:25:0f:1c:63:62:8a:c9:33:67:6b:3c:10:83:c6:ad: + de:a8:cd:16:8e:8d:f0:07:37:71:9f:f2:ab:fc:41:f5:c1:8b: + ec:00:37:5d:09:e5:4e:80:ef:fa:b1:5c:38:06:a5:1b:4a:e1: + dc:38:2d:3c:dc:ab:1f:90:1a:d5:4a:9c:ee:d1:70:6c:cc:ee: + f4:57:f8:18:ba:84:6e:87 +SHA1 Fingerprint=DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 diff --git a/luni/src/main/files/cacerts/d6e6eab9.0 b/luni/src/main/files/cacerts/d6e6eab9.0 new file mode 100644 index 0000000..aff6bdf --- /dev/null +++ b/luni/src/main/files/cacerts/d6e6eab9.0 @@ -0,0 +1,123 @@ +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=FR, O=Certinomis, OU=0002 433998903, CN=Certinomis - Root CA + Validity + Not Before: Oct 21 09:17:18 2013 GMT + Not After : Oct 21 09:17:18 2033 GMT + Subject: C=FR, O=Certinomis, OU=0002 433998903, CN=Certinomis - Root CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:d4:cc:09:0a:2c:3f:92:f6:7f:14:9e:0b:9c:9a: + 6a:1d:40:30:64:fd:aa:df:0e:1e:06:5b:9f:50:85: + ea:cd:8d:ab:43:67:de:b0:fa:7e:80:96:9e:84:78: + 92:48:d6:e3:39:ee:ce:e4:59:58:97:e5:2e:27:98: + ea:93:a8:77:9b:4a:f0:ef:74:80:2d:eb:30:1f:b5: + d9:c7:80:9c:62:27:91:88:f0:4a:89:dd:dc:88:e6: + 14:f9:d5:03:2f:ff:95:db:bd:9f:ec:2c:fa:14:15: + 59:95:0a:c6:47:7c:69:18:b9:a7:03:f9:ca:76:a9: + cf:c7:6f:b4:5e:05:fe:ee:c1:52:b2:75:32:87:ec: + ed:29:66:3b:f3:4a:16:82:f6:d6:9a:db:72:98:e9: + de:f0:c5:4c:a5:ab:b5:ea:01:e2:8c:2e:64:7f:64: + 6f:fd:a3:25:93:8b:c8:a2:0e:49:8d:34:f0:1f:ec: + 58:45:2e:34:aa:84:50:bd:e7:b2:4a:13:b8:b0:0f: + ae:38:5d:b0:a9:1b:e6:73:c9:5a:a1:d9:66:40:aa: + a9:4d:a6:34:02:ad:84:7e:b2:23:c1:fb:2a:c6:67: + f4:34:b6:b0:95:6a:33:4f:71:44:b5:ad:c0:79:33: + 88:e0:bf:ed:a3:a0:14:b4:9c:09:b0:0a:e3:60:be: + f8:f8:66:88:cd:5b:f1:77:05:e0:b5:73:6e:c1:7d: + 46:2e:8e:4b:27:a6:cd:35:0a:fd:e5:4d:7d:aa:2a: + a3:29:c7:5a:68:04:e8:e5:d6:93:a4:62:c2:c5:e6: + f4:4f:c6:f9:9f:1a:8d:82:49:19:8a:ca:59:43:3a: + e8:0d:32:c1:f4:4c:13:03:6f:6e:a6:3f:91:73:cb: + ca:73:6f:12:20:8b:ee:c0:82:78:de:4b:2e:c2:49: + c3:1d:ed:16:f6:24:f4:27:1b:5c:57:31:dc:55:ee: + a8:1e:6f:6c:ac:e2:45:cc:57:57:8a:75:57:19:e0: + b5:58:99:49:36:31:3c:33:01:6d:16:4a:cd:b8:2a: + 83:84:86:9b:f9:60:d2:1f:6d:91:03:d3:60:a6:d5: + 3d:9a:dd:77:90:3d:35:a4:9f:0f:5e:f5:52:44:69: + b9:c0:ba:dc:cf:7d:df:7c:d9:c4:ac:86:22:32:bc: + 7b:6b:91:ef:7a:f8:17:68:b0:e2:53:55:60:2d:af: + 3e:c2:83:d8:d9:09:2b:f0:c0:64:db:87:8b:91:cc: + 91:eb:04:fd:76:b4:95:9a:e6:14:06:1b:d5:34:1d: + be:d8:ff:74:1c:53:85:99:e0:59:52:4a:61:ed:88: + 9e:6b:49:89:46:7e:20:5a:d9:e7:4a:e5:6a:ee:d2: + 65:11:43 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + EF:91:4C:F5:A5:C3:30:E8:2F:08:EA:D3:71:22:A4:92:68:78:74:D9 + X509v3 Authority Key Identifier: + keyid:EF:91:4C:F5:A5:C3:30:E8:2F:08:EA:D3:71:22:A4:92:68:78:74:D9 + + Signature Algorithm: sha256WithRSAEncryption + 7e:3d:54:da:22:5d:1a:58:3e:3b:54:27:ba:ba:cc:c8:e3:1a: + 6a:ea:3e:f9:12:eb:56:5f:3d:50:ce:e0:ea:48:26:26:cf:79: + 56:7e:91:1c:99:3f:d0:a1:91:1c:2c:0f:4f:98:95:59:53:bd: + d0:22:d8:88:5d:9c:37:fc:fb:64:c1:78:8c:8b:9a:60:09:ea: + d5:fa:21:5f:d0:74:65:e7:50:c5:bf:2e:b9:0b:0b:ad:b5:b0: + 17:a6:12:8c:d4:62:78:ea:56:6a:ec:0a:d2:40:c3:3c:05:30: + 3e:4d:94:b7:9f:4a:03:d3:7d:27:4b:b6:fe:44:ce:fa:19:33: + 1a:6d:a4:42:d1:dd:cc:c8:c8:d7:16:52:83:4f:35:94:b3:12: + 55:7d:e5:e2:42:eb:e4:9c:93:09:c0:4c:5b:07:ab:c7:6d:11: + a0:50:17:94:23:a8:b5:0a:92:0f:b2:7a:c1:60:2c:38:cc:1a: + a6:5b:ff:f2:0c:e3:aa:1f:1c:dc:b8:a0:93:27:de:63:e3:7f: + 21:9f:3a:e5:9e:fa:e0:13:6a:75:eb:96:5c:62:91:94:8e:67: + 53:b6:89:f8:12:09:cb:6f:52:5b:03:72:86:50:95:08:d4:8d: + 87:86:15:1f:95:24:d8:a4:6f:9a:ce:a4:9d:9b:6d:d2:b2:76: + 06:86:c6:56:08:c5:eb:09:da:36:c2:1b:5b:41:be:61:2a:e3: + 70:e6:b8:a6:f8:b6:5a:c4:bd:21:f7:ff:aa:5f:a1:6c:76:39: + 66:d6:ea:4c:55:e1:00:33:9b:13:98:63:c9:6f:d0:01:20:09: + 37:52:e7:0c:4f:3e:cd:bc:f5:5f:96:27:a7:20:02:95:e0:2e: + e8:07:41:05:1f:15:6e:d6:b0:e4:19:e0:0f:02:93:00:27:72: + c5:8b:d1:54:1f:5d:4a:c3:40:97:7e:55:a6:7c:c1:33:04:14: + 01:1d:49:20:69:0b:19:93:9d:6e:58:22:f7:40:0c:46:0c:23: + 63:f3:39:d2:7f:76:51:a7:f4:c8:a1:f1:0c:76:22:23:46:52: + 29:2d:e2:a3:41:07:56:69:98:d2:05:09:bc:69:c7:5a:61:cd: + 8f:81:60:15:4d:80:dd:90:e2:7d:c4:50:f2:8c:3b:6e:4a:c7: + c6:e6:80:2b:3c:81:bc:11:80:16:10:27:d7:f0:cd:3f:79:cc: + 73:2a:c3:7e:53:91:d6:6e:f8:f5:f3:c7:d0:51:4d:8e:4b:a5: + 5b:e6:19:17:3b:d6:81:09:dc:22:dc:ee:8e:b9:c4:8f:53:e1: + 67:bb:33:b8:88:15:46:cf:ed:69:35:ff:75:0d:46:f3:ce:71: + e1:c5:6b:86:42:06:b9:41 +SHA1 Fingerprint=9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8 diff --git a/luni/src/main/files/cacerts/ddc328ff.0 b/luni/src/main/files/cacerts/ddc328ff.0 deleted file mode 100644 index bcc8a9a..0000000 --- a/luni/src/main/files/cacerts/ddc328ff.0 +++ /dev/null @@ -1,57 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDIjCCAougAwIBAgIQNKT/9jCvTKU8MxdCoZRmdTANBgkqhkiG9w0BAQUFADCB -xDELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ -Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE -CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhh -d3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 -ZS5jb20wHhcNOTYwODAxMDAwMDAwWhcNMjEwMTAxMjM1OTU5WjCBxDELMAkGA1UE -BhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du -MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZl -ciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8w -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl -/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF -/rFrKbYvScg71CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982 -OsK1ZiIS1ocNAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF -BQADgYEAvkBpQW/G28GnvwfAReTQtUMeTJUzNelewj4o9qgNUNX/4gwP/FACjq6R -ua00io2fJ3GqGcxL6ATK1BdrEhrWxl/WzV7/iXa/2EjYWb0IiokdV81FHlK6EpqE -+hiJX+j5MDVqAWC5mYCDhQpu2vTJj15zLTFKY6B08h+LItIpPus= ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 34:a4:ff:f6:30:af:4c:a5:3c:33:17:42:a1:94:66:75 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com - Validity - Not Before: Aug 1 00:00:00 1996 GMT - Not After : Jan 1 23:59:59 2021 GMT - Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (1024 bit) - Modulus: - 00:d3:a4:50:6e:c8:ff:56:6b:e6:cf:5d:b6:ea:0c: - 68:75:47:a2:aa:c2:da:84:25:fc:a8:f4:47:51:da: - 85:b5:20:74:94:86:1e:0f:75:c9:e9:08:61:f5:06: - 6d:30:6e:15:19:02:e9:52:c0:62:db:4d:99:9e:e2: - 6a:0c:44:38:cd:fe:be:e3:64:09:70:c5:fe:b1:6b: - 29:b6:2f:49:c8:3b:d4:27:04:25:10:97:2f:e7:90: - 6d:c0:28:42:99:d7:4c:43:de:c3:f5:21:6d:54:9f: - 5d:c3:58:e1:c0:e4:d9:5b:b0:b8:dc:b4:7b:df:36: - 3a:c2:b5:66:22:12:d6:87:0d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - Signature Algorithm: sha1WithRSAEncryption - be:40:69:41:6f:c6:db:c1:a7:bf:07:c0:45:e4:d0:b5:43:1e: - 4c:95:33:35:e9:5e:c2:3e:28:f6:a8:0d:50:d5:ff:e2:0c:0f: - fc:50:02:8e:ae:91:b9:ad:34:8a:8d:9f:27:71:aa:19:cc:4b: - e8:04:ca:d4:17:6b:12:1a:d6:c6:5f:d6:cd:5e:ff:89:76:bf: - d8:48:d8:59:bd:08:8a:89:1d:57:cd:45:1e:52:ba:12:9a:84: - fa:18:89:5f:e8:f9:30:35:6a:01:60:b9:99:80:83:85:0a:6e: - da:f4:c9:8f:5e:73:2d:31:4a:63:a0:74:f2:1f:8b:22:d2:29: - 3e:eb -SHA1 Fingerprint=9F:AD:91:A6:CE:6A:C6:C5:00:47:C4:4E:C9:D4:A5:0D:92:D8:49:79 diff --git a/luni/src/main/files/cacerts/e7b8d656.0 b/luni/src/main/files/cacerts/e7b8d656.0 deleted file mode 100644 index a019756..0000000 --- a/luni/src/main/files/cacerts/e7b8d656.0 +++ /dev/null @@ -1,60 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT -ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw -MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j -LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ -KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo -RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu -WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw -Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK -eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM -zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ -WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN -/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 4 (0x4) - Signature Algorithm: md5WithRSAEncryption - Issuer: C=US, O=Equifax Secure Inc., CN=Equifax Secure eBusiness CA-1 - Validity - Not Before: Jun 21 04:00:00 1999 GMT - Not After : Jun 21 04:00:00 2020 GMT - Subject: C=US, O=Equifax Secure Inc., CN=Equifax Secure eBusiness CA-1 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (1024 bit) - Modulus: - 00:ce:2f:19:bc:17:b7:77:de:93:a9:5f:5a:0d:17: - 4f:34:1a:0c:98:f4:22:d9:59:d4:c4:68:46:f0:b4: - 35:c5:85:03:20:c6:af:45:a5:21:51:45:41:eb:16: - 58:36:32:6f:e2:50:62:64:f9:fd:51:9c:aa:24:d9: - f4:9d:83:2a:87:0a:21:d3:12:38:34:6c:8d:00:6e: - 5a:a0:d9:42:ee:1a:21:95:f9:52:4c:55:5a:c5:0f: - 38:4f:46:fa:6d:f8:2e:35:d6:1d:7c:eb:e2:f0:b0: - 75:80:c8:a9:13:ac:be:88:ef:3a:6e:ab:5f:2a:38: - 62:02:b0:12:7b:fe:8f:a6:03 - Exponent: 65537 (0x10001) - X509v3 extensions: - Netscape Cert Type: - SSL CA, S/MIME CA, Object Signing CA - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Authority Key Identifier: - keyid:4A:78:32:52:11:DB:59:16:36:5E:DF:C1:14:36:40:6A:47:7C:4C:A1 - - X509v3 Subject Key Identifier: - 4A:78:32:52:11:DB:59:16:36:5E:DF:C1:14:36:40:6A:47:7C:4C:A1 - Signature Algorithm: md5WithRSAEncryption - 75:5b:a8:9b:03:11:e6:e9:56:4c:cd:f9:a9:4c:c0:0d:9a:f3: - cc:65:69:e6:25:76:cc:59:b7:d6:54:c3:1d:cd:99:ac:19:dd: - b4:85:d5:e0:3d:fc:62:20:a7:84:4b:58:65:f1:e2:f9:95:21: - 3f:f5:d4:7e:58:1e:47:87:54:3e:58:a1:b5:b5:f8:2a:ef:71: - e7:bc:c3:f6:b1:49:46:e2:d7:a0:6b:e5:56:7a:9a:27:98:7c: - 46:62:14:e7:c9:fc:6e:03:12:79:80:38:1d:48:82:8d:fc:17: - fe:2a:96:2b:b5:62:a6:a6:3d:bd:7f:92:59:cd:5a:2a:82:b2: - 37:79 -SHA1 Fingerprint=DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41 diff --git a/luni/src/main/files/cacerts/eb375c3e.0 b/luni/src/main/files/cacerts/eb375c3e.0 deleted file mode 100644 index 739b045..0000000 --- a/luni/src/main/files/cacerts/eb375c3e.0 +++ /dev/null @@ -1,77 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg -Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL -MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD -VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg -isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z -NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI -+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R -hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+ -mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD -AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP -Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s -EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2 -mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC -e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow -dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 2 (0x2) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 CA 1 - Validity - Not Before: May 9 14:13:03 2005 GMT - Not After : May 9 14:13:03 2015 GMT - Subject: C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 CA 1 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a4:8e:d7:74:d9:29:64:de:5f:1f:87:80:91:ea: - 4e:39:e6:19:c6:44:0b:80:d5:0b:af:53:07:8b:12: - bd:e6:67:f0:02:b1:89:f6:60:8a:c4:5b:b0:42:d1: - c0:21:a8:cb:e1:9b:ef:64:51:b6:a7:cf:15:f5:74: - 80:68:04:90:a0:58:a2:e6:74:a6:53:53:55:48:63: - 3f:92:56:dd:24:4e:8e:f8:ba:2b:ff:f3:34:8a:9e: - 28:d7:34:9f:ac:2f:d6:0f:f1:a4:2f:bd:52:b2:49: - 85:6d:39:35:f0:44:30:93:46:24:f3:b6:e7:53:fb: - bc:61:af:a9:a3:14:fb:c2:17:17:84:6c:e0:7c:88: - f8:c9:1c:57:2c:f0:3d:7e:94:bc:25:93:84:e8:9a: - 00:9a:45:05:42:57:80:f4:4e:ce:d9:ae:39:f6:c8: - 53:10:0c:65:3a:47:7b:60:c2:d6:fa:91:c9:c6:71: - 6c:bd:91:87:3c:91:86:49:ab:f3:0f:a0:6c:26:76: - 5e:1c:ac:9b:71:e5:8d:bc:9b:21:1e:9c:d6:38:7e: - 24:80:15:31:82:96:b1:49:d3:62:37:5b:88:0c:0a: - 62:34:fe:a7:48:7e:99:b1:30:8b:90:37:95:1c:a8: - 1f:a5:2c:8d:f4:55:c8:db:dd:59:0a:c2:ad:78:a0: - f4:8b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Subject Key Identifier: - 38:14:E6:C8:F0:A9:A4:03:F4:4E:3E:22:A3:5B:F2:D6:E0:AD:40:74 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Signature Algorithm: sha1WithRSAEncryption - 01:67:a3:8c:c9:25:3d:13:63:5d:16:6f:ec:a1:3e:09:5c:91: - 15:2a:2a:d9:80:21:4f:05:dc:bb:a5:89:ab:13:33:2a:9e:38: - b7:8c:6f:02:72:63:c7:73:77:1e:09:06:ba:3b:28:7b:a4:47: - c9:61:6b:08:08:20:fc:8a:05:8a:1f:bc:ba:c6:c2:fe:cf:6e: - ec:13:33:71:67:2e:69:fa:a9:2c:3f:66:c0:12:59:4d:0b:54: - 02:92:84:bb:db:12:ef:83:70:70:78:c8:53:fa:df:c6:c6:ff: - dc:88:2f:07:c0:49:9d:32:57:60:d3:f2:f6:99:29:5f:e7:aa: - 01:cc:ac:33:a8:1c:0a:bb:91:c4:03:a0:6f:b6:34:f9:86:d3: - b3:76:54:98:f4:4a:81:b3:53:9d:4d:40:ec:e5:77:13:45:af: - 5b:aa:1f:d8:2f:4c:82:7b:fe:2a:c4:58:bb:4f:fc:9e:fd:03: - 65:1a:2a:0e:c3:a5:20:16:94:6b:79:a6:a2:12:b4:bb:1a:a4: - 23:7a:5f:f0:ae:84:24:e4:f3:2b:fb:8a:24:a3:27:98:65:da: - 30:75:76:fc:19:91:e8:db:eb:9b:3f:32:bf:40:97:07:26:ba: - cc:f3:94:85:4a:7a:27:93:cf:90:42:d4:b8:5b:16:a6:e7:cb: - 40:03:dd:79 -SHA1 Fingerprint=61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71 diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java index fcecf18..a1e87c8 100644 --- a/luni/src/main/java/android/system/Os.java +++ b/luni/src/main/java/android/system/Os.java @@ -215,6 +215,8 @@ public final class Os { */ public static int getuid() { return Libcore.os.getuid(); } + /** @hide */ public static int getxattr(String path, String name, byte[] outValue) throws ErrnoException { return Libcore.os.getxattr(path, name, outValue); } + /** * See <a href="http://man7.org/linux/man-pages/man3/if_indextoname.3.html">if_indextoname(3)</a>. */ @@ -389,6 +391,8 @@ public final class Os { */ public static void remove(String path) throws ErrnoException { Libcore.os.remove(path); } + /** @hide */ public static void removexattr(String path, String name) throws ErrnoException { Libcore.os.removexattr(path, name); } + /** * See <a href="http://man7.org/linux/man-pages/man2/rename.2.html">rename(2)</a>. */ @@ -468,6 +472,8 @@ public final class Os { */ public static void setuid(int uid) throws ErrnoException { Libcore.os.setuid(uid); } + /** @hide */ public static void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException { Libcore.os.setxattr(path, name, value, flags); }; + /** * See <a href="http://man7.org/linux/man-pages/man2/shutdown.2.html">shutdown(2)</a>. */ diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java index c0d31e5..8832f3d 100644 --- a/luni/src/main/java/android/system/OsConstants.java +++ b/luni/src/main/java/android/system/OsConstants.java @@ -207,6 +207,7 @@ public final class OsConstants { public static final int ENOLINK = placeholder(); public static final int ENOMEM = placeholder(); public static final int ENOMSG = placeholder(); + /** @hide */ public static final int ENONET = placeholder(); public static final int ENOPROTOOPT = placeholder(); public static final int ENOSPC = placeholder(); public static final int ENOSR = placeholder(); @@ -455,15 +456,15 @@ public final class OsConstants { public static final int STDERR_FILENO = placeholder(); public static final int STDIN_FILENO = placeholder(); public static final int STDOUT_FILENO = placeholder(); - /** @hide */ public static final int ST_MANDLOCK = placeholder(); - /** @hide */ public static final int ST_NOATIME = placeholder(); - /** @hide */ public static final int ST_NODEV = placeholder(); - /** @hide */ public static final int ST_NODIRATIME = placeholder(); - /** @hide */ public static final int ST_NOEXEC = placeholder(); - /** @hide */ public static final int ST_NOSUID = placeholder(); - /** @hide */ public static final int ST_RDONLY = placeholder(); - /** @hide */ public static final int ST_RELATIME = placeholder(); - /** @hide */ public static final int ST_SYNCHRONOUS = placeholder(); + public static final int ST_MANDLOCK = placeholder(); + public static final int ST_NOATIME = placeholder(); + public static final int ST_NODEV = placeholder(); + public static final int ST_NODIRATIME = placeholder(); + public static final int ST_NOEXEC = placeholder(); + public static final int ST_NOSUID = placeholder(); + public static final int ST_RDONLY = placeholder(); + public static final int ST_RELATIME = placeholder(); + public static final int ST_SYNCHRONOUS = placeholder(); public static final int S_IFBLK = placeholder(); public static final int S_IFCHR = placeholder(); public static final int S_IFDIR = placeholder(); @@ -495,6 +496,8 @@ public final class OsConstants { public static final int WSTOPPED = placeholder(); public static final int WUNTRACED = placeholder(); public static final int W_OK = placeholder(); + /** @hide */ public static final int XATTR_CREATE = placeholder(); + /** @hide */ public static final int XATTR_REPLACE = placeholder(); public static final int X_OK = placeholder(); public static final int _SC_2_CHAR_TERM = placeholder(); public static final int _SC_2_C_BIND = placeholder(); @@ -783,6 +786,9 @@ public final class OsConstants { if (errno == ENOMSG) { return "ENOMSG"; } + if (errno == ENONET) { + return "ENONET"; + } if (errno == ENOPROTOOPT) { return "ENOPROTOOPT"; } diff --git a/luni/src/main/java/java/lang/IllegalAccessError.java b/luni/src/main/java/java/lang/IllegalAccessError.java index 3f7cf86..582de12 100644 --- a/luni/src/main/java/java/lang/IllegalAccessError.java +++ b/luni/src/main/java/java/lang/IllegalAccessError.java @@ -18,8 +18,14 @@ package java.lang; /** - * Thrown when the VM notices that a program tries access a field - * which is not accessible from where it is referenced. + * Thrown when the runtime notices that a program tries to access a class or member + * which is not accessible from where it is referenced. Some examples are: + * <ul> + * <li>The superclass or an implemented interface is not accessible in the subclass. + * <li>Reading or writing an inaccessible field, e.g., a private field in another class. + * <li>Invoking an inaccessible method, e.g., the constructor of an inaccessible class, + * or a private method of another class. + * </ul> * <p> * Note that this can only occur when inconsistent class files have been loaded. */ diff --git a/luni/src/main/java/java/lang/Runtime.java b/luni/src/main/java/java/lang/Runtime.java index 3ddacf7..f1f6438 100644 --- a/luni/src/main/java/java/lang/Runtime.java +++ b/luni/src/main/java/java/lang/Runtime.java @@ -34,6 +34,7 @@ package java.lang; import dalvik.system.BaseDexClassLoader; import dalvik.system.VMDebug; +import dalvik.system.VMRuntime; import dalvik.system.VMStack; import java.io.File; import java.io.IOException; @@ -357,11 +358,14 @@ public class Runtime { */ void loadLibrary(String libraryName, ClassLoader loader) { if (loader != null) { - // TODO: We shouldn't assume that we know default linker search logic. String filename = loader.findLibrary(libraryName); if (filename == null) { - // The dynamic linker might still find the library by name. - filename = System.mapLibraryName(libraryName); + // It's not necessarily true that the ClassLoader used + // System.mapLibraryName, but the default setup does, and it's + // misleading to say we didn't find "libMyLibrary.so" when we + // actually searched for "liblibMyLibrary.so.so". + throw new UnsatisfiedLinkError(loader + " couldn't find \"" + + System.mapLibraryName(libraryName) + "\""); } String error = doLoad(filename, loader); if (error != null) { @@ -423,35 +427,31 @@ public class Runtime { } else if (loader instanceof BaseDexClassLoader) { BaseDexClassLoader dexClassLoader = (BaseDexClassLoader) loader; ldLibraryPath = dexClassLoader.getLdLibraryPath(); - dexPath = dexClassLoader.getDexPath(); } // 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, ldLibraryPath, dexPath); + return nativeLoad(name, loader, ldLibraryPath); } } // TODO: should be synchronized, but dalvik doesn't support synchronized internal natives. private static native String nativeLoad(String filename, ClassLoader loader, - String ldLibraryPath, String dexPath); + String ldLibraryPath); /** - * Provides a hint to the VM that it would be useful to attempt + * Provides a hint to the runtime that it would be useful to attempt * to perform any outstanding object finalization. */ public void runFinalization() { - try { - FinalizerReference.finalizeAllEnqueued(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + // 0 for no timeout. + VMRuntime.runFinalization(0); } /** * Sets the flag that indicates whether all objects are finalized when the - * VM is about to exit. Note that all finalization which occurs + * runtime is about to exit. Note that all finalization which occurs * when the system is exiting is performed after all running threads have * been terminated. * diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java index e79f844..c5d9a89 100644 --- a/luni/src/main/java/java/lang/System.java +++ b/luni/src/main/java/java/lang/System.java @@ -82,7 +82,10 @@ public final class System { */ public static final PrintStream err; - private static final String lineSeparator; + private static final String PATH_SEPARATOR = ":"; + private static final String LINE_SEPARATOR = "\n"; + private static final String FILE_SEPARATOR = "/"; + private static final Properties unchangeableSystemProperties; private static Properties systemProperties; @@ -108,7 +111,6 @@ public final class System { in = new BufferedInputStream(new FileInputStream(FileDescriptor.in)); unchangeableSystemProperties = initUnchangeableSystemProperties(); systemProperties = createSystemProperties(); - lineSeparator = System.getProperty("line.separator"); addLegacyLocaleSystemProperties(); } @@ -770,10 +772,6 @@ public final class System { p.put("java.vm.vendor", projectName); p.put("java.vm.version", runtime.vmVersion()); - p.put("file.separator", "/"); - p.put("line.separator", "\n"); - p.put("path.separator", ":"); - p.put("java.runtime.name", "Android Runtime"); p.put("java.runtime.version", "0.9"); p.put("java.vm.vendor.url", projectUrl); @@ -808,6 +806,25 @@ public final class System { // Override built-in properties with settings from the command line. parsePropertyAssignments(p, runtime.properties()); + + if (p.containsKey("file.separator")) { + logE("Ignoring command line argument: -Dfile.separator"); + } + + if (p.containsKey("line.separator")) { + logE("Ignoring command line argument: -Dline.separator"); + } + + if (p.containsKey("path.separator")) { + logE("Ignoring command line argument: -Dpath.separator"); + } + + // We ignore values for "file.separator", "line.separator" and "path.separator" from + // the command line. They're fixed on the operating systems we support. + p.put("file.separator", FILE_SEPARATOR); + p.put("line.separator", LINE_SEPARATOR); + p.put("path.separator", PATH_SEPARATOR); + return p; } @@ -1038,10 +1055,11 @@ public final class System { * <p>On Android versions before Lollipop the {@code line.separator} system property can be * modified but this method continues to return the original value. The system property cannot * be modified on later versions of Android. + * * @since 1.7 */ public static String lineSeparator() { - return lineSeparator; + return LINE_SEPARATOR; } /** diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java index 5416a80..02cfa01 100644 --- a/luni/src/main/java/java/lang/ref/FinalizerReference.java +++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java @@ -82,7 +82,7 @@ public final class FinalizerReference<T> extends Reference<T> { /** * Waits for all currently-enqueued references to be finalized. */ - public static void finalizeAllEnqueued() throws InterruptedException { + public static void finalizeAllEnqueued(long timeout) throws InterruptedException { // Alloate a new sentinel, this creates a FinalizerReference. Sentinel sentinel; // Keep looping until we safely enqueue our sentinel FinalizerReference. @@ -91,7 +91,7 @@ public final class FinalizerReference<T> extends Reference<T> { do { sentinel = new Sentinel(); } while (!enqueueSentinelReference(sentinel)); - sentinel.awaitFinalization(); + sentinel.awaitFinalization(timeout); } private static boolean enqueueSentinelReference(Sentinel sentinel) { @@ -144,9 +144,22 @@ public final class FinalizerReference<T> extends Reference<T> { notifyAll(); } - synchronized void awaitFinalization() throws InterruptedException { + synchronized void awaitFinalization(long timeout) throws InterruptedException { + final long startTime = System.nanoTime(); + final long endTime = startTime + timeout; while (!finalized) { - wait(); + // 0 signifies no timeout. + if (timeout != 0) { + final long currentTime = System.nanoTime(); + if (currentTime >= endTime) { + break; + } else { + final long deltaTime = endTime - currentTime; + wait(deltaTime / 1000000, (int)(deltaTime % 1000000)); + } + } else { + wait(); + } } } } diff --git a/luni/src/main/java/java/net/HttpURLConnection.java b/luni/src/main/java/java/net/HttpURLConnection.java index 4e5b4ee..2a70729 100644 --- a/luni/src/main/java/java/net/HttpURLConnection.java +++ b/luni/src/main/java/java/net/HttpURLConnection.java @@ -134,15 +134,23 @@ import java.util.Arrays; * used to control how many idle connections to each server will be held. * * <p>By default, this implementation of {@code HttpURLConnection} requests that - * servers use gzip compression. Since {@link #getContentLength()} returns the - * number of bytes transmitted, you cannot use that method to predict how many - * bytes can be read from {@link #getInputStream()}. Instead, read that stream - * until it is exhausted: when {@link InputStream#read} returns -1. Gzip - * compression can be disabled by setting the acceptable encodings in the - * request header: <pre> {@code + * servers use gzip compression and it automatically decompresses the data for + * callers of {@link #getInputStream()}. The Content-Encoding and Content-Length + * response headers are cleared in this case. Gzip compression can be disabled by + * setting the acceptable encodings in the request header: <pre> {@code * urlConnection.setRequestProperty("Accept-Encoding", "identity"); * }</pre> * + * <p>Setting the Accept-Encoding request header explicitly disables automatic + * decompression and leaves the response headers intact; callers must handle + * decompression as needed, according to the Content-Encoding header of the + * response. + * + * <p>{@link #getContentLength()} returns the number of bytes transmitted and + * cannot be used to predict how many bytes can be read from + * {@link #getInputStream()} for compressed streams. Instead, read that stream + * until it is exhausted, i.e. when {@link InputStream#read} returns -1. + * * <h3>Handling Network Sign-On</h3> * Some Wi-Fi networks block Internet access until the user clicks through a * sign-on page. Such sign-on pages are typically presented by using HTTP diff --git a/luni/src/main/java/java/security/Provider.java b/luni/src/main/java/java/security/Provider.java index 1704b58..1a64ecc 100644 --- a/luni/src/main/java/java/security/Provider.java +++ b/luni/src/main/java/java/security/Provider.java @@ -368,8 +368,8 @@ public abstract class Provider extends Properties { } /** - * Get the service of the specified type - * + * Get the service of the specified {@code type} (e.g. "SecureRandom", + * "Signature"). */ synchronized Provider.Service getService(String type) { updatePropertyServiceTable(); diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java index 3151058..b11abaa 100644 --- a/luni/src/main/java/java/security/Signature.java +++ b/luni/src/main/java/java/security/Signature.java @@ -172,7 +172,12 @@ public abstract class Signature extends SignatureSpi { throw new NoSuchAlgorithmException("Unknown algorithm: " + algorithm); } - SpiAndProvider spiAndProvider = tryAlgorithm(null, provider, algorithm); + SpiAndProvider spiAndProvider; + try { + spiAndProvider = tryAlgorithm(null, provider, algorithm); + } catch (InvalidKeyException e) { + throw new IllegalStateException("InvalidKeyException thrown when key == null", e); + } if (spiAndProvider == null) { if (provider == null) { throw new NoSuchAlgorithmException("No provider found for " + algorithm); @@ -187,7 +192,12 @@ public abstract class Signature extends SignatureSpi { return new SignatureImpl(algorithm, provider); } - private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) { + /** + * @throws InvalidKeyException if the specified key cannot be used to + * initialize any provider. + */ + private static Engine.SpiAndProvider tryAlgorithm( + Key key, Provider provider, String algorithm) throws InvalidKeyException { if (provider != null) { Provider.Service service = provider.getService(SERVICE, algorithm); if (service == null) { @@ -196,15 +206,22 @@ public abstract class Signature extends SignatureSpi { return tryAlgorithmWithProvider(null, service); } ArrayList<Provider.Service> services = ENGINE.getServices(algorithm); - if (services == null) { + if (services == null || services.isEmpty()) { return null; } + boolean keySupported = false; for (Provider.Service service : services) { - Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service); - if (sap != null) { - return sap; + if (key == null || service.supportsParameter(key)) { + keySupported = true; + Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service); + if (sap != null) { + return sap; + } } } + if (!keySupported) { + throw new InvalidKeyException("No provider supports the provided key"); + } return null; } @@ -245,11 +262,12 @@ public abstract class Signature extends SignatureSpi { } /** - * Gets the SPI implementation backing this signature. + * Returns the {@code SignatureSpi} backing this {@code Signature} or {@code null} if no + * {@code SignatureSpi} is backing this {@code Signature}. * * @hide */ - public SignatureSpi getSpi() { + public SignatureSpi getCurrentSpi() { return null; } @@ -660,7 +678,7 @@ public abstract class Signature extends SignatureSpi { @Override void ensureProviderChosen() { - getSpi(null); + getSpi(); } @Override @@ -718,8 +736,11 @@ public abstract class Signature extends SignatureSpi { /** * Makes sure a CipherSpi that matches this type is selected. + * + * @throws InvalidKeyException if the specified key cannot be used to + * initialize this signature. */ - private SignatureSpi getSpi(Key key) { + private SignatureSpi getSpi(Key key) throws InvalidKeyException { synchronized (initLock) { if (spiImpl != null && key == null) { return spiImpl; @@ -739,12 +760,20 @@ public abstract class Signature extends SignatureSpi { /** * Convenience call when the Key is not available. - * - * @hide */ + private SignatureSpi getSpi() { + try { + return getSpi(null); + } catch (InvalidKeyException e) { + throw new IllegalStateException("InvalidKeyException thrown when key == null", e); + } + } + @Override - public SignatureSpi getSpi() { - return getSpi(null); + public SignatureSpi getCurrentSpi() { + synchronized (initLock) { + return spiImpl; + } } } } diff --git a/luni/src/main/java/java/text/DecimalFormatSymbols.java b/luni/src/main/java/java/text/DecimalFormatSymbols.java index 2f1d4f4..006d37b 100644 --- a/luni/src/main/java/java/text/DecimalFormatSymbols.java +++ b/luni/src/main/java/java/text/DecimalFormatSymbols.java @@ -297,8 +297,14 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { return minusSign.charAt(0); } - throw new UnsupportedOperationException( - "Minus sign spans multiple characters: " + minusSign); + // Return the minus sign from Locale.ROOT instead of crashing. None of libcore the parsers + // or formatters actually call this function, they use {@code getMinusSignString()} instead + // and that function always returns the correct (possibly multi-char) symbol. + // + // Callers of this method that format strings and expect them to be parseable by + // the "standard" parsers (or vice-versa) are hosed, but there's not much we can do to + // save them. + return '-'; } /** @hide */ @@ -349,7 +355,15 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { if (percent.length() == 1) { return percent.charAt(0); } - throw new UnsupportedOperationException("Percent spans multiple characters: " + percent); + + // Return the percent sign from Locale.ROOT instead of crashing. None of the libcore parsers + // or formatters actually call this function, they use {@code getPercentString()} instead + // and that function always returns the correct (possibly multi-char) symbol. + // + // Callers of this method that format strings and expect them to be parseable by + // the "standard" parsers (or vice-versa) are hosed, but there's not much we can do to + // save them. + return '%'; } /** @@ -601,6 +615,8 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { new ObjectStreamField("serialVersionOnStream", int.class), new ObjectStreamField("zeroDigit", char.class), new ObjectStreamField("locale", Locale.class), + new ObjectStreamField("minusSignStr", String.class), + new ObjectStreamField("percentStr", String.class), }; private void writeObject(ObjectOutputStream stream) throws IOException { @@ -613,15 +629,21 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { fields.put("groupingSeparator", getGroupingSeparator()); fields.put("infinity", infinity); fields.put("intlCurrencySymbol", intlCurrencySymbol); - fields.put("minusSign", getMinusSign()); fields.put("monetarySeparator", getMonetaryDecimalSeparator()); fields.put("NaN", NaN); fields.put("patternSeparator", getPatternSeparator()); - fields.put("percent", getPercent()); fields.put("perMill", getPerMill()); fields.put("serialVersionOnStream", 3); fields.put("zeroDigit", getZeroDigit()); fields.put("locale", locale); + + // Hardcode values here for backwards compatibility. These values will only be used + // if we're de-serializing this object on an earlier version of android. + fields.put("minusSign", minusSign.length() == 1 ? minusSign.charAt(0) : '-'); + fields.put("percent", percent.length() == 1 ? percent.charAt(0) : '%'); + + fields.put("minusSignStr", getMinusSignString()); + fields.put("percentStr", getPercentString()); stream.writeFields(); } @@ -634,10 +656,26 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { setGroupingSeparator(fields.get("groupingSeparator", ',')); infinity = (String) fields.get("infinity", ""); intlCurrencySymbol = (String) fields.get("intlCurrencySymbol", ""); - setMinusSign(fields.get("minusSign", '-')); NaN = (String) fields.get("NaN", ""); setPatternSeparator(fields.get("patternSeparator", ';')); - setPercent(fields.get("percent", '%')); + + // Special handling for minusSign and percent. If we've serialized the string versions of + // these fields, use them. If not, fall back to the single character versions. This can + // only happen if we're de-serializing an object that was written by an older version of + // android (something that's strongly discouraged anyway). + final String minusSignStr = (String) fields.get("minusSignStr", null); + if (minusSignStr != null) { + minusSign = minusSignStr; + } else { + setMinusSign(fields.get("minusSign", '-')); + } + final String percentStr = (String) fields.get("percentStr", null); + if (percentStr != null) { + percent = percentStr; + } else { + setPercent(fields.get("percent", '%')); + } + setPerMill(fields.get("perMill", '\u2030')); setZeroDigit(fields.get("zeroDigit", '0')); locale = (Locale) fields.get("locale", null); diff --git a/luni/src/main/java/java/util/ComparableTimSort.java b/luni/src/main/java/java/util/ComparableTimSort.java index aba7573..f3da001 100644 --- a/luni/src/main/java/java/util/ComparableTimSort.java +++ b/luni/src/main/java/java/util/ComparableTimSort.java @@ -94,7 +94,7 @@ class ComparableTimSort { private final int[] runLen; /** - * Asserts have been placed in if-statements for performace. To enable them, + * Asserts have been placed in if-statements for performance. To enable them, * set this field to true and enable them in VM with a command line flag. * If you modify this class, please do test the asserts! */ @@ -363,11 +363,28 @@ class ComparableTimSort { */ private void mergeCollapse() { while (stackSize > 1) { - int n = stackSize - 2; + final int n = stackSize - 2; if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) { - if (runLen[n - 1] < runLen[n + 1]) - n--; - mergeAt(n); + // Merge the smaller of runLen[n-1] or runLen[n + 1] with runLen[n]. + if (runLen[n - 1] < runLen[n + 1]) { + // runLen[n-1] is smallest. Merge runLen[n] into runLen[n - 1], leaving + // runLen[n+1] as the new runLen[n]. + mergeAt(n - 1); + // n is now stackSize - 1, the top of the stack. + // Fix for http://b/19493779 + // Because we modified runLen[n - 1] we might have affected invariant 1 as far + // back as runLen[n - 3]. Check we did not violate it. + if (n > 2 && runLen[n-3] <= runLen[n-2] + runLen[n-1]) { + // Avoid leaving invariant 1 still violated on the next loop by also merging + // runLen[n] into runLen[n - 1]. + mergeAt(n - 1); + // Now the last three elements in the stack will again be the only elements + // that might break the invariant and we can loop again safely. + } + } else { + // runLen[n+1] is smallest. Merge runLen[n + 1] into runLen[n]. + mergeAt(n); + } } else if (runLen[n] <= runLen[n + 1]) { mergeAt(n); } else { diff --git a/luni/src/main/java/java/util/Date.java b/luni/src/main/java/java/util/Date.java index d45c971..253d2e8 100644 --- a/luni/src/main/java/java/util/Date.java +++ b/luni/src/main/java/java/util/Date.java @@ -691,21 +691,23 @@ public class Date implements Serializable, Cloneable, Comparable<Date> { } /** - * Returns a string representation of this {@code Date}. - * The formatting is equivalent to using a {@code SimpleDateFormat} with - * the format string "EEE MMM dd HH:mm:ss zzz yyyy", which looks something - * like "Tue Jun 22 13:07:00 PDT 1999". The current default time zone and - * locale are used. If you need control over the time zone or locale, - * use {@code SimpleDateFormat} instead. + * Returns a string representation of this {@code Date}. The formatting is equivalent to + * using a {@code SimpleDateFormat} with the format string "EEE MMM dd HH:mm:ss zzz yyyy", + * which looks something like "Tue Jun 22 13:07:00 PDT 1999". While the current default time + * zone is used, all formatting and timezone names follow {@code Locale.US}. If you need control + * over the time zone or locale, use {@code SimpleDateFormat} instead. */ @Override public String toString() { // TODO: equivalent to the following one-liner, though that's slower on stingray // at 476us versus 69us... - // return new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").format(d); + // return new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").format(d, Locale.US); LocaleData localeData = LocaleData.get(Locale.US); - Calendar cal = new GregorianCalendar(milliseconds); - TimeZone tz = cal.getTimeZone(); + + TimeZone tz = TimeZone.getDefault(); + Calendar cal = new GregorianCalendar(tz, Locale.US); + cal.setTimeInMillis(milliseconds); + StringBuilder result = new StringBuilder(); result.append(localeData.shortWeekdayNames[cal.get(Calendar.DAY_OF_WEEK)]); result.append(' '); @@ -719,7 +721,7 @@ public class Date implements Serializable, Cloneable, Comparable<Date> { result.append(':'); appendTwoDigits(result, cal.get(Calendar.SECOND)); result.append(' '); - result.append(tz.getDisplayName(tz.inDaylightTime(this), TimeZone.SHORT)); + result.append(tz.getDisplayName(tz.inDaylightTime(this), TimeZone.SHORT, Locale.US)); result.append(' '); result.append(cal.get(Calendar.YEAR)); return result.toString(); diff --git a/luni/src/main/java/java/util/List.java b/luni/src/main/java/java/util/List.java index 8a9e1e3..54c8b65 100644 --- a/luni/src/main/java/java/util/List.java +++ b/luni/src/main/java/java/util/List.java @@ -84,7 +84,8 @@ public interface List<E> extends Collection<E> { * @throws IllegalArgumentException * if an object cannot be added to this {@code List}. * @throws IndexOutOfBoundsException - * if {@code location < 0 || location > size()} + * if {@code location < 0 || location > size()}. + * @throws NullPointerException if {@code collection} is {@code null}. */ public boolean addAll(int location, Collection<? extends E> collection); @@ -104,6 +105,7 @@ public interface List<E> extends Collection<E> { * {@code List}. * @throws IllegalArgumentException * if an object cannot be added to this {@code List}. + * @throws NullPointerException if {@code collection} is {@code null}. */ public boolean addAll(Collection<? extends E> collection); @@ -135,6 +137,7 @@ public interface List<E> extends Collection<E> { * the collection of objects * @return {@code true} if all objects in the specified collection are * elements of this {@code List}, {@code false} otherwise. + * @throws NullPointerException if {@code collection} is {@code null}. */ public boolean containsAll(Collection<?> collection); @@ -269,6 +272,7 @@ public interface List<E> extends Collection<E> { * @return {@code true} if this {@code List} is modified, {@code false} otherwise. * @throws UnsupportedOperationException * if removing from this {@code List} is not supported. + * @throws NullPointerException if {@code collection} is {@code null}. */ public boolean removeAll(Collection<?> collection); @@ -281,6 +285,7 @@ public interface List<E> extends Collection<E> { * @return {@code true} if this {@code List} is modified, {@code false} otherwise. * @throws UnsupportedOperationException * if removing from this {@code List} is not supported. + * @throws NullPointerException if {@code collection} is {@code null}. */ public boolean retainAll(Collection<?> collection); diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java index 1885f83..9b0cd87 100644 --- a/luni/src/main/java/java/util/Locale.java +++ b/luni/src/main/java/java/util/Locale.java @@ -99,6 +99,10 @@ import libcore.icu.ICU; * <td><a href="http://site.icu-project.org/download/53">ICU 53</a></td> * <td><a href="http://cldr.unicode.org/index/downloads/cldr-25">CLDR 25</a></td> * <td><a href="http://www.unicode.org/versions/Unicode6.3.0/">Unicode 6.3</a></td></tr> + * <tr><td>Android 6.0 (Marshmallow)</td> + * <td><a href="http://site.icu-project.org/download/55">ICU 55.1</a></td> + * <td><a href="http://cldr.unicode.org/index/downloads/cldr-27">CLDR 27.0.1</a></td> + * <td><a href="http://www.unicode.org/versions/Unicode7.0.0/">Unicode 7.0</a></td></tr> * </table> * * <a name="default_locale"></a><h3>Be wary of the default locale</h3> @@ -744,12 +748,13 @@ public final class Locale implements Cloneable, Serializable { final String normalizedValue = value.toLowerCase(Locale.ROOT).replace('_', '-'); final String[] subtags = normalizedValue.split("-"); + final char normalizedKey = Character.toLowerCase(key); // Lengths for subtags in the private use extension should be [1, 8] chars. // For all other extensions, they should be [2, 8] chars. // // http://www.rfc-editor.org/rfc/bcp/bcp47.txt - final int minimumLength = (key == PRIVATE_USE_EXTENSION) ? 1 : 2; + final int minimumLength = (normalizedKey == PRIVATE_USE_EXTENSION) ? 1 : 2; for (String subtag : subtags) { if (!isValidBcp47Alphanum(subtag, minimumLength, 8)) { throw new IllformedLocaleException( @@ -759,14 +764,14 @@ public final class Locale implements Cloneable, Serializable { // We need to take special action in the case of unicode extensions, // since we claim to understand their keywords and attributes. - if (key == UNICODE_LOCALE_EXTENSION) { + if (normalizedKey == UNICODE_LOCALE_EXTENSION) { // First clear existing attributes and keywords. extensions.clear(); attributes.clear(); parseUnicodeExtension(subtags, keywords, attributes); } else { - extensions.put(key, normalizedValue); + extensions.put(normalizedKey, normalizedValue); } return this; @@ -986,6 +991,27 @@ public final class Locale implements Cloneable, Serializable { this.unicodeKeywords = Collections.unmodifiableMap(keywordsCopy); this.extensions = Collections.unmodifiableMap(extensionsCopy); } else { + + // The locales ja_JP_JP and th_TH_TH are ill formed since their variant is too + // short, however they have been used to represent a locale with the japanese imperial + // calendar and thai numbering respectively. We add an extension in their constructor + // to modernize them. + if ("ja".equals(language) && "JP".equals(country) && "JP".equals(variant)) { + Map<String, String> keywordsCopy = new TreeMap<>(unicodeKeywords); + keywordsCopy.put("ca", "japanese"); + unicodeKeywords = keywordsCopy; + } else if ("th".equals(language) && "TH".equals(country) && "TH".equals(variant)) { + Map<String, String> keywordsCopy = new TreeMap<>(unicodeKeywords); + keywordsCopy.put("nu", "thai"); + unicodeKeywords = keywordsCopy; + } + + if (!unicodeKeywords.isEmpty() || !unicodeAttributes.isEmpty()) { + Map<Character, String> extensionsCopy = new TreeMap<>(extensions); + addUnicodeExtensionToExtensionsMap(unicodeAttributes, unicodeKeywords, extensionsCopy); + extensions = extensionsCopy; + } + this.unicodeAttributes = unicodeAttributes; this.unicodeKeywords = unicodeKeywords; this.extensions = extensions; @@ -2134,7 +2160,7 @@ public final class Locale implements Cloneable, Serializable { return extensionKeyIndex; } - final String key = subtags[extensionKeyIndex]; + final String key = subtags[extensionKeyIndex].toLowerCase(Locale.ROOT); if (extensions.containsKey(key.charAt(0))) { return extensionKeyIndex; } @@ -2146,7 +2172,7 @@ public final class Locale implements Cloneable, Serializable { // Mark the start of the next extension. Also keep track of whether this // is a private use extension, and throw an error if it doesn't come last. extensionKeyIndex = i; - if ("x".equals(subtag)) { + if ("x".equals(subtag.toLowerCase(Locale.ROOT))) { privateUseExtensionIndex = i; } else if (privateUseExtensionIndex != -1) { // The private use extension must come last. @@ -2169,7 +2195,7 @@ public final class Locale implements Cloneable, Serializable { return extensionKeyIndex; } - final String key = subtags[extensionKeyIndex]; + final String key = subtags[extensionKeyIndex].toLowerCase(Locale.ROOT); if (extensions.containsKey(key.charAt(0))) { return extensionKeyIndex; } diff --git a/luni/src/main/java/java/util/TimSort.java b/luni/src/main/java/java/util/TimSort.java index ffe4e17..1a566c2 100644 --- a/luni/src/main/java/java/util/TimSort.java +++ b/luni/src/main/java/java/util/TimSort.java @@ -119,7 +119,7 @@ class TimSort<T> { private final int[] runLen; /** - * Asserts have been placed in if-statements for performace. To enable them, + * Asserts have been placed in if-statements for performance. To enable them, * set this field to true and enable them in VM with a command line flag. * If you modify this class, please do test the asserts! */ @@ -397,11 +397,29 @@ class TimSort<T> { */ private void mergeCollapse() { while (stackSize > 1) { - int n = stackSize - 2; + final int n = stackSize - 2; if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) { - if (runLen[n - 1] < runLen[n + 1]) - n--; - mergeAt(n); + // Merge the smaller of runLen[n-1] or runLen[n + 1] with runLen[n]. + if (runLen[n - 1] < runLen[n + 1]) { + // runLen[n-1] is smallest. Merge runLen[n] into runLen[n - 1], leaving + // runLen[n+1] as the new runLen[n]. + mergeAt(n - 1); + // n is now stackSize - 1, the top of the stack. + + // Fix for http://b/19493779 + // Because we modified runLen[n - 1] we might have affected invariant 1 as far + // back as runLen[n - 3]. Check we did not violate it. + if (n > 2 && runLen[n-3] <= runLen[n-2] + runLen[n-1]) { + // Avoid leaving invariant 1 still violated on the next loop by also merging + // runLen[n] into runLen[n - 1]. + mergeAt(n - 1); + // Now the last three elements in the stack will again be the only elements + // that might break the invariant and we can loop again safely. + } + } else { + // runLen[n+1] is smallest. Merge runLen[n + 1] into runLen[n]. + mergeAt(n); + } } else if (runLen[n] <= runLen[n + 1]) { mergeAt(n); } else { diff --git a/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java b/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java index 23e68bb..26649a8 100644 --- a/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java +++ b/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; /** diff --git a/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java b/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java index 3cfe6d5..9dca1b3 100644 --- a/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java +++ b/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java @@ -5,13 +5,15 @@ */ package java.util.concurrent; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; + +import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.AbstractQueue; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; -import java.lang.ref.WeakReference; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; // BEGIN android-note // removed link to collections framework docs @@ -46,7 +48,7 @@ import java.lang.ref.WeakReference; * * @since 1.5 * @author Doug Lea - * @param <E> the type of elements held in this collection + * @param <E> the type of elements held in this queue */ public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { @@ -95,14 +97,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> // Internal helper methods /** - * Circularly increment i. - */ - final int inc(int i) { - return (++i == items.length) ? 0 : i; - } - - /** - * Circularly decrement i. + * Circularly decrements array index i. */ final int dec(int i) { return ((i == 0) ? items.length : i) - 1; @@ -117,24 +112,15 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> } /** - * Throws NullPointerException if argument is null. - * - * @param v the element - */ - private static void checkNotNull(Object v) { - if (v == null) - throw new NullPointerException(); - } - - /** * Inserts element at current put position, advances, and signals. * Call only when holding lock. */ private void enqueue(E x) { // assert lock.getHoldCount() == 1; // assert items[putIndex] == null; + final Object[] items = this.items; items[putIndex] = x; - putIndex = inc(putIndex); + if (++putIndex == items.length) putIndex = 0; count++; notEmpty.signal(); } @@ -150,7 +136,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> @SuppressWarnings("unchecked") E x = (E) items[takeIndex]; items[takeIndex] = null; - takeIndex = inc(takeIndex); + if (++takeIndex == items.length) takeIndex = 0; count--; if (itrs != null) itrs.elementDequeued(); @@ -171,7 +157,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> if (removeIndex == takeIndex) { // removing front item; just advance items[takeIndex] = null; - takeIndex = inc(takeIndex); + if (++takeIndex == items.length) takeIndex = 0; count--; if (itrs != null) itrs.elementDequeued(); @@ -179,17 +165,15 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> // an "interior" remove // slide over all others up through putIndex. - final int putIndex = this.putIndex; - for (int i = removeIndex;;) { - int next = inc(i); - if (next != putIndex) { - items[i] = items[next]; - i = next; - } else { - items[i] = null; - this.putIndex = i; + for (int i = removeIndex, putIndex = this.putIndex;;) { + int pred = i; + if (++i == items.length) i = 0; + if (i == putIndex) { + items[pred] = null; + this.putIndex = pred; break; } + items[pred] = items[i]; } count--; if (itrs != null) @@ -254,7 +238,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> int i = 0; try { for (E e : c) { - checkNotNull(e); + if (e == null) throw new NullPointerException(); items[i++] = e; } } catch (ArrayIndexOutOfBoundsException ex) { @@ -292,7 +276,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * @throws NullPointerException if the specified element is null */ public boolean offer(E e) { - checkNotNull(e); + if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); try { @@ -315,7 +299,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * @throws NullPointerException {@inheritDoc} */ public void put(E e) throws InterruptedException { - checkNotNull(e); + if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { @@ -338,7 +322,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { - checkNotNull(e); + if (e == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -462,11 +446,11 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> */ public boolean remove(Object o) { if (o == null) return false; - final Object[] items = this.items; final ReentrantLock lock = this.lock; lock.lock(); try { if (count > 0) { + final Object[] items = this.items; final int putIndex = this.putIndex; int i = takeIndex; do { @@ -474,7 +458,8 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> removeAt(i); return true; } - } while ((i = inc(i)) != putIndex); + if (++i == items.length) i = 0; + } while (i != putIndex); } return false; } finally { @@ -492,17 +477,18 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> */ public boolean contains(Object o) { if (o == null) return false; - final Object[] items = this.items; final ReentrantLock lock = this.lock; lock.lock(); try { if (count > 0) { + final Object[] items = this.items; final int putIndex = this.putIndex; int i = takeIndex; do { if (o.equals(items[i])) return true; - } while ((i = inc(i)) != putIndex); + if (++i == items.length) i = 0; + } while (i != putIndex); } return false; } finally { @@ -524,19 +510,14 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * @return an array containing all of the elements in this queue */ public Object[] toArray() { - final Object[] items = this.items; final ReentrantLock lock = this.lock; lock.lock(); try { - final int count = this.count; - Object[] a = new Object[count]; - int n = items.length - takeIndex; - if (count <= n) { - System.arraycopy(items, takeIndex, a, 0, count); - } else { - System.arraycopy(items, takeIndex, a, 0, n); - System.arraycopy(items, 0, a, n, count - n); - } + final Object[] items = this.items; + final int end = takeIndex + count; + final Object[] a = Arrays.copyOfRange(items, takeIndex, end); + if (end != putIndex) + System.arraycopy(items, 0, a, items.length - takeIndex, putIndex); return a; } finally { lock.unlock(); @@ -564,7 +545,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * The following code can be used to dump the queue into a newly * allocated array of {@code String}: * - * <pre> {@code String[] y = x.toArray(new String[0]);}</pre> + * <pre> {@code String[] y = x.toArray(new String[0]);}</pre> * * Note that {@code toArray(new Object[0])} is identical in function to * {@code toArray()}. @@ -580,24 +561,22 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> */ @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { - final Object[] items = this.items; final ReentrantLock lock = this.lock; lock.lock(); try { + final Object[] items = this.items; final int count = this.count; - final int len = a.length; - if (len < count) - a = (T[])java.lang.reflect.Array.newInstance( - a.getClass().getComponentType(), count); - int n = items.length - takeIndex; - if (count <= n) - System.arraycopy(items, takeIndex, a, 0, count); - else { - System.arraycopy(items, takeIndex, a, 0, n); - System.arraycopy(items, 0, a, n, count - n); + final int firstLeg = Math.min(items.length - takeIndex, count); + if (a.length < count) { + a = (T[]) Arrays.copyOfRange(items, takeIndex, takeIndex + count, + a.getClass()); + } else { + System.arraycopy(items, takeIndex, a, 0, firstLeg); + if (a.length > count) + a[count] = null; } - if (len > count) - a[count] = null; + if (firstLeg < count) + System.arraycopy(items, 0, a, firstLeg, putIndex); return a; } finally { lock.unlock(); @@ -612,14 +591,16 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> if (k == 0) return "[]"; + final Object[] items = this.items; StringBuilder sb = new StringBuilder(); sb.append('['); - for (int i = takeIndex; ; i = inc(i)) { + for (int i = takeIndex; ; ) { Object e = items[i]; sb.append(e == this ? "(this Collection)" : e); if (--k == 0) return sb.append(']').toString(); sb.append(',').append(' '); + if (++i == items.length) i = 0; } } finally { lock.unlock(); @@ -641,7 +622,8 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> int i = takeIndex; do { items[i] = null; - } while ((i = inc(i)) != putIndex); + if (++i == items.length) i = 0; + } while (i != putIndex); takeIndex = putIndex; count = 0; if (itrs != null) @@ -671,7 +653,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * @throws IllegalArgumentException {@inheritDoc} */ public int drainTo(Collection<? super E> c, int maxElements) { - checkNotNull(c); + if (c == null) throw new NullPointerException(); if (c == this) throw new IllegalArgumentException(); if (maxElements <= 0) @@ -689,7 +671,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> E x = (E) items[take]; c.add(x); items[take] = null; - take = inc(take); + if (++take == items.length) take = 0; i++; } return n; @@ -717,12 +699,8 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue in proper sequence */ @@ -796,13 +774,13 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> } /** Incremented whenever takeIndex wraps around to 0 */ - int cycles = 0; + int cycles; /** Linked list of weak iterator references */ private Node head; /** Used to expunge stale iterators */ - private Node sweeper = null; + private Node sweeper; private static final int SHORT_SWEEP_PROBES = 4; private static final int LONG_SWEEP_PROBES = 16; @@ -910,7 +888,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> } /** - * Called whenever an interior remove (not at takeIndex) occured. + * Called whenever an interior remove (not at takeIndex) occurred. * * Notifies all iterators, and expunges any that are now stale. */ @@ -1059,9 +1037,8 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> private int incCursor(int index) { // assert lock.getHoldCount() == 1; - index = inc(index); - if (index == putIndex) - index = NONE; + if (++index == items.length) index = 0; + if (index == putIndex) index = NONE; return index; } @@ -1268,7 +1245,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> } /** - * Called whenever an interior remove (not at takeIndex) occured. + * Called whenever an interior remove (not at takeIndex) occurred. * * @return true if this iterator should be unlinked from itrs */ @@ -1277,17 +1254,18 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> if (isDetached()) return true; - final int cycles = itrs.cycles; final int takeIndex = ArrayBlockingQueue.this.takeIndex; - final int prevCycles = this.prevCycles; final int prevTakeIndex = this.prevTakeIndex; final int len = items.length; - int cycleDiff = cycles - prevCycles; - if (removedIndex < takeIndex) - cycleDiff++; + // distance from prevTakeIndex to removedIndex final int removedDistance = - (cycleDiff * len) + (removedIndex - prevTakeIndex); - // assert removedDistance >= 0; + len * (itrs.cycles - this.prevCycles + + ((removedIndex < takeIndex) ? 1 : 0)) + + (removedIndex - prevTakeIndex); + // assert itrs.cycles - this.prevCycles >= 0; + // assert itrs.cycles - this.prevCycles <= 1; + // assert removedDistance > 0; + // assert removedIndex != takeIndex; int cursor = this.cursor; if (cursor >= 0) { int x = distance(cursor, prevTakeIndex, len); @@ -1316,7 +1294,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> else if (x > removedDistance) this.nextIndex = nextIndex = dec(nextIndex); } - else if (cursor < 0 && nextIndex < 0 && lastRet < 0) { + if (cursor < 0 && nextIndex < 0 && lastRet < 0) { this.prevTakeIndex = DETACHED; return true; } @@ -1354,4 +1332,5 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E> // "remainingCapacity()=" + remainingCapacity()); // } } + } diff --git a/luni/src/main/java/java/util/concurrent/BlockingDeque.java b/luni/src/main/java/java/util/concurrent/BlockingDeque.java index 8a393ba..b1437cc 100644 --- a/luni/src/main/java/java/util/concurrent/BlockingDeque.java +++ b/luni/src/main/java/java/util/concurrent/BlockingDeque.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; /** @@ -23,6 +24,7 @@ import java.util.*; * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Summary of BlockingDeque methods</caption> * <tr> * <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td> * </tr> @@ -98,6 +100,7 @@ import java.util.*; * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Comparison of BlockingQueue and BlockingDeque methods</caption> * <tr> * <td ALIGN=CENTER> <b>{@code BlockingQueue} Method</b></td> * <td ALIGN=CENTER> <b>Equivalent {@code BlockingDeque} Method</b></td> @@ -606,9 +609,10 @@ public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> { // *** Stack methods *** /** - * Pushes an element onto the stack represented by this deque. In other - * words, inserts the element at the front of this deque unless it would - * violate capacity restrictions. + * Pushes an element onto the stack represented by this deque (in other + * words, at the head of this deque) if it is possible to do so + * immediately without violating capacity restrictions, throwing an + * {@code IllegalStateException} if no space is currently available. * * <p>This method is equivalent to {@link #addFirst(Object) addFirst}. * diff --git a/luni/src/main/java/java/util/concurrent/BlockingQueue.java b/luni/src/main/java/java/util/concurrent/BlockingQueue.java index cc6d541..33d83b7 100644 --- a/luni/src/main/java/java/util/concurrent/BlockingQueue.java +++ b/luni/src/main/java/java/util/concurrent/BlockingQueue.java @@ -30,6 +30,7 @@ import java.util.Queue; * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Summary of BlockingQueue methods</caption> * <tr> * <td></td> * <td ALIGN=CENTER><em>Throws exception</em></td> diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java index ea3b1e9..3ed54cf 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java @@ -10,9 +10,9 @@ import java.io.ObjectStreamField; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.AbstractMap; import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.ConcurrentModificationException; import java.util.Enumeration; import java.util.HashMap; @@ -22,7 +22,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; @@ -99,7 +98,9 @@ import java.util.concurrent.locks.ReentrantLock; * @param <K> the type of keys maintained by this map * @param <V> the type of mapped values */ -public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> +// android-note: removed documentation about hidden newKeySet and newKeySet(int) APIs. +// android-note: Added "extends AbstractMap<K, V>. +public class ConcurrentHashMap<K,V> extends AbstractMap<K, V> implements ConcurrentMap<K,V>, Serializable { private static final long serialVersionUID = 7249069246763182397L; @@ -208,14 +209,15 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * The table is resized when occupancy exceeds a percentage * threshold (nominally, 0.75, but see below). Any thread * noticing an overfull bin may assist in resizing after the - * initiating thread allocates and sets up the replacement - * array. However, rather than stalling, these other threads may - * proceed with insertions etc. The use of TreeBins shields us - * from the worst case effects of overfilling while resizes are in + * initiating thread allocates and sets up the replacement array. + * However, rather than stalling, these other threads may proceed + * with insertions etc. The use of TreeBins shields us from the + * worst case effects of overfilling while resizes are in * progress. Resizing proceeds by transferring bins, one by one, - * from the table to the next table. To enable concurrency, the - * next table must be (incrementally) prefilled with place-holders - * serving as reverse forwarders to the old table. Because we are + * from the table to the next table. However, threads claim small + * blocks of indices to transfer (via field transferIndex) before + * doing so, reducing contention. A generation stamp in field + * sizeCtl ensures that resizings do not overlap. Because we are * using power-of-two expansion, the elements from each bin must * either stay at same index, or move with a power of two * offset. We eliminate unnecessary node creation by catching @@ -236,13 +238,19 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * locks, average aggregate waits become shorter as resizing * progresses. The transfer operation must also ensure that all * accessible bins in both the old and new table are usable by any - * traversal. This is arranged by proceeding from the last bin - * (table.length - 1) up towards the first. Upon seeing a - * forwarding node, traversals (see class Traverser) arrange to - * move to the new table without revisiting nodes. However, to - * ensure that no intervening nodes are skipped, bin splitting can - * only begin after the associated reverse-forwarders are in - * place. + * traversal. This is arranged in part by proceeding from the + * last bin (table.length - 1) up towards the first. Upon seeing + * a forwarding node, traversals (see class Traverser) arrange to + * move to the new table without revisiting nodes. To ensure that + * no intervening nodes are skipped even when moved out of order, + * a stack (see class TableStack) is created on first encounter of + * a forwarding node during a traversal, to maintain its place if + * later processing the current table. The need for these + * save/restore mechanics is relatively rare, but when one + * forwarding node is encountered, typically many more will be. + * So Traversers use a simple caching scheme to avoid creating so + * many new TableStack nodes. (Thanks to Peter Levart for + * suggesting use of a stack here.) * * The traversal scheme also applies to partial traversals of * ranges of bins (via an alternate Traverser constructor) @@ -274,16 +282,18 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * related operations (which is the main reason we cannot use * existing collections such as TreeMaps). TreeBins contain * Comparable elements, but may contain others, as well as - * elements that are Comparable but not necessarily Comparable - * for the same T, so we cannot invoke compareTo among them. To - * handle this, the tree is ordered primarily by hash value, then - * by Comparable.compareTo order if applicable. On lookup at a - * node, if elements are not comparable or compare as 0 then both - * left and right children may need to be searched in the case of - * tied hash values. (This corresponds to the full list search - * that would be necessary if all elements were non-Comparable and - * had tied hashes.) The red-black balancing code is updated from - * pre-jdk-collections + * elements that are Comparable but not necessarily Comparable for + * the same T, so we cannot invoke compareTo among them. To handle + * this, the tree is ordered primarily by hash value, then by + * Comparable.compareTo order if applicable. On lookup at a node, + * if elements are not comparable or compare as 0 then both left + * and right children may need to be searched in the case of tied + * hash values. (This corresponds to the full list search that + * would be necessary if all elements were non-Comparable and had + * tied hashes.) On insertion, to keep a total ordering (or as + * close as is required here) across rebalancings, we compare + * classes and identityHashCodes as tie-breakers. The red-black + * balancing code is updated from pre-jdk-collections * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) * based in turn on Cormen, Leiserson, and Rivest "Introduction to * Algorithms" (CLR). @@ -313,6 +323,10 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * unused "Segment" class that is instantiated in minimal form * only when serializing. * + * Also, solely for compatibility with previous versions of this + * class, it extends AbstractMap, even though all of its methods + * are overridden, so it is just useless baggage. + * * This file is organized to make things a little easier to follow * while reading than they might otherwise: First the main static * declarations and utilities, then fields, then main public @@ -321,6 +335,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * bulk operations. */ + /* ---------------- Constants -------------- */ /** @@ -393,6 +408,23 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> */ private static final int MIN_TRANSFER_STRIDE = 16; + /** + * The number of bits used for generation stamp in sizeCtl. + * Must be at least 6 for 32bit arrays. + */ + private static int RESIZE_STAMP_BITS = 16; + + /** + * The maximum number of threads that can help resize. + * Must fit in 32 - RESIZE_STAMP_BITS bits. + */ + private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1; + + /** + * The bit shift for recording size stamp in sizeCtl. + */ + private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS; + /* * Encodings for Node hash fields. See above for explanation. */ @@ -504,7 +536,6 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; } - /** * Returns x's Class if it is of the form "class C implements * Comparable<C>", else null. @@ -605,11 +636,6 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> private transient volatile int transferIndex; /** - * The least available table index to split while resizing. - */ - private transient volatile int transferOrigin; - - /** * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. */ private transient volatile int cellsBusy; @@ -1035,8 +1061,8 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * reflect any modifications subsequent to construction. * * @return the set view - * */ + // android-note : changed KeySetView<K,V> to Set<K> to maintain API compatibility. public Set<K> keySet() { KeySetView<K,V> ks; return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null)); @@ -1209,9 +1235,10 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL]; for (int i = 0; i < segments.length; ++i) segments[i] = new Segment<K,V>(LOAD_FACTOR); - s.putFields().put("segments", segments); - s.putFields().put("segmentShift", segmentShift); - s.putFields().put("segmentMask", segmentMask); + java.io.ObjectOutputStream.PutField streamFields = s.putFields(); + streamFields.put("segments", segments); + streamFields.put("segmentShift", segmentShift); + streamFields.put("segmentMask", segmentMask); s.writeFields(); Node<K,V>[] t; @@ -1264,8 +1291,8 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> int sz = (int)size; n = tableSizeFor(sz + (sz >>> 1) + 1); } - @SuppressWarnings({"rawtypes","unchecked"}) - Node<K,V>[] tab = (Node<K,V>[])new Node[n]; + @SuppressWarnings("unchecked") + Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n]; int mask = n - 1; long added = 0L; while (p != null) { @@ -1377,9 +1404,13 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> /** * Legacy method testing if some key maps into the specified value - * in this table. This method is identical in functionality to + * in this table. + * + * This method is identical in functionality to * {@link #containsValue(Object)}, and exists solely to ensure - * full compatibility with class {@link java.util.Hashtable}. + * full compatibility with class {@link java.util.Hashtable}, + * which supported this method prior to introduction of the + * Java Collections framework. * * @param value a value to search for * @return {@code true} if and only if some key maps to the @@ -1388,6 +1419,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * {@code false} otherwise * @throws NullPointerException if the specified value is null */ + // android-note : removed @deprecated tag from javadoc. public boolean contains(Object value) { // BEGIN android-note // removed deprecation @@ -1442,6 +1474,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * Creates a new {@link Set} backed by a ConcurrentHashMap * from the given type to {@code Boolean.TRUE}. * + * @param <K> the element type of the returned set * @return the new set * @since 1.8 * @@ -1458,9 +1491,10 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * * @param initialCapacity The implementation performs internal * sizing to accommodate this many elements. + * @param <K> the element type of the returned set + * @return the new set * @throws IllegalArgumentException if the initial capacity of * elements is negative - * @return the new set * @since 1.8 * * @hide @@ -1483,7 +1517,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * * @hide */ - public Set<K> keySet(V mappedValue) { + public KeySetView<K,V> keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); return new KeySetView<K,V>(this, mappedValue); @@ -1535,6 +1569,14 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> /* ---------------- Table Initialization and Resizing -------------- */ /** + * Returns the stamp bits for resizing a table of size n. + * Must be negative when shifted left by RESIZE_STAMP_SHIFT. + */ + static final int resizeStamp(int n) { + return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1)); + } + + /** * Initializes table, using the size recorded in sizeCtl. */ private final Node<K,V>[] initTable() { @@ -1546,8 +1588,8 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> try { if ((tab = table) == null || tab.length == 0) { int n = (sc > 0) ? sc : DEFAULT_CAPACITY; - @SuppressWarnings({"rawtypes","unchecked"}) - Node<K,V>[] nt = (Node<K,V>[])new Node[n]; + @SuppressWarnings("unchecked") + Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; table = tab = nt; sc = n - (n >>> 2); } @@ -1589,17 +1631,20 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> s = sumCount(); } if (check >= 0) { - Node<K,V>[] tab, nt; int sc; + Node<K,V>[] tab, nt; int n, sc; while (s >= (long)(sc = sizeCtl) && (tab = table) != null && - tab.length < MAXIMUM_CAPACITY) { + (n = tab.length) < MAXIMUM_CAPACITY) { + int rs = resizeStamp(n); if (sc < 0) { - if (sc == -1 || transferIndex <= transferOrigin || - (nt = nextTable) == null) + if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || + sc == rs + MAX_RESIZERS || (nt = nextTable) == null || + transferIndex <= 0) break; - if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) + if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) transfer(tab, nt); } - else if (U.compareAndSwapInt(this, SIZECTL, sc, -2)) + else if (U.compareAndSwapInt(this, SIZECTL, sc, + (rs << RESIZE_STAMP_SHIFT) + 2)) transfer(tab, null); s = sumCount(); } @@ -1611,12 +1656,19 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> */ final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) { Node<K,V>[] nextTab; int sc; - if ((f instanceof ForwardingNode) && + if (tab != null && (f instanceof ForwardingNode) && (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) { - if (nextTab == nextTable && tab == table && - transferIndex > transferOrigin && (sc = sizeCtl) < -1 && - U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) - transfer(tab, nextTab); + int rs = resizeStamp(tab.length); + while (nextTab == nextTable && table == tab && + (sc = sizeCtl) < 0) { + if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || + sc == rs + MAX_RESIZERS || transferIndex <= 0) + break; + if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) { + transfer(tab, nextTab); + break; + } + } return nextTab; } return table; @@ -1638,8 +1690,8 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { try { if (table == tab) { - @SuppressWarnings({"rawtypes","unchecked"}) - Node<K,V>[] nt = (Node<K,V>[])new Node[n]; + @SuppressWarnings("unchecked") + Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; table = nt; sc = n - (n >>> 2); } @@ -1650,9 +1702,21 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> } else if (c <= sc || n >= MAXIMUM_CAPACITY) break; - else if (tab == table && - U.compareAndSwapInt(this, SIZECTL, sc, -2)) - transfer(tab, null); + else if (tab == table) { + int rs = resizeStamp(n); + if (sc < 0) { + Node<K,V>[] nt; + if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || + sc == rs + MAX_RESIZERS || (nt = nextTable) == null || + transferIndex <= 0) + break; + if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) + transfer(tab, nt); + } + else if (U.compareAndSwapInt(this, SIZECTL, sc, + (rs << RESIZE_STAMP_SHIFT) + 2)) + transfer(tab, null); + } } } @@ -1666,35 +1730,27 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> stride = MIN_TRANSFER_STRIDE; // subdivide range if (nextTab == null) { // initiating try { - @SuppressWarnings({"rawtypes","unchecked"}) - Node<K,V>[] nt = (Node<K,V>[])new Node[n << 1]; + @SuppressWarnings("unchecked") + Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1]; nextTab = nt; } catch (Throwable ex) { // try to cope with OOME sizeCtl = Integer.MAX_VALUE; return; } nextTable = nextTab; - transferOrigin = n; transferIndex = n; - ForwardingNode<K,V> rev = new ForwardingNode<K,V>(tab); - for (int k = n; k > 0;) { // progressively reveal ready slots - int nextk = (k > stride) ? k - stride : 0; - for (int m = nextk; m < k; ++m) - nextTab[m] = rev; - for (int m = n + nextk; m < n + k; ++m) - nextTab[m] = rev; - U.putOrderedInt(this, TRANSFERORIGIN, k = nextk); - } } int nextn = nextTab.length; ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab); boolean advance = true; + boolean finishing = false; // to ensure sweep before committing nextTab for (int i = 0, bound = 0;;) { - int nextIndex, nextBound, fh; Node<K,V> f; + Node<K,V> f; int fh; while (advance) { - if (--i >= bound) + int nextIndex, nextBound; + if (--i >= bound || finishing) advance = false; - else if ((nextIndex = transferIndex) <= transferOrigin) { + else if ((nextIndex = transferIndex) <= 0) { i = -1; advance = false; } @@ -1708,24 +1764,22 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> } } if (i < 0 || i >= n || i + n >= nextn) { - for (int sc;;) { - if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) { - if (sc == -1) { - nextTable = null; - table = nextTab; - sizeCtl = (n << 1) - (n >>> 1); - } - return; - } + int sc; + if (finishing) { + nextTable = null; + table = nextTab; + sizeCtl = (n << 1) - (n >>> 1); + return; } - } - else if ((f = tabAt(tab, i)) == null) { - if (casTabAt(tab, i, null, fwd)) { - setTabAt(nextTab, i, null); - setTabAt(nextTab, i + n, null); - advance = true; + if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) { + if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT) + return; + finishing = advance = true; + i = n; // recheck before commit } } + else if ((f = tabAt(tab, i)) == null) + advance = casTabAt(tab, i, null, fwd); else if ((fh = f.hash) == MOVED) advance = true; // already processed else { @@ -1757,6 +1811,10 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> else hn = new Node<K,V>(ph, pk, pv, hn); } + setTabAt(nextTab, i, ln); + setTabAt(nextTab, i + n, hn); + setTabAt(tab, i, fwd); + advance = true; } else if (f instanceof TreeBin) { TreeBin<K,V> t = (TreeBin<K,V>)f; @@ -1788,13 +1846,11 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> (hc != 0) ? new TreeBin<K,V>(lo) : t; hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : (lc != 0) ? new TreeBin<K,V>(hi) : t; + setTabAt(nextTab, i, ln); + setTabAt(nextTab, i + n, hn); + setTabAt(tab, i, fwd); + advance = true; } - else - ln = hn = null; - setTabAt(nextTab, i, ln); - setTabAt(nextTab, i + n, hn); - setTabAt(tab, i, fwd); - advance = true; } } } @@ -1810,12 +1866,9 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> private final void treeifyBin(Node<K,V>[] tab, int index) { Node<K,V> b; int n, sc; if (tab != null) { - if ((n = tab.length) < MIN_TREEIFY_CAPACITY) { - if (tab == table && (sc = sizeCtl) >= 0 && - U.compareAndSwapInt(this, SIZECTL, sc, -2)) - transfer(tab, null); - } - else if ((b = tabAt(tab, index)) != null) { + if ((n = tab.length) < MIN_TREEIFY_CAPACITY) + tryPresize(n << 1); + else if ((b = tabAt(tab, index)) != null && b.hash >= 0) { synchronized (b) { if (tabAt(tab, index) == b) { TreeNode<K,V> hd = null, tl = null; @@ -1881,7 +1934,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) { if (k != null) { TreeNode<K,V> p = this; - do { + do { int ph, dir; K pk; TreeNode<K,V> q; TreeNode<K,V> pl = p.left, pr = p.right; if ((ph = p.hash) > h) @@ -1890,25 +1943,25 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> p = pr; else if ((pk = p.key) == k || (pk != null && k.equals(pk))) return p; - else if (pl == null && pr == null) - break; + else if (pl == null) + p = pr; + else if (pr == null) + p = pl; else if ((kc != null || (kc = comparableClassFor(k)) != null) && (dir = compareComparables(kc, k, pk)) != 0) p = (dir < 0) ? pl : pr; - else if (pl == null) - p = pr; - else if (pr == null || - (q = pr.findTreeNode(h, k, kc)) == null) - p = pl; - else + else if ((q = pr.findTreeNode(h, k, kc)) != null) return q; + else + p = pl; } while (p != null); } return null; } } + /* ---------------- TreeBins -------------- */ /** @@ -1929,6 +1982,23 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> static final int READER = 4; // increment value for setting read lock /** + * Tie-breaking utility for ordering insertions when equal + * hashCodes and non-comparable. We don't require a total + * order, just a consistent insertion rule to maintain + * equivalence across rebalancings. Tie-breaking further than + * necessary simplifies testing a bit. + */ + static int tieBreakOrder(Object a, Object b) { + int d; + if (a == null || b == null || + (d = a.getClass().getName(). + compareTo(b.getClass().getName())) == 0) + d = (System.identityHashCode(a) <= System.identityHashCode(b) ? + -1 : 1); + return d; + } + + /** * Creates bin with initial set of nodes headed by b. */ TreeBin(TreeNode<K,V> b) { @@ -1944,21 +2014,21 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> r = x; } else { - Object key = x.key; - int hash = x.hash; + K k = x.key; + int h = x.hash; Class<?> kc = null; for (TreeNode<K,V> p = r;;) { int dir, ph; - if ((ph = p.hash) > hash) + K pk = p.key; + if ((ph = p.hash) > h) dir = -1; - else if (ph < hash) + else if (ph < h) dir = 1; - else if ((kc != null || - (kc = comparableClassFor(key)) != null)) - dir = compareComparables(kc, key, p.key); - else - dir = 0; - TreeNode<K,V> xp = p; + else if ((kc == null && + (kc = comparableClassFor(k)) == null) || + (dir = compareComparables(kc, k, pk)) == 0) + dir = tieBreakOrder(k, pk); + TreeNode<K,V> xp = p; if ((p = (dir <= 0) ? p.left : p.right) == null) { x.parent = xp; if (dir <= 0) @@ -1972,6 +2042,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> } } this.root = r; + assert checkInvariants(root); } /** @@ -1995,7 +2066,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> private final void contendedLock() { boolean waiting = false; for (int s;;) { - if (((s = lockState) & WRITER) == 0) { + if (((s = lockState) & ~WAITER) == 0) { if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) { if (waiting) waiter = null; @@ -2020,12 +2091,13 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> */ final Node<K,V> find(int h, Object k) { if (k != null) { - for (Node<K,V> e = first; e != null; e = e.next) { + for (Node<K,V> e = first; e != null; ) { int s; K ek; if (((s = lockState) & (WAITER|WRITER)) != 0) { if (e.hash == h && ((ek = e.key) == k || (ek != null && k.equals(ek)))) return e; + e = e.next; } else if (U.compareAndSwapInt(this, LOCKSTATE, s, s + READER)) { @@ -2054,10 +2126,15 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * Finds or adds a node. * @return null if added */ + /** + * Finds or adds a node. + * @return null if added + */ final TreeNode<K,V> putTreeVal(int h, K k, V v) { Class<?> kc = null; + boolean searched = false; for (TreeNode<K,V> p = root;;) { - int dir, ph; K pk; TreeNode<K,V> q, pr; + int dir, ph; K pk; if (p == null) { first = root = new TreeNode<K,V>(h, k, v, null, null); break; @@ -2071,21 +2148,25 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> else if ((kc == null && (kc = comparableClassFor(k)) == null) || (dir = compareComparables(kc, k, pk)) == 0) { - if (p.left == null) - dir = 1; - else if ((pr = p.right) == null || - (q = pr.findTreeNode(h, k, kc)) == null) - dir = -1; - else - return q; + if (!searched) { + TreeNode<K,V> q, ch; + searched = true; + if (((ch = p.left) != null && + (q = ch.findTreeNode(h, k, kc)) != null) || + ((ch = p.right) != null && + (q = ch.findTreeNode(h, k, kc)) != null)) + return q; + } + dir = tieBreakOrder(k, pk); } + TreeNode<K,V> xp = p; - if ((p = (dir < 0) ? p.left : p.right) == null) { + if ((p = (dir <= 0) ? p.left : p.right) == null) { TreeNode<K,V> x, f = first; first = x = new TreeNode<K,V>(h, k, v, f, xp); if (f != null) f.prev = x; - if (dir < 0) + if (dir <= 0) xp.left = x; else xp.right = x; @@ -2308,7 +2389,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root, TreeNode<K,V> x) { - for (TreeNode<K,V> xp, xpl, xpr;;) { + for (TreeNode<K,V> xp, xpl, xpr;;) { if (x == null || x == root) return root; else if ((xp = x.parent) == null) { @@ -2440,8 +2521,20 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> /* ----------------Table Traversal -------------- */ /** + * Records the table, its length, and current traversal index for a + * traverser that must process a region of a forwarded table before + * proceeding with current table. + */ + static final class TableStack<K,V> { + int length; + int index; + Node<K,V>[] tab; + TableStack<K,V> next; + } + + /** * Encapsulates traversal for methods such as containsValue; also - * serves as a base class for other iterators. + * serves as a base class for other iterators and spliterators. * * Method advance visits once each still-valid node that was * reachable upon iterator construction. It might miss some that @@ -2463,6 +2556,7 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> static class Traverser<K,V> { Node<K,V>[] tab; // current table; updated if resized Node<K,V> next; // the next entry to use + TableStack<K,V> stack, spare; // to save/restore on ForwardingNodes int index; // index of bin to use next int baseIndex; // current index of initial table int baseLimit; // index bound for initial table @@ -2484,16 +2578,17 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> if ((e = next) != null) e = e.next; for (;;) { - Node<K,V>[] t; int i, n; K ek; // must use locals in checks + Node<K,V>[] t; int i, n; // must use locals in checks if (e != null) return next = e; if (baseIndex >= baseLimit || (t = tab) == null || (n = t.length) <= (i = index) || i < 0) return next = null; - if ((e = tabAt(t, index)) != null && e.hash < 0) { + if ((e = tabAt(t, i)) != null && e.hash < 0) { if (e instanceof ForwardingNode) { tab = ((ForwardingNode<K,V>)e).nextTable; e = null; + pushState(t, i, n); continue; } else if (e instanceof TreeBin) @@ -2501,9 +2596,48 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> else e = null; } - if ((index += baseSize) >= n) - index = ++baseIndex; // visit upper slots if present + if (stack != null) + recoverState(n); + else if ((index = i + baseSize) >= n) + index = ++baseIndex; // visit upper slots if present + } + } + + /** + * Saves traversal state upon encountering a forwarding node. + */ + private void pushState(Node<K,V>[] t, int i, int n) { + TableStack<K,V> s = spare; // reuse if possible + if (s != null) + spare = s.next; + else + s = new TableStack<K,V>(); + s.tab = t; + s.length = n; + s.index = i; + s.next = stack; + stack = s; + } + + /** + * Possibly pops traversal state. + * + * @param n length of current table + */ + private void recoverState(int n) { + TableStack<K,V> s; int len; + while ((s = stack) != null && (index += (len = s.length)) >= n) { + n = len; + index = s.index; + tab = s.tab; + s.tab = null; + TableStack<K,V> next = s.next; + s.next = spare; // save for reuse + stack = next; + spare = s; } + if (s == null && (index += baseSize) >= n) + index = ++baseIndex; } } @@ -2639,7 +2773,6 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> /** * Base class for views. - * */ abstract static class CollectionView<K,V,E> implements Collection<E>, java.io.Serializable { @@ -2797,13 +2930,12 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> * common value. This class cannot be directly instantiated. * See {@link #keySet() keySet()}, * {@link #keySet(Object) keySet(V)}, - * {@link #newKeySet() newKeySet()}, - * {@link #newKeySet(int) newKeySet(int)}. * * @since 1.8 * * @hide */ + // android-note: removed references to hidden APIs. public static class KeySetView<K,V> extends CollectionView<K,V,K> implements Set<K>, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; @@ -3162,7 +3294,6 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> private static final sun.misc.Unsafe U; private static final long SIZECTL; private static final long TRANSFERINDEX; - private static final long TRANSFERORIGIN; private static final long BASECOUNT; private static final long CELLSBUSY; private static final long CELLVALUE; @@ -3177,8 +3308,6 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> (k.getDeclaredField("sizeCtl")); TRANSFERINDEX = U.objectFieldOffset (k.getDeclaredField("transferIndex")); - TRANSFERORIGIN = U.objectFieldOffset - (k.getDeclaredField("transferOrigin")); BASECOUNT = U.objectFieldOffset (k.getDeclaredField("baseCount")); CELLSBUSY = U.objectFieldOffset @@ -3195,6 +3324,10 @@ public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V> } catch (Exception e) { throw new Error(e); } + + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; } } diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java index b39a533..9010cbe 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java @@ -32,9 +32,9 @@ import java.util.Queue; * does not permit the use of {@code null} elements. * * <p>This implementation employs an efficient <em>non-blocking</em> - * algorithm based on one described in <a - * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple, - * Fast, and Practical Non-Blocking and Blocking Concurrent Queue + * algorithm based on one described in + * <a href="http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf"> + * Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue * Algorithms</a> by Maged M. Michael and Michael L. Scott. * * <p>Iterators are <i>weakly consistent</i>, returning elements diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentMap.java index 27feeb2..1391f04 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentMap.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentMap.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.Map; // BEGIN android-note diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java index e87fbee..17890ff 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; // BEGIN android-note diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java index 4a76104..0e8b64a 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; // BEGIN android-note @@ -215,7 +216,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> * highly contended cases. * * Unlike most skip-list implementations, index insertion and - * deletion here require a separate traversal pass occuring after + * deletion here require a separate traversal pass occurring after * the base-level action, to add or remove index nodes. This adds * to single-threaded overhead, but improves contended * multithreaded performance by narrowing interference windows, @@ -2358,8 +2359,8 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> } static final class Values<E> extends AbstractCollection<E> { - private final ConcurrentNavigableMap<?, E> m; - Values(ConcurrentNavigableMap<?, E> map) { + private final ConcurrentNavigableMap<?,E> m; + Values(ConcurrentNavigableMap<?,E> map) { m = map; } public Iterator<E> iterator() { @@ -2566,7 +2567,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> } /** - * Returns lowest absolute key (ignoring directonality). + * Returns lowest absolute key (ignoring directionality). */ private K lowestKey() { ConcurrentSkipListMap.Node<K,V> n = loNode(); @@ -2577,7 +2578,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> } /** - * Returns highest absolute key (ignoring directonality). + * Returns highest absolute key (ignoring directionality). */ private K highestKey() { ConcurrentSkipListMap.Node<K,V> n = hiNode(); diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java index f1402b6..13f1a43 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; // BEGIN android-note diff --git a/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java b/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java index 6fa8feb..347ed14 100644 --- a/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java +++ b/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; // BEGIN android-note diff --git a/luni/src/main/java/java/util/concurrent/CountDownLatch.java b/luni/src/main/java/java/util/concurrent/CountDownLatch.java index fe0fa65..77093f7 100644 --- a/luni/src/main/java/java/util/concurrent/CountDownLatch.java +++ b/luni/src/main/java/java/util/concurrent/CountDownLatch.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.concurrent.locks.AbstractQueuedSynchronizer; /** diff --git a/luni/src/main/java/java/util/concurrent/CountedCompleter.java b/luni/src/main/java/java/util/concurrent/CountedCompleter.java index d5f794e..b868037 100644 --- a/luni/src/main/java/java/util/concurrent/CountedCompleter.java +++ b/luni/src/main/java/java/util/concurrent/CountedCompleter.java @@ -686,7 +686,7 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> { } /** - * Returns the result of the computation. By default + * Returns the result of the computation. By default, * returns {@code null}, which is appropriate for {@code Void} * actions, but in other cases should be overridden, almost * always to return a field or function of a field that diff --git a/luni/src/main/java/java/util/concurrent/CyclicBarrier.java b/luni/src/main/java/java/util/concurrent/CyclicBarrier.java index e1a7bee..d698501 100644 --- a/luni/src/main/java/java/util/concurrent/CyclicBarrier.java +++ b/luni/src/main/java/java/util/concurrent/CyclicBarrier.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -125,7 +126,7 @@ public class CyclicBarrier { private final Condition trip = lock.newCondition(); /** The number of parties */ private final int parties; - /* The command to run when tripped */ + /** The command to run when tripped */ private final Runnable barrierCommand; /** The current generation */ private Generation generation = new Generation(); diff --git a/luni/src/main/java/java/util/concurrent/DelayQueue.java b/luni/src/main/java/java/util/concurrent/DelayQueue.java index 945249e..e4a715e 100644 --- a/luni/src/main/java/java/util/concurrent/DelayQueue.java +++ b/luni/src/main/java/java/util/concurrent/DelayQueue.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import static java.util.concurrent.TimeUnit.NANOSECONDS; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -60,7 +61,7 @@ public class DelayQueue<E extends Delayed> extends AbstractQueue<E> * signalled. So waiting threads must be prepared to acquire * and lose leadership while waiting. */ - private Thread leader = null; + private Thread leader; /** * Condition signalled when a newer element becomes available diff --git a/luni/src/main/java/java/util/concurrent/Exchanger.java b/luni/src/main/java/java/util/concurrent/Exchanger.java index 01d5960..60871b4 100644 --- a/luni/src/main/java/java/util/concurrent/Exchanger.java +++ b/luni/src/main/java/java/util/concurrent/Exchanger.java @@ -6,9 +6,6 @@ */ package java.util.concurrent; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.LockSupport; /** * A synchronization point at which threads can pair and swap elements diff --git a/luni/src/main/java/java/util/concurrent/Executor.java b/luni/src/main/java/java/util/concurrent/Executor.java index f55209a..095ebfc 100644 --- a/luni/src/main/java/java/util/concurrent/Executor.java +++ b/luni/src/main/java/java/util/concurrent/Executor.java @@ -12,7 +12,7 @@ package java.util.concurrent; * mechanics of how each task will be run, including details of thread * use, scheduling, etc. An {@code Executor} is normally used * instead of explicitly creating threads. For example, rather than - * invoking {@code new Thread(new(RunnableTask())).start()} for each + * invoking {@code new Thread(new RunnableTask()).start()} for each * of a set of tasks, you might use: * * <pre> @@ -52,7 +52,7 @@ package java.util.concurrent; * * <pre> {@code * class SerialExecutor implements Executor { - * final Queue<Runnable> tasks = new ArrayDeque<Runnable>(); + * final Queue<Runnable> tasks = new ArrayDeque<>(); * final Executor executor; * Runnable active; * @@ -61,7 +61,7 @@ package java.util.concurrent; * } * * public synchronized void execute(final Runnable r) { - * tasks.offer(new Runnable() { + * tasks.add(new Runnable() { * public void run() { * try { * r.run(); diff --git a/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java b/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java index c0d6006..9514246 100644 --- a/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java +++ b/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java @@ -132,7 +132,7 @@ public class ExecutorCompletionService<V> implements CompletionService<V> { * @param completionQueue the queue to use as the completion queue * normally one dedicated for use by this service. This * queue is treated as unbounded -- failed attempted - * {@code Queue.add} operations for completed taskes cause + * {@code Queue.add} operations for completed tasks cause * them not to be retrievable. * @throws NullPointerException if executor or completionQueue are {@code null} */ diff --git a/luni/src/main/java/java/util/concurrent/ExecutorService.java b/luni/src/main/java/java/util/concurrent/ExecutorService.java index 4599f59..2173529 100644 --- a/luni/src/main/java/java/util/concurrent/ExecutorService.java +++ b/luni/src/main/java/java/util/concurrent/ExecutorService.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.List; import java.util.Collection; @@ -29,8 +30,8 @@ import java.util.Collection; * reclamation of its resources. * * <p>Method {@code submit} extends base method {@link - * Executor#execute} by creating and returning a {@link Future} that - * can be used to cancel execution and/or wait for completion. + * Executor#execute(Runnable)} by creating and returning a {@link Future} + * that can be used to cancel execution and/or wait for completion. * Methods {@code invokeAny} and {@code invokeAll} perform the most * commonly useful forms of bulk execution, executing a collection of * tasks and then waiting for at least one, or all, to diff --git a/luni/src/main/java/java/util/concurrent/Executors.java b/luni/src/main/java/java/util/concurrent/Executors.java index 53c68fc..8731372 100644 --- a/luni/src/main/java/java/util/concurrent/Executors.java +++ b/luni/src/main/java/java/util/concurrent/Executors.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.security.AccessControlContext; diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinPool.java b/luni/src/main/java/java/util/concurrent/ForkJoinPool.java index 9448616..5bcac28 100644 --- a/luni/src/main/java/java/util/concurrent/ForkJoinPool.java +++ b/luni/src/main/java/java/util/concurrent/ForkJoinPool.java @@ -12,14 +12,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.concurrent.AbstractExecutorService; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.RunnableFuture; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; /** * An {@link ExecutorService} for running {@link ForkJoinTask}s. @@ -498,6 +490,7 @@ public class ForkJoinPool extends AbstractExecutorService { * (7) Exported methods * (8) Static block initializing statics in minimally dependent order */ + // android-note: Removed references to CountedCompleters. // Static utilities @@ -524,8 +517,8 @@ public class ForkJoinPool extends AbstractExecutorService { * Returns a new worker thread operating in the given pool. * * @param pool the pool this thread works in - * @throws NullPointerException if the pool is null * @return the new worker thread + * @throws NullPointerException if the pool is null */ public ForkJoinWorkerThread newThread(ForkJoinPool pool); } @@ -2090,7 +2083,7 @@ public class ForkJoinPool extends AbstractExecutorService { w.currentSteal = ps; } } - else if (active) { // decrement active count without queuing + else if (active) { // decrement active count without queuing long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT); if ((int)(nc >> AC_SHIFT) + parallelism == 0) break; // bypass decrement-then-increment diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinTask.java b/luni/src/main/java/java/util/concurrent/ForkJoinTask.java index c6bc6de..d34cae3 100644 --- a/luni/src/main/java/java/util/concurrent/ForkJoinTask.java +++ b/luni/src/main/java/java/util/concurrent/ForkJoinTask.java @@ -12,14 +12,6 @@ import java.util.List; import java.util.RandomAccess; import java.lang.ref.WeakReference; import java.lang.ref.ReferenceQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.RunnableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantLock; import java.lang.reflect.Constructor; @@ -177,6 +169,8 @@ import java.lang.reflect.Constructor; * @since 1.7 * @author Doug Lea */ +// android-note: Removed references to hidden apis commonPool, CountedCompleter +// etc. public abstract class ForkJoinTask<V> implements Future<V>, Serializable { /* @@ -407,11 +401,13 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable { final Throwable ex; ExceptionNode next; final long thrower; // use id not ref to avoid weak cycles + final int hashCode; // store task hashCode before weak ref disappears ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) { super(task, exceptionTableRefQueue); this.ex = ex; this.next = next; this.thrower = Thread.currentThread().getId(); + this.hashCode = System.identityHashCode(task); } } @@ -573,9 +569,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable { private static void expungeStaleExceptions() { for (Object x; (x = exceptionTableRefQueue.poll()) != null;) { if (x instanceof ExceptionNode) { - ForkJoinTask<?> key = ((ExceptionNode)x).get(); + int hashCode = ((ExceptionNode)x).hashCode; ExceptionNode[] t = exceptionTable; - int i = System.identityHashCode(key) & (t.length - 1); + int i = hashCode & (t.length - 1); ExceptionNode e = t[i]; ExceptionNode pred = null; while (e != null) { @@ -1413,8 +1409,6 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable { try { result = callable.call(); return true; - } catch (Error err) { - throw err; } catch (RuntimeException rex) { throw rex; } catch (Exception ex) { diff --git a/luni/src/main/java/java/util/concurrent/FutureTask.java b/luni/src/main/java/java/util/concurrent/FutureTask.java index 114fe49..5e24fc8 100644 --- a/luni/src/main/java/java/util/concurrent/FutureTask.java +++ b/luni/src/main/java/java/util/concurrent/FutureTask.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.concurrent.locks.LockSupport; /** @@ -134,7 +135,7 @@ public class FutureTask<V> implements RunnableFuture<V> { public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && - UNSAFE.compareAndSwapInt(this, stateOffset, NEW, + U.compareAndSwapInt(this, STATE, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception @@ -144,7 +145,7 @@ public class FutureTask<V> implements RunnableFuture<V> { if (t != null) t.interrupt(); } finally { // final state - UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); + U.putOrderedInt(this, STATE, INTERRUPTED); } } } finally { @@ -198,9 +199,9 @@ public class FutureTask<V> implements RunnableFuture<V> { * @param v the value */ protected void set(V v) { - if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { + if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v; - UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state + U.putOrderedInt(this, STATE, NORMAL); // final state finishCompletion(); } } @@ -216,17 +217,16 @@ public class FutureTask<V> implements RunnableFuture<V> { * @param t the cause of failure */ protected void setException(Throwable t) { - if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { + if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = t; - UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state + U.putOrderedInt(this, STATE, EXCEPTIONAL); // final state finishCompletion(); } } public void run() { if (state != NEW || - !UNSAFE.compareAndSwapObject(this, runnerOffset, - null, Thread.currentThread())) + !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return; try { Callable<V> c = callable; @@ -263,12 +263,11 @@ public class FutureTask<V> implements RunnableFuture<V> { * designed for use with tasks that intrinsically execute more * than once. * - * @return true if successfully run and reset + * @return {@code true} if successfully run and reset */ protected boolean runAndReset() { if (state != NEW || - !UNSAFE.compareAndSwapObject(this, runnerOffset, - null, Thread.currentThread())) + !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return false; boolean ran = false; int s = state; @@ -335,7 +334,7 @@ public class FutureTask<V> implements RunnableFuture<V> { private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { - if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) { + if (U.compareAndSwapObject(this, WAITERS, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { @@ -362,39 +361,61 @@ public class FutureTask<V> implements RunnableFuture<V> { * * @param timed true if use timed waits * @param nanos time to wait, if timed - * @return state upon completion + * @return state upon completion or at timeout */ private int awaitDone(boolean timed, long nanos) throws InterruptedException { - final long deadline = timed ? System.nanoTime() + nanos : 0L; + // The code below is very delicate, to achieve these goals: + // - call nanoTime exactly once for each call to park + // - if nanos <= 0, return promptly without allocation or nanoTime + // - if nanos == Long.MIN_VALUE, don't underflow + // - if nanos == Long.MAX_VALUE, and nanoTime is non-monotonic + // and we suffer a spurious wakeup, we will do no worse than + // to park-spin for a while + long startTime = 0L; // Special value 0L means not yet parked WaitNode q = null; boolean queued = false; for (;;) { - if (Thread.interrupted()) { - removeWaiter(q); - throw new InterruptedException(); - } - int s = state; if (s > COMPLETING) { if (q != null) q.thread = null; return s; } - else if (s == COMPLETING) // cannot time out yet + else if (s == COMPLETING) + // We may have already promised (via isDone) that we are done + // so never return empty-handed or throw InterruptedException Thread.yield(); - else if (q == null) + else if (Thread.interrupted()) { + removeWaiter(q); + throw new InterruptedException(); + } + else if (q == null) { + if (timed && nanos <= 0L) + return s; q = new WaitNode(); + } else if (!queued) - queued = UNSAFE.compareAndSwapObject(this, waitersOffset, - q.next = waiters, q); + queued = U.compareAndSwapObject(this, WAITERS, + q.next = waiters, q); else if (timed) { - nanos = deadline - System.nanoTime(); - if (nanos <= 0L) { - removeWaiter(q); - return state; + final long parkNanos; + if (startTime == 0L) { // first time + startTime = System.nanoTime(); + if (startTime == 0L) + startTime = 1L; + parkNanos = nanos; + } else { + long elapsed = System.nanoTime() - startTime; + if (elapsed >= nanos) { + removeWaiter(q); + return state; + } + parkNanos = nanos - elapsed; } - LockSupport.parkNanos(this, nanos); + // nanoTime may be slow; recheck before parking + if (state < COMPLETING) + LockSupport.parkNanos(this, parkNanos); } else LockSupport.park(this); @@ -425,8 +446,7 @@ public class FutureTask<V> implements RunnableFuture<V> { if (pred.thread == null) // check for race continue retry; } - else if (!UNSAFE.compareAndSwapObject(this, waitersOffset, - q, s)) + else if (!U.compareAndSwapObject(this, WAITERS, q, s)) continue retry; } break; @@ -435,23 +455,25 @@ public class FutureTask<V> implements RunnableFuture<V> { } // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long stateOffset; - private static final long runnerOffset; - private static final long waitersOffset; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final long STATE; + private static final long RUNNER; + private static final long WAITERS; static { try { - UNSAFE = sun.misc.Unsafe.getUnsafe(); - Class<?> k = FutureTask.class; - stateOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("state")); - runnerOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("runner")); - waitersOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("waiters")); + STATE = U.objectFieldOffset + (FutureTask.class.getDeclaredField("state")); + RUNNER = U.objectFieldOffset + (FutureTask.class.getDeclaredField("runner")); + WAITERS = U.objectFieldOffset + (FutureTask.class.getDeclaredField("waiters")); } catch (Exception e) { throw new Error(e); } + + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; } } diff --git a/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java b/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java index a041fb1..db48420 100644 --- a/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java +++ b/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java @@ -11,7 +11,6 @@ import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; -import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; // BEGIN android-note @@ -76,7 +75,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E> * * A FIFO dual queue may be implemented using a variation of the * Michael & Scott (M&S) lock-free queue algorithm - * (http://www.cs.rochester.edu/u/scott/papers/1996_PODC_queues.pdf). + * (http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf). * It maintains two pointer fields, "head", pointing to a * (matched) node that in turn points to the first actual * (unmatched) queue node (or null if empty); and "tail" that @@ -1313,5 +1312,9 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E> } catch (Exception e) { throw new Error(e); } + + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; } } diff --git a/luni/src/main/java/java/util/concurrent/Phaser.java b/luni/src/main/java/java/util/concurrent/Phaser.java index a97d187..c5faf16 100644 --- a/luni/src/main/java/java/util/concurrent/Phaser.java +++ b/luni/src/main/java/java/util/concurrent/Phaser.java @@ -6,8 +6,6 @@ package java.util.concurrent; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; @@ -1128,5 +1126,9 @@ public class Phaser { } catch (Exception e) { throw new Error(e); } + + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; } } diff --git a/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java b/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java index 0f9e715..40b3510 100644 --- a/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java +++ b/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java @@ -190,7 +190,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E> /** * Creates a {@code PriorityBlockingQueue} containing the elements * in the specified collection. If the specified collection is a - * {@link SortedSet} or a {@link PriorityQueue}, this + * {@link SortedSet} or a {@link PriorityQueue}, this * priority queue will be ordered according to the same ordering. * Otherwise, this priority queue will be ordered according to the * {@linkplain Comparable natural ordering} of its elements. diff --git a/luni/src/main/java/java/util/concurrent/RecursiveTask.java b/luni/src/main/java/java/util/concurrent/RecursiveTask.java index 80baa52..d201bd6 100644 --- a/luni/src/main/java/java/util/concurrent/RecursiveTask.java +++ b/luni/src/main/java/java/util/concurrent/RecursiveTask.java @@ -46,6 +46,7 @@ public abstract class RecursiveTask<V> extends ForkJoinTask<V> { /** * The main computation performed by this task. + * @return the result of the computation */ protected abstract V compute(); diff --git a/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java b/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java index b978fae..d5bae22 100644 --- a/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java +++ b/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java @@ -16,9 +16,9 @@ package java.util.concurrent; * {@code scheduleWithFixedDelay} methods create and execute tasks * that run periodically until cancelled. * - * <p>Commands submitted using the {@link Executor#execute} and - * {@link ExecutorService} {@code submit} methods are scheduled with - * a requested delay of zero. Zero and negative delays (but not + * <p>Commands submitted using the {@link Executor#execute(Runnable)} + * and {@link ExecutorService} {@code submit} methods are scheduled + * with a requested delay of zero. Zero and negative delays (but not * periods) are also allowed in {@code schedule} methods, and are * treated as requests for immediate execution. * @@ -33,7 +33,7 @@ package java.util.concurrent; * which the task is enabled due to network time synchronization * protocols, clock drift, or other factors. * - * The {@link Executors} class provides convenient factory methods for + * <p>The {@link Executors} class provides convenient factory methods for * the ScheduledExecutorService implementations provided in this package. * * <h3>Usage Example</h3> diff --git a/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java b/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java index 483981d..d01cc33 100644 --- a/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -5,7 +5,9 @@ */ package java.util.concurrent; + import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -17,11 +19,11 @@ import java.util.*; /** * A {@link ThreadPoolExecutor} that can additionally schedule - * commands to run after a given delay, or to execute - * periodically. This class is preferable to {@link java.util.Timer} - * when multiple worker threads are needed, or when the additional - * flexibility or capabilities of {@link ThreadPoolExecutor} (which - * this class extends) are required. + * commands to run after a given delay, or to execute periodically. + * This class is preferable to {@link java.util.Timer} when multiple + * worker threads are needed, or when the additional flexibility or + * capabilities of {@link ThreadPoolExecutor} (which this class + * extends) are required. * * <p>Delayed tasks execute no sooner than they are enabled, but * without any real-time guarantees about when, after they are @@ -35,9 +37,9 @@ import java.util.*; * elapses. While this enables further inspection and monitoring, it * may also cause unbounded retention of cancelled tasks. * - * <p>Successive executions of a task scheduled via - * {@code scheduleAtFixedRate} or - * {@code scheduleWithFixedDelay} do not overlap. While different + * <p>Successive executions of a periodic task scheduled via + * {@link #scheduleAtFixedRate} or + * {@link #scheduleWithFixedDelay} do not overlap. While different * executions may be performed by different threads, the effects of * prior executions <a * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> @@ -132,7 +134,7 @@ public class ScheduledThreadPoolExecutor private volatile boolean executeExistingDelayedTasksAfterShutdown = true; /** - * True if ScheduledFutureTask.cancel should remove from queue + * True if ScheduledFutureTask.cancel should remove from queue. */ private volatile boolean removeOnCancel = false; @@ -159,10 +161,10 @@ public class ScheduledThreadPoolExecutor private long time; /** - * Period in nanoseconds for repeating tasks. A positive - * value indicates fixed-rate execution. A negative value - * indicates fixed-delay execution. A value of 0 indicates a - * non-repeating task. + * Period in nanoseconds for repeating tasks. + * A positive value indicates fixed-rate execution. + * A negative value indicates fixed-delay execution. + * A value of 0 indicates a non-repeating (one-shot) task. */ private final long period; @@ -177,19 +179,21 @@ public class ScheduledThreadPoolExecutor /** * Creates a one-shot action with given nanoTime-based trigger time. */ - ScheduledFutureTask(Runnable r, V result, long ns) { + ScheduledFutureTask(Runnable r, V result, long triggerTime) { super(r, result); - this.time = ns; + this.time = triggerTime; this.period = 0; this.sequenceNumber = sequencer.getAndIncrement(); } /** - * Creates a periodic action with given nano time and period. + * Creates a periodic action with given nanoTime-based initial + * trigger time and period. */ - ScheduledFutureTask(Runnable r, V result, long ns, long period) { + ScheduledFutureTask(Runnable r, V result, long triggerTime, + long period) { super(r, result); - this.time = ns; + this.time = triggerTime; this.period = period; this.sequenceNumber = sequencer.getAndIncrement(); } @@ -197,9 +201,9 @@ public class ScheduledThreadPoolExecutor /** * Creates a one-shot action with given nanoTime-based trigger time. */ - ScheduledFutureTask(Callable<V> callable, long ns) { + ScheduledFutureTask(Callable<V> callable, long triggerTime) { super(callable); - this.time = ns; + this.time = triggerTime; this.period = 0; this.sequenceNumber = sequencer.getAndIncrement(); } @@ -389,6 +393,22 @@ public class ScheduledThreadPoolExecutor } /** + * The default keep-alive time for pool threads. + * + * Normally, this value is unused because all pool threads will be + * core threads, but if a user creates a pool with a corePoolSize + * of zero (against our advice), we keep a thread alive as long as + * there are queued tasks. If the keep alive time is zero (the + * historic value), we end up hot-spinning in getTask, wasting a + * CPU. But on the other hand, if we set the value too high, and + * users create a one-shot pool which they don't cleanly shutdown, + * the pool's non-daemon threads will prevent JVM termination. A + * small but non-zero value (relative to a JVM's lifetime) seems + * best. + */ + private static final long DEFAULT_KEEPALIVE_MILLIS = 10L; + + /** * Creates a new {@code ScheduledThreadPoolExecutor} with the * given core pool size. * @@ -397,7 +417,8 @@ public class ScheduledThreadPoolExecutor * @throws IllegalArgumentException if {@code corePoolSize < 0} */ public ScheduledThreadPoolExecutor(int corePoolSize) { - super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, + super(corePoolSize, Integer.MAX_VALUE, + DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); } @@ -414,13 +435,14 @@ public class ScheduledThreadPoolExecutor */ public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) { - super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, + super(corePoolSize, Integer.MAX_VALUE, + DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue(), threadFactory); } /** - * Creates a new ScheduledThreadPoolExecutor with the given - * initial parameters. + * Creates a new {@code ScheduledThreadPoolExecutor} with the + * given initial parameters. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set @@ -431,13 +453,14 @@ public class ScheduledThreadPoolExecutor */ public ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler) { - super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, + super(corePoolSize, Integer.MAX_VALUE, + DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue(), handler); } /** - * Creates a new ScheduledThreadPoolExecutor with the given - * initial parameters. + * Creates a new {@code ScheduledThreadPoolExecutor} with the + * given initial parameters. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set @@ -452,19 +475,20 @@ public class ScheduledThreadPoolExecutor public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler) { - super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, + super(corePoolSize, Integer.MAX_VALUE, + DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue(), threadFactory, handler); } /** - * Returns the trigger time of a delayed action. + * Returns the nanoTime-based trigger time of a delayed action. */ private long triggerTime(long delay, TimeUnit unit) { return triggerTime(unit.toNanos((delay < 0) ? 0 : delay)); } /** - * Returns the trigger time of a delayed action. + * Returns the nanoTime-based trigger time of a delayed action. */ long triggerTime(long delay) { return now() + @@ -497,7 +521,7 @@ public class ScheduledThreadPoolExecutor TimeUnit unit) { if (command == null || unit == null) throw new NullPointerException(); - RunnableScheduledFuture<?> t = decorateTask(command, + RunnableScheduledFuture<Void> t = decorateTask(command, new ScheduledFutureTask<Void>(command, null, triggerTime(delay, unit))); delayedExecute(t); @@ -725,6 +749,7 @@ public class ScheduledThreadPoolExecutor * {@code true}, future executions of existing periodic tasks will * be cancelled. */ + // android-note: Removed "throws SecurityException" doc. public void shutdown() { super.shutdown(); } @@ -744,23 +769,28 @@ public class ScheduledThreadPoolExecutor * fails to respond to interrupts may never terminate. * * @return list of tasks that never commenced execution. - * Each element of this list is a {@link ScheduledFuture}, - * including those tasks submitted using {@code execute}, - * which are for scheduling purposes used as the basis of a - * zero-delay {@code ScheduledFuture}. + * Each element of this list is a {@link ScheduledFuture}. + * For tasks submitted via one of the {@code schedule} + * methods, the element will be identical to the returned + * {@code ScheduledFuture}. For tasks submitted using + * {@link #execute}, the element will be a zero-delay {@code + * ScheduledFuture}. */ + // android-note: Removed "throws SecurityException" doc. public List<Runnable> shutdownNow() { return super.shutdownNow(); } /** - * Returns the task queue used by this executor. Each element of - * this queue is a {@link ScheduledFuture}, including those - * tasks submitted using {@code execute} which are for scheduling - * purposes used as the basis of a zero-delay - * {@code ScheduledFuture}. Iteration over this queue is - * <em>not</em> guaranteed to traverse tasks in the order in - * which they will execute. + * Returns the task queue used by this executor. + * Each element of this list is a {@link ScheduledFuture}. + * For tasks submitted via one of the {@code schedule} methods, the + * element will be identical to the returned {@code ScheduledFuture}. + * For tasks submitted using {@link #execute}, the element will be a + * zero-delay {@code ScheduledFuture}. + * + * <p>Iteration over this queue is <em>not</em> guaranteed to traverse + * tasks in the order in which they will execute. * * @return the task queue */ @@ -803,7 +833,7 @@ public class ScheduledThreadPoolExecutor private RunnableScheduledFuture<?>[] queue = new RunnableScheduledFuture<?>[INITIAL_CAPACITY]; private final ReentrantLock lock = new ReentrantLock(); - private int size = 0; + private int size; /** * Thread designated to wait for the task at the head of the @@ -821,7 +851,7 @@ public class ScheduledThreadPoolExecutor * signalled. So waiting threads must be prepared to acquire * and lose leadership while waiting. */ - private Thread leader = null; + private Thread leader; /** * Condition signalled when a newer task becomes available at the @@ -1220,11 +1250,11 @@ public class ScheduledThreadPoolExecutor * Snapshot iterator that works off copy of underlying q array. */ private class Itr implements Iterator<Runnable> { - final RunnableScheduledFuture[] array; + final RunnableScheduledFuture<?>[] array; int cursor = 0; // index of next element to return int lastRet = -1; // index of last element, or -1 if no such - Itr(RunnableScheduledFuture[] array) { + Itr(RunnableScheduledFuture<?>[] array) { this.array = array; } diff --git a/luni/src/main/java/java/util/concurrent/Semaphore.java b/luni/src/main/java/java/util/concurrent/Semaphore.java index 9ee18a8..b4b7edd 100644 --- a/luni/src/main/java/java/util/concurrent/Semaphore.java +++ b/luni/src/main/java/java/util/concurrent/Semaphore.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.Collection; import java.util.concurrent.locks.AbstractQueuedSynchronizer; diff --git a/luni/src/main/java/java/util/concurrent/SynchronousQueue.java b/luni/src/main/java/java/util/concurrent/SynchronousQueue.java index ea6b3d1..69452af 100644 --- a/luni/src/main/java/java/util/concurrent/SynchronousQueue.java +++ b/luni/src/main/java/java/util/concurrent/SynchronousQueue.java @@ -6,6 +6,7 @@ */ package java.util.concurrent; + import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; import java.util.*; @@ -1057,7 +1058,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E> } /** - * Sets the zeroeth element of the specified array to {@code null} + * Sets the zeroth element of the specified array to {@code null} * (if the array has non-zero length) and returns it. * * @param a the array @@ -1150,7 +1151,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E> /** * Reconstitutes this queue from a stream (that is, deserializes it). */ - private void readObject(final java.io.ObjectInputStream s) + private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); if (waitingProducers instanceof FifoWaitQueue) @@ -1172,4 +1173,9 @@ public class SynchronousQueue<E> extends AbstractQueue<E> } } + static { + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; + } } diff --git a/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java b/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java index 5baf75f..b007af2 100644 --- a/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java +++ b/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java @@ -107,9 +107,9 @@ public class ThreadLocalRandom extends Random { * * @param least the least value returned * @param bound the upper bound (exclusive) + * @return the next value * @throws IllegalArgumentException if least greater than or equal * to bound - * @return the next value */ public int nextInt(int least, int bound) { if (least >= bound) @@ -172,7 +172,7 @@ public class ThreadLocalRandom extends Random { * @throws IllegalArgumentException if n is not positive */ public double nextDouble(double n) { - if (n <= 0) + if (!(n > 0)) throw new IllegalArgumentException("n must be positive"); return nextDouble() * n; } diff --git a/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java index 9586293..c484920 100644 --- a/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java +++ b/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java @@ -5,6 +5,7 @@ */ package java.util.concurrent; + import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -582,7 +583,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { this.thread = getThreadFactory().newThread(this); } - /** Delegates main run loop to outer runWorker */ + /** Delegates main run loop to outer runWorker. */ public void run() { runWorker(this); } @@ -1348,6 +1349,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * complete execution. Use {@link #awaitTermination awaitTermination} * to do that. */ + // android-note: Removed @throws SecurityException public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); @@ -1377,6 +1379,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * cancels tasks via {@link Thread#interrupt}, so any task that * fails to respond to interrupts may never terminate. */ + // android-note: Removed @throws SecurityException public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; diff --git a/luni/src/main/java/java/util/concurrent/TimeUnit.java b/luni/src/main/java/java/util/concurrent/TimeUnit.java index eb2c495..8e6a5f7 100644 --- a/luni/src/main/java/java/util/concurrent/TimeUnit.java +++ b/luni/src/main/java/java/util/concurrent/TimeUnit.java @@ -40,6 +40,9 @@ package java.util.concurrent; * @author Doug Lea */ public enum TimeUnit { + /** + * Time unit representing one thousandth of a microsecond + */ NANOSECONDS { public long toNanos(long d) { return d; } public long toMicros(long d) { return d/(C1/C0); } @@ -51,6 +54,10 @@ public enum TimeUnit { public long convert(long d, TimeUnit u) { return u.toNanos(d); } int excessNanos(long d, long m) { return (int)(d - (m*C2)); } }, + + /** + * Time unit representing one thousandth of a millisecond + */ MICROSECONDS { public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } public long toMicros(long d) { return d; } @@ -62,6 +69,10 @@ public enum TimeUnit { public long convert(long d, TimeUnit u) { return u.toMicros(d); } int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } }, + + /** + * Time unit representing one thousandth of a second + */ MILLISECONDS { public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } @@ -73,6 +84,10 @@ public enum TimeUnit { public long convert(long d, TimeUnit u) { return u.toMillis(d); } int excessNanos(long d, long m) { return 0; } }, + + /** + * Time unit representing one second + */ SECONDS { public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } @@ -84,6 +99,11 @@ public enum TimeUnit { public long convert(long d, TimeUnit u) { return u.toSeconds(d); } int excessNanos(long d, long m) { return 0; } }, + + /** + * Time unit representing sixty seconds + * @since 1.6 + */ MINUTES { public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } @@ -95,6 +115,11 @@ public enum TimeUnit { public long convert(long d, TimeUnit u) { return u.toMinutes(d); } int excessNanos(long d, long m) { return 0; } }, + + /** + * Time unit representing sixty minutes + * @since 1.6 + */ HOURS { public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } @@ -106,6 +131,11 @@ public enum TimeUnit { public long convert(long d, TimeUnit u) { return u.toHours(d); } int excessNanos(long d, long m) { return 0; } }, + + /** + * Time unit representing twenty four hours + * @since 1.6 + */ DAYS { public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } @@ -145,14 +175,13 @@ public enum TimeUnit { // etc. are not declared abstract but otherwise act as abstract methods. /** - * Convert the given time duration in the given unit to this - * unit. Conversions from finer to coarser granularities - * truncate, so lose precision. For example converting - * {@code 999} milliseconds to seconds results in - * {@code 0}. Conversions from coarser to finer granularities - * with arguments that would numerically overflow saturate to - * {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE} - * if positive. + * Converts the given time duration in the given unit to this unit. + * Conversions from finer to coarser granularities truncate, so + * lose precision. For example, converting {@code 999} milliseconds + * to seconds results in {@code 0}. Conversions from coarser to + * finer granularities with arguments that would numerically + * overflow saturate to {@code Long.MIN_VALUE} if negative or + * {@code Long.MAX_VALUE} if positive. * * <p>For example, to convert 10 minutes to milliseconds, use: * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)} @@ -168,60 +197,60 @@ public enum TimeUnit { } /** - * Equivalent to {@code NANOSECONDS.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. - * @see #convert */ public long toNanos(long duration) { throw new AbstractMethodError(); } /** - * Equivalent to {@code MICROSECONDS.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. - * @see #convert */ public long toMicros(long duration) { throw new AbstractMethodError(); } /** - * Equivalent to {@code MILLISECONDS.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. - * @see #convert */ public long toMillis(long duration) { throw new AbstractMethodError(); } /** - * Equivalent to {@code SECONDS.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. - * @see #convert */ public long toSeconds(long duration) { throw new AbstractMethodError(); } /** - * Equivalent to {@code MINUTES.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. - * @see #convert * @since 1.6 */ public long toMinutes(long duration) { @@ -229,12 +258,12 @@ public enum TimeUnit { } /** - * Equivalent to {@code HOURS.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. - * @see #convert * @since 1.6 */ public long toHours(long duration) { @@ -242,10 +271,10 @@ public enum TimeUnit { } /** - * Equivalent to {@code DAYS.convert(duration, this)}. + * Equivalent to + * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}. * @param duration the duration * @return the converted duration - * @see #convert * @since 1.6 */ public long toDays(long duration) { diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java index 13b12aa..f51e6af 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java index d67b20a..8a15298 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java index 1f6980d..fd492d1 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index 6067152..4354cb6 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -10,6 +10,9 @@ import dalvik.system.VMStack; // android-added import sun.misc.Unsafe; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.security.PrivilegedActionException; /** * A reflection-based utility that enables atomic updates to @@ -243,7 +246,7 @@ public abstract class AtomicIntegerFieldUpdater<T> { private final Class<T> tclass; private final Class<?> cclass; - AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) { + AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) { final Field field; final Class<?> caller; final int modifiers; diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java index 278c5b5..ab2961a 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java index 2e8c2b7..b7f3d1e 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index 0096a6b..715788c 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -243,7 +243,7 @@ public abstract class AtomicLongFieldUpdater<T> { private final Class<T> tclass; private final Class<?> cclass; - CASUpdater(Class<T> tclass, String fieldName) { + CASUpdater(final Class<T> tclass, final String fieldName) { final Field field; final Class<?> caller; final int modifiers; @@ -337,7 +337,7 @@ public abstract class AtomicLongFieldUpdater<T> { private final Class<T> tclass; private final Class<?> cclass; - LockedUpdater(Class<T> tclass, String fieldName) { + LockedUpdater(final Class<T> tclass, final String fieldName) { Field field = null; Class<?> caller = null; int modifiers = 0; diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java index 1257be0..18d148f 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java @@ -68,7 +68,7 @@ public class AtomicMarkableReference<V> { * Typical usage is {@code boolean[1] holder; ref = v.get(holder); }. * * @param markHolder an array of size of at least one. On return, - * {@code markholder[0]} will hold the value of the mark. + * {@code markHolder[0]} will hold the value of the mark. * @return the current value of the reference */ public V get(boolean[] markHolder) { diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java index 98b402a..7ea6066 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index eb2d73e..4b5e59c 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.atomic; + import dalvik.system.VMStack; // android-added import sun.misc.Unsafe; import java.lang.reflect.Field; @@ -27,7 +28,7 @@ import java.lang.reflect.Modifier; * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater = * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); * - * Node getLeft() { return left; } + * Node getLeft() { return left; } * boolean compareAndSetLeft(Node expect, Node update) { * return leftUpdater.compareAndSet(this, expect, update); * } @@ -63,10 +64,11 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { * or the field is inaccessible to the caller according to Java language * access control */ - public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) { - return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, - vclass, - fieldName); + public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, + Class<W> vclass, + String fieldName) { + return new AtomicReferenceFieldUpdaterImpl<U,W> + (tclass, vclass, fieldName); } /** diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java index b93a6f3..1449856 100644 --- a/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java +++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java @@ -68,7 +68,7 @@ public class AtomicStampedReference<V> { * Typical usage is {@code int[1] holder; ref = v.get(holder); }. * * @param stampHolder an array of size of at least one. On return, - * {@code stampholder[0]} will hold the value of the stamp. + * {@code stampHolder[0]} will hold the value of the stamp. * @return the current value of the reference */ public V get(int[] stampHolder) { diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java index fa01824..66a2f8e 100644 --- a/luni/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java +++ b/luni/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java @@ -35,20 +35,20 @@ public abstract class AbstractOwnableSynchronizer private transient Thread exclusiveOwnerThread; /** - * Sets the thread that currently owns exclusive access. A - * {@code null} argument indicates that no thread owns access. + * Sets the thread that currently owns exclusive access. + * A {@code null} argument indicates that no thread owns access. * This method does not otherwise impose any synchronization or * {@code volatile} field accesses. + * @param thread the owner thread */ - protected final void setExclusiveOwnerThread(Thread t) { - exclusiveOwnerThread = t; + protected final void setExclusiveOwnerThread(Thread thread) { + exclusiveOwnerThread = thread; } /** - * Returns the thread last set by - * {@code setExclusiveOwnerThread}, or {@code null} if never - * set. This method does not otherwise impose any synchronization - * or {@code volatile} field accesses. + * Returns the thread last set by {@code setExclusiveOwnerThread}, + * or {@code null} if never set. This method does not otherwise + * impose any synchronization or {@code volatile} field accesses. * @return the owner thread */ protected final Thread getExclusiveOwnerThread() { diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 37aa9d0..47a02a9 100644 --- a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; import java.util.ArrayList; import java.util.Collection; @@ -227,7 +228,7 @@ public abstract class AbstractQueuedLongSynchronizer Node nextWaiter; /** - * @return true if node is waiting in shared mode + * Returns true if node is waiting in shared mode. */ final boolean isShared() { return nextWaiter == SHARED; @@ -403,9 +404,9 @@ public abstract class AbstractQueuedLongSynchronizer Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; - for (Node t = tail; t != null && t != node; t = t.prev) - if (t.waitStatus <= 0) - s = t; + for (Node p = tail; p != null && p != node; p = p.prev) + if (p.waitStatus <= 0) + s = p; } if (s != null) LockSupport.unpark(s.thread); @@ -1397,13 +1398,13 @@ public abstract class AbstractQueuedLongSynchronizer * @return true if present */ private boolean findNodeFromTail(Node node) { - Node t = tail; + Node p = tail; for (;;) { - if (t == node) + if (p == node) return true; - if (t == null) + if (p == null) return false; - t = t.prev; + p = p.prev; } } @@ -1814,6 +1815,7 @@ public abstract class AbstractQueuedLongSynchronizer throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); + long initialNanos = nanosTimeout; Node node = addConditionWaiter(); long savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; @@ -1835,7 +1837,8 @@ public abstract class AbstractQueuedLongSynchronizer unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); - return deadline - System.nanoTime(); + long remaining = deadline - System.nanoTime(); // avoid overflow + return (remaining < initialNanos) ? remaining : Long.MIN_VALUE; } /** @@ -2027,6 +2030,10 @@ public abstract class AbstractQueuedLongSynchronizer (Node.class.getDeclaredField("next")); } catch (Exception ex) { throw new Error(ex); } + + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; } /** diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index e711da5..bfe88e5 100644 --- a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; import java.util.ArrayList; import java.util.Collection; @@ -128,15 +129,11 @@ import sun.misc.Unsafe; * others that are blocked and queued. However, you can, if desired, * define {@code tryAcquire} and/or {@code tryAcquireShared} to * disable barging by internally invoking one or more of the inspection - * methods. In particular, a strict FIFO lock can define - * {@code tryAcquire} to immediately return {@code false} if {@link - * #getFirstQueuedThread} does not return the current thread. A - * normally preferable non-strict fair version can immediately return - * {@code false} only if {@link #hasQueuedThreads} returns - * {@code true} and {@code getFirstQueuedThread} is not the current - * thread; or equivalently, that {@code getFirstQueuedThread} is both - * non-null and not the current thread. Further variations are - * possible. + * methods, thereby providing a <em>fair</em> FIFO acquisition order. + * In particular, most fair synchronizers can define {@code tryAcquire} + * to return {@code false} if {@code hasQueuedPredecessors} (a method + * specifically designed to be used by fair synchronizers) returns + * {@code true}. Other variations are possible. * * <p>Throughput and scalability are generally highest for the * default barging (also known as <em>greedy</em>, @@ -1461,7 +1458,7 @@ public abstract class AbstractQueuedSynchronizer * due to the queue being empty. * * <p>This method is designed to be used by a fair synchronizer to - * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>. + * avoid <a href="AbstractQueuedSynchronizer.html#barging">barging</a>. * Such a synchronizer's {@link #tryAcquire} method should return * {@code false}, and its {@link #tryAcquireShared} method should * return a negative value, if this method returns {@code true} @@ -2042,6 +2039,7 @@ public abstract class AbstractQueuedSynchronizer throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); + long initialNanos = nanosTimeout; Node node = addConditionWaiter(); int savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; @@ -2063,7 +2061,8 @@ public abstract class AbstractQueuedSynchronizer unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); - return deadline - System.nanoTime(); + long remaining = deadline - System.nanoTime(); // avoid overflow + return (remaining < initialNanos) ? remaining : Long.MIN_VALUE; } /** @@ -2255,6 +2254,10 @@ public abstract class AbstractQueuedSynchronizer (Node.class.getDeclaredField("next")); } catch (Exception ex) { throw new Error(ex); } + + // Reduce the risk of rare disastrous classloading in first call to + // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + Class<?> ensureLoaded = LockSupport.class; } /** diff --git a/luni/src/main/java/java/util/concurrent/locks/Condition.java b/luni/src/main/java/java/util/concurrent/locks/Condition.java index 522e9e2..11a7090 100644 --- a/luni/src/main/java/java/util/concurrent/locks/Condition.java +++ b/luni/src/main/java/java/util/concurrent/locks/Condition.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; import java.util.Date; diff --git a/luni/src/main/java/java/util/concurrent/locks/Lock.java b/luni/src/main/java/java/util/concurrent/locks/Lock.java index 6eeb236..a7ca001 100644 --- a/luni/src/main/java/java/util/concurrent/locks/Lock.java +++ b/luni/src/main/java/java/util/concurrent/locks/Lock.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; /** diff --git a/luni/src/main/java/java/util/concurrent/locks/LockSupport.java b/luni/src/main/java/java/util/concurrent/locks/LockSupport.java index 875b2bf..089d818 100644 --- a/luni/src/main/java/java/util/concurrent/locks/LockSupport.java +++ b/luni/src/main/java/java/util/concurrent/locks/LockSupport.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import sun.misc.Unsafe; /** diff --git a/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java b/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java index bde4741..3654248 100644 --- a/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java +++ b/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; import java.util.Collection; diff --git a/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java b/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java index 2d3c65d..cc7ba4c 100644 --- a/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -5,6 +5,7 @@ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; import java.util.Collection; @@ -236,14 +237,14 @@ public class ReentrantReadWriteLock static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; - /** Returns the number of shared holds represented in count */ + /** Returns the number of shared holds represented in count. */ static int sharedCount(int c) { return c >>> SHARED_SHIFT; } - /** Returns the number of exclusive holds represented in count */ + /** Returns the number of exclusive holds represented in count. */ static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } /** * A counter for per-thread read hold counts. - * Maintained as a ThreadLocal; cached in cachedHoldCounter + * Maintained as a ThreadLocal; cached in cachedHoldCounter. */ static final class HoldCounter { int count = 0; @@ -303,7 +304,7 @@ public class ReentrantReadWriteLock * <p>This allows tracking of read holds for uncontended read * locks to be very cheap. */ - private transient Thread firstReader = null; + private transient Thread firstReader; private transient int firstReaderHoldCount; Sync() { diff --git a/luni/src/main/java/java/util/concurrent/package-info.java b/luni/src/main/java/java/util/concurrent/package-info.java index 51a29e8..afc8ca4 100644 --- a/luni/src/main/java/java/util/concurrent/package-info.java +++ b/luni/src/main/java/java/util/concurrent/package-info.java @@ -4,10 +4,6 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -// BEGIN android-note -// omit links to ForkJoinPool, ForkJoinTask, LinkedTransferQueue, Phaser, TransferQueue -// END android-note - /** * Utility classes commonly useful in concurrent programming. This * package includes a few small standardized extensible frameworks, as @@ -67,11 +63,20 @@ * assists in coordinating the processing of groups of * asynchronous tasks. * + * <p>Class {@link java.util.concurrent.ForkJoinPool} provides an + * Executor primarily designed for processing instances of {@link + * java.util.concurrent.ForkJoinTask} and its subclasses. These + * classes employ a work-stealing scheduler that attains high + * throughput for tasks conforming to restrictions that often hold in + * computation-intensive parallel processing. + * * <h2>Queues</h2> * * The {@link java.util.concurrent.ConcurrentLinkedQueue} class - * supplies an efficient scalable thread-safe non-blocking FIFO - * queue. + * supplies an efficient scalable thread-safe non-blocking FIFO queue. + * The {@link java.util.concurrent.ConcurrentLinkedDeque} class is + * similar, but additionally supports the {@link java.util.Deque} + * interface. * * <p>Five implementations in {@code java.util.concurrent} support * the extended {@link java.util.concurrent.BlockingQueue} @@ -85,6 +90,12 @@ * for producer-consumer, messaging, parallel tasking, and * related concurrent designs. * + * <p>Extended interface {@link java.util.concurrent.TransferQueue}, + * and implementation {@link java.util.concurrent.LinkedTransferQueue} + * introduce a synchronous {@code transfer} method (along with related + * features) in which a producer may optionally block awaiting its + * consumer. + * * <p>The {@link java.util.concurrent.BlockingDeque} interface * extends {@code BlockingQueue} to support both FIFO and LIFO * (stack-based) operations. @@ -111,7 +122,7 @@ * * <h2>Synchronizers</h2> * - * Four classes aid common special-purpose synchronization idioms. + * Five classes aid common special-purpose synchronization idioms. * <ul> * * <li>{@link java.util.concurrent.Semaphore} is a classic concurrency tool. @@ -124,6 +135,10 @@ * multiway synchronization point useful in some styles of parallel * programming. * + * <li>A {@link java.util.concurrent.Phaser} provides + * a more flexible form of barrier that may be used to control phased + * computation among multiple threads. + * * <li>An {@link java.util.concurrent.Exchanger} allows two threads to * exchange objects at a rendezvous point, and is useful in several * pipeline designs. @@ -176,7 +191,7 @@ * * <h2 id="MemoryVisibility">Memory Consistency Properties</h2> * - * <a href="http://java.sun.com/docs/books/jls/third_edition/html/memory.html"> + * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5"> * Chapter 17 of the Java Language Specification</a> defines the * <i>happens-before</i> relation on memory operations such as reads and * writes of shared variables. The results of a write by one thread are @@ -243,7 +258,8 @@ * in each thread <i>happen-before</i> those subsequent to the * corresponding {@code exchange()} in another thread. * - * <li>Actions prior to calling {@code CyclicBarrier.await} + * <li>Actions prior to calling {@code CyclicBarrier.await} and + * {@code Phaser.awaitAdvance} (as well as its variants) * <i>happen-before</i> actions performed by the barrier action, and * actions performed by the barrier action <i>happen-before</i> actions * subsequent to a successful return from the corresponding {@code await} diff --git a/luni/src/main/java/java/util/zip/Zip64.java b/luni/src/main/java/java/util/zip/Zip64.java index 9be3d1c..3060670 100644 --- a/luni/src/main/java/java/util/zip/Zip64.java +++ b/luni/src/main/java/java/util/zip/Zip64.java @@ -19,6 +19,7 @@ package java.util.zip; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -37,8 +38,10 @@ public class Zip64 { /** * The maximum supported entry / archive size for standard (non zip64) entries and archives. + * + * @hide */ - static final long MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE = 0x00000000ffffffffL; + public static final long MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE = 0x00000000ffffffffL; /** * The header ID of the zip64 extended info header. This value is used to identify @@ -46,11 +49,6 @@ public class Zip64 { */ private static final short ZIP64_EXTENDED_INFO_HEADER_ID = 0x0001; - /** - * The minimum size of the zip64 extended info header. This excludes the 2 byte header ID - * and the 2 byte size. - */ - private static final int ZIP64_EXTENDED_INFO_MIN_SIZE = 28; /* * Size (in bytes) of the zip64 end of central directory locator. This will be located @@ -191,35 +189,32 @@ public class Zip64 { if (extendedInfoSize != -1) { extendedInfoStart = buf.position(); try { - if (extendedInfoSize < ZIP64_EXTENDED_INFO_MIN_SIZE) { - throw new ZipException("Invalid zip64 extended info size: " + extendedInfoSize); - } - // The size & compressed size only make sense in the central directory *or* if // we know them beforehand. If we don't know them beforehand, they're stored in // the data descriptor and should be read from there. + // + // Note that the spec says that the local file header "MUST" contain the + // original and compressed size fields. We don't care too much about that. + // The spec claims that the order of fields is fixed anyway. if (fromCentralDirectory || (ze.getMethod() == ZipEntry.STORED)) { - final long zip64Size = buf.getLong(); if (ze.size == MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE) { - ze.size = zip64Size; + ze.size = buf.getLong(); } - final long zip64CompressedSize = buf.getLong(); if (ze.compressedSize == MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE) { - ze.compressedSize = zip64CompressedSize; + ze.compressedSize = buf.getLong(); } } // The local header offset is significant only in the central directory. It makes no // sense within the local header itself. if (fromCentralDirectory) { - final long zip64LocalHeaderRelOffset = buf.getLong(); if (ze.localHeaderRelOffset == MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE) { - ze.localHeaderRelOffset = zip64LocalHeaderRelOffset; + ze.localHeaderRelOffset = buf.getLong(); } } } catch (BufferUnderflowException bue) { - ZipException zipException = new ZipException("Error parsing extendend info "); + ZipException zipException = new ZipException("Error parsing extended info"); zipException.initCause(bue); throw zipException; } @@ -273,8 +268,20 @@ public class Zip64 { */ public static void insertZip64ExtendedInfoToExtras(ZipEntry ze) throws ZipException { final byte[] output; - // We add 4 to ZIP64_EXTENDED_INFO_MIN_SIZE to account for the 2 byte header and length. - final int extendedInfoSize = ZIP64_EXTENDED_INFO_MIN_SIZE + 4; + // We always write the size, uncompressed size and local rel header offset in all our + // Zip64 extended info headers (in both the local file header as well as the central + // directory). We always omit the disk number because we don't support spanned + // archives anyway. + // + // 2 bytes : Zip64 Extended Info Header ID + // 2 bytes : Zip64 Extended Info Field Size. + // 8 bytes : Uncompressed size + // 8 bytes : Compressed size + // 8 bytes : Local header rel offset. + // ---------- + // 28 bytes : total + final int extendedInfoSize = 28; + if (ze.extra == null) { output = new byte[extendedInfoSize]; } else { @@ -291,13 +298,15 @@ public class Zip64 { // This means that people that for ZipOutputStream users, the value ZipEntry.getExtra // after an entry is written will be different from before. This shouldn't be an issue // in practice. - output = new byte[ze.extra.length + ZIP64_EXTENDED_INFO_MIN_SIZE + 4]; - System.arraycopy(ze.extra, 0, output, ZIP64_EXTENDED_INFO_MIN_SIZE + 4, ze.extra.length); + output = new byte[ze.extra.length + extendedInfoSize]; + System.arraycopy(ze.extra, 0, output, extendedInfoSize, ze.extra.length); } ByteBuffer bb = ByteBuffer.wrap(output).order(ByteOrder.LITTLE_ENDIAN); bb.putShort(ZIP64_EXTENDED_INFO_HEADER_ID); - bb.putShort((short) ZIP64_EXTENDED_INFO_MIN_SIZE); + // We subtract four because extendedInfoSize includes the ID and field + // size itself. + bb.putShort((short) (extendedInfoSize - 4)); if (ze.getMethod() == ZipEntry.STORED) { bb.putLong(ze.size); @@ -311,7 +320,6 @@ public class Zip64 { // The offset is only relevant in the central directory entry, but we write it out here // anyway, since we know what it is. bb.putLong(ze.localHeaderRelOffset); - bb.putInt(0); // disk number ze.extra = output; } @@ -354,23 +362,29 @@ public class Zip64 { * we could calculate the correct sizes only after writing out the entry. In this case, * the local file header would not contain real sizes, and they would be present in the * data descriptor and the central directory only. + * + * We choose the simplest strategy of always writing out the size, compressedSize and + * local header offset in all our Zip64 Extended info records. */ public static void refreshZip64ExtendedInfo(ZipEntry ze) { - if (ze.extra == null || ze.extra.length < ZIP64_EXTENDED_INFO_MIN_SIZE) { + if (ze.extra == null) { throw new IllegalStateException("Zip64 entry has no available extras: " + ze); } - ByteBuffer buf = ByteBuffer.wrap(ze.extra).order(ByteOrder.LITTLE_ENDIAN); - if (getZip64ExtendedInfoSize(buf) == -1) { + final int extendedInfoSize = getZip64ExtendedInfoSize(buf); + if (extendedInfoSize == -1) { throw new IllegalStateException( "Zip64 entry extras has no zip64 extended info record: " + ze); } - buf.putLong(ze.size); - buf.putLong(ze.compressedSize); - buf.putLong(ze.localHeaderRelOffset); - buf.putInt(0); // disk number. + try { + buf.putLong(ze.size); + buf.putLong(ze.compressedSize); + buf.putLong(ze.localHeaderRelOffset); + } catch (BufferOverflowException boe) { + throw new IllegalStateException("Invalid extended info extra", boe); + } } public static void writeZip64EocdRecordAndLocator(ByteArrayOutputStream baos, diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java index 26f6863..a06f1b6 100644 --- a/luni/src/main/java/java/util/zip/ZipEntry.java +++ b/luni/src/main/java/java/util/zip/ZipEntry.java @@ -66,7 +66,8 @@ public class ZipEntry implements ZipConstants, Cloneable { */ public static final int STORED = 0; - ZipEntry(String name, String comment, long crc, long compressedSize, + /** @hide - for testing only */ + public ZipEntry(String name, String comment, long crc, long compressedSize, long size, int compressionMethod, int time, int modDate, byte[] extra, long localHeaderRelOffset, long dataOffset) { this.name = name; diff --git a/luni/src/main/java/java/util/zip/ZipOutputStream.java b/luni/src/main/java/java/util/zip/ZipOutputStream.java index 7748cfd..dfd85b6 100644 --- a/luni/src/main/java/java/util/zip/ZipOutputStream.java +++ b/luni/src/main/java/java/util/zip/ZipOutputStream.java @@ -260,7 +260,11 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant writeIntAsUint16(cDir, 0); // Disk Start writeIntAsUint16(cDir, 0); // Internal File Attributes writeLongAsUint32(cDir, 0); // External File Attributes - writeLongAsUint32(cDir, offset); + if (currentEntryNeedsZip64) { + writeLongAsUint32(cDir, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE); + } else { + writeLongAsUint32(cDir, currentEntry.localHeaderRelOffset); + } cDir.write(nameBytes); nameBytes = null; if (currentEntry.extra != null) { diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java index 66d03ad..b27ea88 100644 --- a/luni/src/main/java/javax/crypto/Cipher.java +++ b/luni/src/main/java/javax/crypto/Cipher.java @@ -108,6 +108,50 @@ public class Cipher { }; /** + * Used to keep track of which underlying {@code CipherSpi#engineInit(...)} + * variant to call when testing suitability. + */ + private static enum InitType { + KEY, ALGORITHM_PARAMS, ALGORITHM_PARAM_SPEC, + }; + + /** + * Keeps track of the possible arguments to {@code Cipher#init(...)}. + */ + private static class InitParams { + private final InitType initType; + private final int opmode; + private final Key key; + private final SecureRandom random; + private final AlgorithmParameterSpec spec; + private final AlgorithmParameters params; + + private InitParams(InitType initType, int opmode, Key key, SecureRandom random, + AlgorithmParameterSpec spec, AlgorithmParameters params) { + this.initType = initType; + this.opmode = opmode; + this.key = key; + this.random = random; + this.spec = spec; + this.params = params; + } + } + + /** + * Expresses the various types of transforms that may be used during + * initialization. + */ + private static class Transform { + private final String name; + private final NeedToSet needToSet; + + public Transform(String name, NeedToSet needToSet) { + this.name = name; + this.needToSet = needToSet; + } + } + + /** * The service name. */ private static final String SERVICE = "Cipher"; @@ -297,7 +341,16 @@ public class Cipher { } String[] transformParts = checkTransformation(transformation); - if (tryCombinations(null, provider, transformParts) == null) { + + Engine.SpiAndProvider sap; + try { + sap = tryCombinations(null /* params */, provider, transformation, transformParts); + } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { + // should never happen since we passed in null params + throw new ProviderException(e); + } + + if (sap == null) { if (provider == null) { throw new NoSuchAlgorithmException("No provider found for " + transformation); } else { @@ -308,6 +361,25 @@ public class Cipher { return new Cipher(transformation, transformParts, provider); } + /** + * Checks that the provided algorithm {@code transformation} string is a + * valid input. The algorithm is the only mandatory field and input can be + * of the form: + * <ul> + * <li><code>"[cipher]"</code> + * <li><code>"[cipher]/[mode]/[padding]"</code> + * <li><code>"[cipher]//[padding]"</code> + * <li><code>"[cipher]/[mode]"</code> + * </ul> + * <p> + * Returns the specified transformation split up into three parts + * corresponding to their function: + * <p> + * <code> + * {<algorithm>, <mode>, <padding>} + * </code> + * <p> + */ private static String[] checkTransformation(String transformation) throws NoSuchAlgorithmException { // ignore an extra prefix / characters such as in @@ -339,22 +411,33 @@ public class Cipher { } /** - * Makes sure a CipherSpi that matches this type is selected. + * Makes sure a CipherSpi that matches this type is selected. If + * {@code key != null} then it assumes that a suitable provider exists for + * this instance (used by {@link #init}. If the {@code initParams} is passed + * in, then the {@code CipherSpi} returned will be initialized. + * + * @throws InvalidKeyException if the specified key cannot be used to + * initialize this cipher. + * @throws InvalidAlgorithmParameterException */ - private CipherSpi getSpi(Key key) { + private CipherSpi getSpi(InitParams initParams) throws InvalidKeyException, + InvalidAlgorithmParameterException { if (specifiedSpi != null) { return specifiedSpi; } synchronized (initLock) { - if (spiImpl != null && key == null) { + // This is not only a matter of performance. Many methods like update, doFinal, etc. + // call {@code #getSpi()} (ie, {@code #getSpi(null /* params */)}) and without this + // shortcut they would override an spi that was chosen using the key. + if (spiImpl != null && initParams == null) { return spiImpl; } - final Engine.SpiAndProvider sap = tryCombinations(key, specifiedProvider, - transformParts); + final Engine.SpiAndProvider sap = tryCombinations(initParams, specifiedProvider, + transformation, transformParts); if (sap == null) { - throw new ProviderException("No provider for " + transformation); + throw new ProviderException("No provider found for " + transformation); } spiImpl = (CipherSpi) sap.spi; @@ -366,83 +449,132 @@ public class Cipher { /** * Convenience call when the Key is not available. - * - * @hide */ - public CipherSpi getSpi() { - return getSpi(null); + private CipherSpi getSpi() { + try { + return getSpi(null); + } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { + throw new ProviderException("Exception thrown when params == null", e); + } } /** - * Try all combinations of mode strings: + * Returns the {@code CipherSpi} backing this {@code Cipher} or {@code null} if no + * {@code CipherSpi} is backing this {@code Cipher}. * - * <pre> - * [cipher]/[mode]/[padding] - * [cipher]/[mode] - * [cipher]//[padding] - * [cipher] - * </pre> + * @hide */ - private static Engine.SpiAndProvider tryCombinations(Key key, Provider provider, - String[] transformParts) { - Engine.SpiAndProvider sap = null; + public CipherSpi getCurrentSpi() { + if (specifiedSpi != null) { + return specifiedSpi; + } - if (transformParts[1] != null && transformParts[2] != null) { - sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1] + "/" - + transformParts[2], transformParts, NeedToSet.NONE); - if (sap != null) { - return sap; - } + synchronized (initLock) { + return spiImpl; } + } + /** + * Tries to find the correct {@code Cipher} transform to use. Returns a + * {@link Engine.SpiAndProvider}, throws the first exception that was + * encountered during attempted initialization, or {@code null} if there are + * no providers that support the {@code initParams}. + * <p> + * {@code transformParts} must be in the format returned by + * {@link #checkTransformation(String)}. The combinations of mode strings + * tried are as follows: + * <ul> + * <li><code>[cipher]/[mode]/[padding]</code> + * <li><code>[cipher]/[mode]</code> + * <li><code>[cipher]//[padding]</code> + * <li><code>[cipher]</code> + * </ul> + */ + private static Engine.SpiAndProvider tryCombinations(InitParams initParams, Provider provider, + String transformation, String[] transformParts) throws InvalidKeyException, + InvalidAlgorithmParameterException { + // Enumerate all the transforms we need to try + ArrayList<Transform> transforms = new ArrayList<Transform>(); + if (transformParts[1] != null && transformParts[2] != null) { + transforms.add(new Transform(transformParts[0] + "/" + transformParts[1] + "/" + + transformParts[2], NeedToSet.NONE)); + } if (transformParts[1] != null) { - sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1], - transformParts, NeedToSet.PADDING); - if (sap != null) { - return sap; - } + transforms.add(new Transform(transformParts[0] + "/" + transformParts[1], + NeedToSet.PADDING)); } - if (transformParts[2] != null) { - sap = tryTransform(key, provider, transformParts[0] + "//" + transformParts[2], - transformParts, NeedToSet.MODE); - if (sap != null) { - return sap; + transforms.add(new Transform(transformParts[0] + "//" + transformParts[2], + NeedToSet.MODE)); + } + transforms.add(new Transform(transformParts[0], NeedToSet.BOTH)); + + // Try each of the transforms and keep track of the first exception + // encountered. + Exception cause = null; + for (Transform transform : transforms) { + if (provider != null) { + Provider.Service service = provider.getService(SERVICE, transform.name); + if (service == null) { + continue; + } + return tryTransformWithProvider(initParams, transformParts, transform.needToSet, + service); } - } - - return tryTransform(key, provider, transformParts[0], transformParts, NeedToSet.BOTH); - } - - private static Engine.SpiAndProvider tryTransform(Key key, Provider provider, String transform, - String[] transformParts, NeedToSet type) { - if (provider != null) { - Provider.Service service = provider.getService(SERVICE, transform); - if (service == null) { - return null; + ArrayList<Provider.Service> services = ENGINE.getServices(transform.name); + if (services == null || services.isEmpty()) { + continue; + } + for (Provider.Service service : services) { + if (initParams == null || initParams.key == null + || service.supportsParameter(initParams.key)) { + try { + Engine.SpiAndProvider sap = tryTransformWithProvider(initParams, + transformParts, transform.needToSet, service); + if (sap != null) { + return sap; + } + } catch (Exception e) { + if (cause == null) { + cause = e; + } + } + } } - return tryTransformWithProvider(null, transformParts, type, service); } - ArrayList<Provider.Service> services = ENGINE.getServices(transform); - if (services == null) { + if (cause instanceof InvalidKeyException) { + throw (InvalidKeyException) cause; + } else if (cause instanceof InvalidAlgorithmParameterException) { + throw (InvalidAlgorithmParameterException) cause; + } else if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause != null) { + throw new InvalidKeyException("No provider can be initialized with given key", cause); + } else if (initParams == null || initParams.key == null) { return null; + } else { + // Since the key is not null, a suitable provider exists, + // and it is an InvalidKeyException. + throw new InvalidKeyException("No provider offers " + transformation + " for " + + initParams.key.getAlgorithm() + " key of class " + + initParams.key.getClass().getName() + " and export format " + + initParams.key.getFormat()); } - for (Provider.Service service : services) { - Engine.SpiAndProvider sap = tryTransformWithProvider(key, transformParts, type, service); - if (sap != null) { - return sap; - } - } - return null; } - private static Engine.SpiAndProvider tryTransformWithProvider(Key key, String[] transformParts, - NeedToSet type, Provider.Service service) { + /** + * Tries to initialize the {@code Cipher} from a given {@code service}. If + * initialization is successful, the initialized {@code spi} is returned. If + * the {@code service} cannot be initialized with the specified + * {@code initParams}, then it's expected to throw + * {@code InvalidKeyException} or {@code InvalidAlgorithmParameterException} + * as a hint to the caller that it should continue searching for a + * {@code Service} that will work. + */ + private static Engine.SpiAndProvider tryTransformWithProvider(InitParams initParams, + String[] transformParts, NeedToSet type, Provider.Service service) + throws InvalidKeyException, InvalidAlgorithmParameterException { try { - if (key != null && !service.supportsParameter(key)) { - return null; - } - /* * Check to see if the Cipher even supports the attributes before * trying to instantiate it. @@ -456,9 +588,6 @@ public class Cipher { if (sap.spi == null || sap.provider == null) { return null; } - if (!(sap.spi instanceof CipherSpi)) { - return null; - } CipherSpi spi = (CipherSpi) sap.spi; if (((type == NeedToSet.MODE) || (type == NeedToSet.BOTH)) && (transformParts[1] != null)) { @@ -468,6 +597,24 @@ public class Cipher { && (transformParts[2] != null)) { spi.engineSetPadding(transformParts[2]); } + + if (initParams != null) { + switch (initParams.initType) { + case ALGORITHM_PARAMS: + spi.engineInit(initParams.opmode, initParams.key, initParams.params, + initParams.random); + break; + case ALGORITHM_PARAM_SPEC: + spi.engineInit(initParams.opmode, initParams.key, initParams.spec, + initParams.random); + break; + case KEY: + spi.engineInit(initParams.opmode, initParams.key, initParams.random); + break; + default: + throw new AssertionError("This should never be reached"); + } + } return sap; } catch (NoSuchAlgorithmException ignored) { } catch (NoSuchPaddingException ignored) { @@ -579,6 +726,10 @@ public class Cipher { } + /** + * Checks that the provided {@code mode} is one that is valid for + * {@code Cipher}. + */ private void checkMode(int mode) { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE && mode != UNWRAP_MODE && mode != WRAP_MODE) { @@ -660,7 +811,12 @@ public class Cipher { // FIXME InvalidKeyException // if keysize exceeds the maximum allowable keysize // (jurisdiction policy files) - getSpi(key).engineInit(opmode, key, random); + try { + getSpi(new InitParams(InitType.KEY, opmode, key, random, null, null)); + } catch (InvalidAlgorithmParameterException e) { + // Should never happen since we only specified the key. + throw new ProviderException("Invalid parameters when params == null", e); + } mode = opmode; } @@ -750,7 +906,7 @@ public class Cipher { // FIXME InvalidAlgorithmParameterException // cryptographic strength exceed the legal limits // (jurisdiction policy files) - getSpi(key).engineInit(opmode, key, params, random); + getSpi(new InitParams(InitType.ALGORITHM_PARAM_SPEC, opmode, key, random, params, null)); mode = opmode; } @@ -841,7 +997,7 @@ public class Cipher { // FIXME InvalidAlgorithmParameterException // cryptographic strength exceed the legal limits // (jurisdiction policy files) - getSpi(key).engineInit(opmode, key, params, random); + getSpi(new InitParams(InitType.ALGORITHM_PARAMS, opmode, key, random, null, params)); mode = opmode; } @@ -966,7 +1122,12 @@ public class Cipher { // if keysize exceeds the maximum allowable keysize // (jurisdiction policy files) final Key key = certificate.getPublicKey(); - getSpi(key).engineInit(opmode, key, random); + try { + getSpi(new InitParams(InitType.KEY, opmode, key, random, null, null)); + } catch (InvalidAlgorithmParameterException e) { + // Should never happen since we only specified the key. + throw new ProviderException("Invalid parameters when params == null", e); + } mode = opmode; } diff --git a/luni/src/main/java/javax/crypto/KeyAgreement.java b/luni/src/main/java/javax/crypto/KeyAgreement.java index d27aa2e..22c2f3f 100644 --- a/luni/src/main/java/javax/crypto/KeyAgreement.java +++ b/luni/src/main/java/javax/crypto/KeyAgreement.java @@ -178,7 +178,13 @@ public class KeyAgreement { throw new NullPointerException("algorithm == null"); } - if (tryAlgorithm(null, provider, algorithm) == null) { + boolean providerSupportsAlgorithm; + try { + providerSupportsAlgorithm = tryAlgorithm(null /* key */, provider, algorithm) != null; + } catch (InvalidKeyException e) { + throw new IllegalStateException("InvalidKeyException thrown when key == null", e); + } + if (!providerSupportsAlgorithm) { if (provider == null) { throw new NoSuchAlgorithmException("No provider found for " + algorithm); } else { @@ -189,33 +195,41 @@ public class KeyAgreement { return new KeyAgreement(null, provider, algorithm); } - private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) { + /** + * @throws InvalidKeyException if the specified key cannot be used to + * initialize any provider. + */ + private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) + throws InvalidKeyException { if (provider != null) { Provider.Service service = provider.getService(SERVICE, algorithm); if (service == null) { return null; } - return tryAlgorithmWithProvider(null, service); + return tryAlgorithmWithProvider(service); } ArrayList<Provider.Service> services = ENGINE.getServices(algorithm); - if (services == null) { + if (services == null || services.isEmpty()) { return null; } + boolean keySupported = false; for (Provider.Service service : services) { - Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service); - if (sap != null) { - return sap; + if (key == null || service.supportsParameter(key)) { + keySupported = true; + Engine.SpiAndProvider sap = tryAlgorithmWithProvider(service); + if (sap != null) { + return sap; + } } } + if (!keySupported) { + throw new InvalidKeyException("No provider supports the provided key"); + } return null; } - private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) { + private static Engine.SpiAndProvider tryAlgorithmWithProvider(Provider.Service service) { try { - if (key != null && !service.supportsParameter(key)) { - return null; - } - Engine.SpiAndProvider sap = ENGINE.getInstance(service, null); if (sap.spi == null || sap.provider == null) { return null; @@ -231,8 +245,11 @@ public class KeyAgreement { /** * Makes sure a KeyAgreementSpi that matches this type is selected. + * + * @throws InvalidKeyException if the specified key cannot be used to + * initialize this key agreement. */ - private KeyAgreementSpi getSpi(Key key) { + private KeyAgreementSpi getSpi(Key key) throws InvalidKeyException { synchronized (initLock) { if (spiImpl != null && key == null) { return spiImpl; @@ -252,11 +269,25 @@ public class KeyAgreement { /** * Convenience call when the Key is not available. + */ + private KeyAgreementSpi getSpi() { + try { + return getSpi(null /* key */); + } catch (InvalidKeyException e) { + throw new IllegalStateException("InvalidKeyException thrown when key == null", e); + } + } + + /** + * Returns the {@code KeyAgreementSpi} backing this {@code KeyAgreement} or {@code null} if no + * {@code KeyAgreementSpi} is backing this {@code KeyAgreement}. * * @hide */ - public KeyAgreementSpi getSpi() { - return getSpi(null); + public KeyAgreementSpi getCurrentSpi() { + synchronized (initLock) { + return spiImpl; + } } /** diff --git a/luni/src/main/java/javax/crypto/Mac.java b/luni/src/main/java/javax/crypto/Mac.java index 536f0c5..b8fb947 100644 --- a/luni/src/main/java/javax/crypto/Mac.java +++ b/luni/src/main/java/javax/crypto/Mac.java @@ -182,7 +182,13 @@ public class Mac implements Cloneable { throw new NullPointerException("algorithm == null"); } - if (tryAlgorithm(null, provider, algorithm) == null) { + boolean providerSupportsAlgorithm; + try { + providerSupportsAlgorithm = tryAlgorithm(null /* key */, provider, algorithm) != null; + } catch (InvalidKeyException e) { + throw new IllegalStateException("InvalidKeyException thrown when key == null", e); + } + if (!providerSupportsAlgorithm) { if (provider == null) { throw new NoSuchAlgorithmException("No provider found for " + algorithm); } else { @@ -192,34 +198,41 @@ public class Mac implements Cloneable { } return new Mac(null, provider, algorithm); } - - private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) { + /** + * @throws InvalidKeyException if the specified key cannot be used to + * initialize this mac. + */ + private static Engine.SpiAndProvider tryAlgorithm( + Key key, Provider provider, String algorithm) throws InvalidKeyException { if (provider != null) { Provider.Service service = provider.getService(SERVICE, algorithm); if (service == null) { return null; } - return tryAlgorithmWithProvider(null, service); + return tryAlgorithmWithProvider(service); } ArrayList<Provider.Service> services = ENGINE.getServices(algorithm); - if (services == null) { + if (services == null || services.isEmpty()) { return null; } + boolean keySupported = false; for (Provider.Service service : services) { - Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service); - if (sap != null) { - return sap; + if (key == null || service.supportsParameter(key)) { + keySupported = true; + Engine.SpiAndProvider sap = tryAlgorithmWithProvider(service); + if (sap != null) { + return sap; + } } } + if (!keySupported) { + throw new InvalidKeyException("No provider supports the provided key"); + } return null; } - private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) { + private static Engine.SpiAndProvider tryAlgorithmWithProvider(Provider.Service service) { try { - if (key != null && !service.supportsParameter(key)) { - return null; - } - Engine.SpiAndProvider sap = ENGINE.getInstance(service, null); if (sap.spi == null || sap.provider == null) { return null; @@ -235,8 +248,11 @@ public class Mac implements Cloneable { /** * Makes sure a MacSpi that matches this type is selected. + * + * @throws InvalidKeyException if the specified key cannot be used to + * initialize this mac. */ - private MacSpi getSpi(Key key) { + private MacSpi getSpi(Key key) throws InvalidKeyException { synchronized (initLock) { if (spiImpl != null && provider != null && key == null) { return spiImpl; @@ -266,11 +282,25 @@ public class Mac implements Cloneable { /** * Convenience call when the Key is not available. + */ + private MacSpi getSpi() { + try { + return getSpi(null); + } catch (InvalidKeyException e) { + throw new IllegalStateException("InvalidKeyException thrown when key == null", e); + } + } + + /** + * Returns the {@code MacSpi} backing this {@code Mac} or {@code null} if no {@code MacSpi} is + * backing this {@code Mac}. * * @hide */ - public MacSpi getSpi() { - return getSpi(null); + public MacSpi getCurrentSpi() { + synchronized (initLock) { + return spiImpl; + } } /** diff --git a/luni/src/main/java/javax/net/ssl/SSLEngine.java b/luni/src/main/java/javax/net/ssl/SSLEngine.java index f40f4b0..e8d1a51 100644 --- a/luni/src/main/java/javax/net/ssl/SSLEngine.java +++ b/luni/src/main/java/javax/net/ssl/SSLEngine.java @@ -28,6 +28,14 @@ import java.nio.ByteBuffer; * <p>{@code SSLEngine} instances obtained from default {@link SSLContext} are configured as * follows: * + * <style type="text/css"> + * tr.deprecated { + * background-color: #ccc; + * color: #999; + * font-style: italic; + * } + * </style> + * * <h4>Protocols</h4> * <table> * <thead> @@ -71,155 +79,155 @@ import java.nio.ByteBuffer; * </tr> * </thead> * <tbody> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9-22</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td> - * <td>9-22</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td> - * <td>9-22</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_WITH_DES_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_WITH_RC4_128_MD5</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> * <tr> * <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td> * <td>9+</td> - * <td>9-19</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_WITH_DES_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_WITH_NULL_MD5</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_WITH_NULL_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> * <tr> * <td>SSL_RSA_WITH_RC4_128_MD5</td> * <td>9+</td> - * <td>9-19</td> + * <td>9–19</td> * </tr> * <tr> * <td>SSL_RSA_WITH_RC4_128_SHA</td> * <td>9+</td> * <td>9+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td> - * <td>9-22</td> - * <td>9-22</td> + * <td>9–22</td> + * <td>9–22</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td> - * <td>9-22</td> - * <td>20-22</td> + * <td>9–22</td> + * <td>20–22</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_DES_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> * <tr> * <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td> @@ -251,89 +259,89 @@ import java.nio.ByteBuffer; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_RSA_WITH_DES_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_DSS_WITH_DES_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_RSA_WITH_DES_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_DES_CBC_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * <tr> @@ -366,9 +374,9 @@ import java.nio.ByteBuffer; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * <tr> @@ -376,9 +384,9 @@ import java.nio.ByteBuffer; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * <tr> @@ -411,9 +419,9 @@ import java.nio.ByteBuffer; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * <tr> @@ -421,119 +429,119 @@ import java.nio.ByteBuffer; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_NULL_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_NULL_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * <tr> @@ -556,14 +564,14 @@ import java.nio.ByteBuffer; * <td>21+</td> * <td>21+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_NULL_WITH_NULL_NULL</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td> - * <td>21+</td> + * <td>21–22</td> * <td></td> * </tr> * <tr> @@ -581,15 +589,15 @@ import java.nio.ByteBuffer; * <td>21+</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> * <tr> * <td>TLS_RSA_WITH_AES_128_CBC_SHA</td> @@ -621,24 +629,24 @@ import java.nio.ByteBuffer; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_WITH_DES_CBC_SHA</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_WITH_NULL_MD5</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_WITH_NULL_SHA</td> - * <td>1-8</td> + * <td>1–8</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_WITH_NULL_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * </tbody> diff --git a/luni/src/main/java/javax/net/ssl/SSLSocket.java b/luni/src/main/java/javax/net/ssl/SSLSocket.java index c6906c5..f48870e 100644 --- a/luni/src/main/java/javax/net/ssl/SSLSocket.java +++ b/luni/src/main/java/javax/net/ssl/SSLSocket.java @@ -30,6 +30,14 @@ import java.net.UnknownHostException; * <p>{@code SSLSocket} instances obtained from default {@link SSLSocketFactory}, * {@link SSLServerSocketFactory}, and {@link SSLContext} are configured as follows: * + * <style type="text/css"> + * tr.deprecated { + * background-color: #ccc; + * color: #999; + * font-style: italic; + * } + * </style> + * * <h4>Protocols</h4> * * <p>Client socket: @@ -115,129 +123,129 @@ import java.net.UnknownHostException; * </tr> * </thead> * <tbody> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9-22</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td> - * <td>9-22</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td> - * <td>9-22</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_WITH_DES_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_DH_anon_WITH_RC4_128_MD5</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> * <tr> * <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td> * <td>9+</td> - * <td>9-19</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_WITH_DES_CBC_SHA</td> - * <td>9+</td> - * <td>9-19</td> + * <td>9–22</td> + * <td>9–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_WITH_NULL_MD5</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>SSL_RSA_WITH_NULL_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> * <tr> * <td>SSL_RSA_WITH_RC4_128_MD5</td> * <td>9+</td> - * <td>9-19</td> + * <td>9–19</td> * </tr> * <tr> * <td>SSL_RSA_WITH_RC4_128_SHA</td> * <td>9+</td> * <td>9+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td> - * <td>9-22</td> - * <td>9-22</td> + * <td>9–22</td> + * <td>9–22</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td> - * <td>9-22</td> - * <td>11-22</td> + * <td>9–22</td> + * <td>11–22</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td> - * <td>20-22</td> + * <td>20–22</td> * <td></td> * </tr> * <tr> @@ -270,40 +278,40 @@ import java.net.UnknownHostException; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td> - * <td>9+</td> + * <td>9–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> * <tr> * <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td> @@ -335,9 +343,9 @@ import java.net.UnknownHostException; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> * <tr> @@ -355,10 +363,10 @@ import java.net.UnknownHostException; * <td>21+</td> * <td>21+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> * <tr> * <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td> @@ -390,9 +398,9 @@ import java.net.UnknownHostException; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> * <tr> @@ -400,119 +408,119 @@ import java.net.UnknownHostException; * <td>11+</td> * <td>11+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_NULL_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td> - * <td>11+</td> - * <td>11-19</td> + * <td>11–22</td> + * <td>11–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_NULL_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td> - * <td>11+</td> + * <td>11–22</td> * <td></td> * </tr> * <tr> @@ -525,9 +533,9 @@ import java.net.UnknownHostException; * <td>21+</td> * <td></td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td> - * <td>21+</td> + * <td>21–22</td> * <td></td> * </tr> * <tr> @@ -575,9 +583,9 @@ import java.net.UnknownHostException; * <td>20+</td> * <td>20+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>TLS_RSA_WITH_NULL_SHA256</td> - * <td>20+</td> + * <td>20–22</td> * <td></td> * </tr> * </tbody> @@ -610,43 +618,43 @@ import java.net.UnknownHostException; * <td>AES256-SHA</td> * <td>TLS_RSA_WITH_AES_256_CBC_SHA</td> * <td>1+</td> - * <td>1-8, 11+</td> + * <td>1–8, 11+</td> * </tr> * <tr> * <td>DES-CBC-MD5</td> * <td>SSL_CK_DES_64_CBC_WITH_MD5</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>DES-CBC-SHA</td> * <td>SSL_RSA_WITH_DES_CBC_SHA</td> - * <td>1+</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> * <tr> * <td>DES-CBC3-MD5</td> * <td>SSL_CK_DES_192_EDE3_CBC_WITH_MD5</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> * <tr> * <td>DES-CBC3-SHA</td> * <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td> * <td>1+</td> - * <td>1-19</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>DHE-DSS-AES128-SHA</td> * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td> - * <td>1-22</td> - * <td>1-22</td> + * <td>1–22</td> + * <td>1–22</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>DHE-DSS-AES256-SHA</td> * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td> - * <td>1-22</td> - * <td>1-8, 11-22</td> + * <td>1–22</td> + * <td>1–8, 11–22</td> * </tr> * <tr> * <td>DHE-RSA-AES128-SHA</td> @@ -658,73 +666,73 @@ import java.net.UnknownHostException; * <td>DHE-RSA-AES256-SHA</td> * <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td> * <td>1+</td> - * <td>1-8, 11+</td> + * <td>1–8, 11+</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EDH-DSS-DES-CBC-SHA</td> * <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td> - * <td>1-22</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EDH-DSS-DES-CBC3-SHA</td> * <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td> - * <td>1-22</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EDH-RSA-DES-CBC-SHA</td> * <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td> - * <td>1+</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EDH-RSA-DES-CBC3-SHA</td> * <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td> - * <td>1+</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EXP-DES-CBC-SHA</td> * <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1+</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EXP-EDH-DSS-DES-CBC-SHA</td> * <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1-22</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EXP-EDH-RSA-DES-CBC-SHA</td> * <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td> - * <td>1+</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> * <tr> * <td>EXP-RC2-CBC-MD5</td> * <td>SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> - * <tr> + * <tr class="deprecated"> * <td>EXP-RC4-MD5</td> * <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td> - * <td>1+</td> - * <td>1-19</td> + * <td>1–22</td> + * <td>1–19</td> * </tr> * <tr> * <td>RC2-CBC-MD5</td> * <td>SSL_CK_RC2_128_CBC_WITH_MD5</td> - * <td>1-8</td> - * <td>1-8</td> + * <td>1–8</td> + * <td>1–8</td> * </tr> * <tr> * <td>RC4-MD5</td> * <td>SSL_RSA_WITH_RC4_128_MD5</td> * <td>1+</td> - * <td>1-19</td> + * <td>1–19</td> * </tr> * <tr> * <td>RC4-SHA</td> diff --git a/luni/src/main/java/libcore/icu/DateIntervalFormat.java b/luni/src/main/java/libcore/icu/DateIntervalFormat.java index 509d0a0..7e7ad01 100644 --- a/luni/src/main/java/libcore/icu/DateIntervalFormat.java +++ b/luni/src/main/java/libcore/icu/DateIntervalFormat.java @@ -75,7 +75,7 @@ public final class DateIntervalFormat { if (startMs != endMs && endsAtMidnight && ((flags & DateUtilsBridge.FORMAT_SHOW_TIME) == 0 || DateUtilsBridge.dayDistance(startCalendar, endCalendar) <= 1)) { - endCalendar.roll(Calendar.DAY_OF_MONTH, false); + endCalendar.add(Calendar.DAY_OF_MONTH, -1); } String skeleton = DateUtilsBridge.toSkeleton(startCalendar, endCalendar, flags); diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java index 5c0c8fd..cb77573 100644 --- a/luni/src/main/java/libcore/io/ForwardingOs.java +++ b/luni/src/main/java/libcore/io/ForwardingOs.java @@ -96,6 +96,7 @@ public class ForwardingOs implements Os { public StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return os.getsockoptUcred(fd, level, option); } public int gettid() { return os.gettid(); } public int getuid() { return os.getuid(); } + public int getxattr(String path, String name, byte[] outValue) throws ErrnoException { return os.getxattr(path, name, outValue); } public String if_indextoname(int index) { return os.if_indextoname(index); } public InetAddress inet_pton(int family, String address) { return os.inet_pton(family, address); } public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return os.ioctlInetAddress(fd, cmd, interfaceName); } @@ -131,6 +132,7 @@ public class ForwardingOs implements Os { public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, buffer, flags, srcAddress); } public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); } 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 int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, buffer, flags, inetAddress, port); } @@ -153,6 +155,7 @@ public class ForwardingOs implements Os { public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { os.setsockoptLinger(fd, level, option, value); } public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { os.setsockoptTimeval(fd, level, option, value); } public void setuid(int uid) throws ErrnoException { os.setuid(uid); } + public void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException { os.setxattr(path, name, value, flags); } public void shutdown(FileDescriptor fd, int how) throws ErrnoException { os.shutdown(fd, how); } public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException { return os.socket(domain, type, protocol); } public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { os.socketpair(domain, type, protocol, fd1, fd2); } diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java index 987d331..6d28b95 100644 --- a/luni/src/main/java/libcore/io/Os.java +++ b/luni/src/main/java/libcore/io/Os.java @@ -88,6 +88,7 @@ public interface Os { public StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException; public int gettid(); public int getuid(); + public int getxattr(String path, String name, byte[] outValue) throws ErrnoException; public String if_indextoname(int index); public InetAddress inet_pton(int family, String address); public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException; @@ -124,6 +125,7 @@ public interface Os { public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; public void remove(String path) throws ErrnoException; + public void removexattr(String path, String name) throws ErrnoException; public void rename(String oldPath, String newPath) throws ErrnoException; 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; @@ -146,6 +148,7 @@ public interface Os { public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException; public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException; public void setuid(int uid) throws ErrnoException; + public void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException; public void shutdown(FileDescriptor fd, int how) throws ErrnoException; public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException; public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException; diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java index d680200..151809d 100644 --- a/luni/src/main/java/libcore/io/Posix.java +++ b/luni/src/main/java/libcore/io/Posix.java @@ -90,6 +90,7 @@ public final class Posix implements Os { public native StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException; public native int gettid(); public native int getuid(); + public native int getxattr(String path, String name, byte[] outValue) throws ErrnoException; public native String if_indextoname(int index); public native InetAddress inet_pton(int family, String address); public native InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException; @@ -189,6 +190,7 @@ public final class Posix implements Os { } private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; 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 int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { @@ -230,6 +232,7 @@ public final class Posix implements Os { public native void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException; public native void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException; public native void setuid(int uid) throws ErrnoException; + public native void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException; public native void shutdown(FileDescriptor fd, int how) throws ErrnoException; public native FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException; public native void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException; diff --git a/luni/src/main/java/libcore/util/CharsetUtils.java b/luni/src/main/java/libcore/util/CharsetUtils.java index 2e426c4..5163dba 100644 --- a/luni/src/main/java/libcore/util/CharsetUtils.java +++ b/luni/src/main/java/libcore/util/CharsetUtils.java @@ -23,33 +23,33 @@ package libcore.util; */ public final class CharsetUtils { /** - * Returns a new byte array containing the bytes corresponding to the given characters, - * encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'. + * Returns a new byte array containing the bytes corresponding to the characters in the given + * string, encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'. */ - public static native byte[] toAsciiBytes(char[] chars, int offset, int length); + public static native byte[] toAsciiBytes(String s, int offset, int length); /** - * Returns a new byte array containing the bytes corresponding to the given characters, - * encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'. + * Returns a new byte array containing the bytes corresponding to the characters in the given + * string, encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'. */ - public static native byte[] toIsoLatin1Bytes(char[] chars, int offset, int length); + public static native byte[] toIsoLatin1Bytes(String s, int offset, int length); /** - * Returns a new byte array containing the bytes corresponding to the given characters, - * encoded in UTF-8. All characters are representable in UTF-8. + * Returns a new byte array containing the bytes corresponding to the characters in the given + * string, encoded in UTF-8. All characters are representable in UTF-8. */ - public static native byte[] toUtf8Bytes(char[] chars, int offset, int length); + public static native byte[] toUtf8Bytes(String s, int offset, int length); /** - * Returns a new byte array containing the bytes corresponding to the given characters, - * encoded in UTF-16BE. All characters are representable in UTF-16BE. + * Returns a new byte array containing the bytes corresponding to the characters in the given + * string, encoded in UTF-16BE. All characters are representable in UTF-16BE. */ - public static byte[] toBigEndianUtf16Bytes(char[] chars, int offset, int length) { + public static byte[] toBigEndianUtf16Bytes(String s, int offset, int length) { byte[] result = new byte[length * 2]; int end = offset + length; int resultIndex = 0; for (int i = offset; i < end; ++i) { - char ch = chars[i]; + char ch = s.charAt(i); result[resultIndex++] = (byte) (ch >> 8); result[resultIndex++] = (byte) ch; } diff --git a/luni/src/main/java/libcore/util/HexEncoding.java b/luni/src/main/java/libcore/util/HexEncoding.java index f883a73..4c7e7a2 100644 --- a/luni/src/main/java/libcore/util/HexEncoding.java +++ b/luni/src/main/java/libcore/util/HexEncoding.java @@ -24,7 +24,7 @@ public class HexEncoding { /** Hidden constructor to prevent instantiation. */ private HexEncoding() {} - private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray(); + private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray(); /** * Encodes the provided data as a sequence of hexadecimal characters. diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java index b8e1dad..fd8570c 100644 --- a/luni/src/main/java/libcore/util/ZoneInfoDB.java +++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java @@ -249,6 +249,10 @@ public final class ZoneInfoDB { // The object from the cache is cloned because TimeZone / ZoneInfo are mutable. return zoneInfo == null ? null : (ZoneInfo) zoneInfo.clone(); } + + public boolean hasTimeZone(String id) throws IOException { + return cache.get(id) != null; + } } private ZoneInfoDB() { diff --git a/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java b/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java index 855a8c7..1c794e5 100644 --- a/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java +++ b/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java @@ -152,7 +152,8 @@ public final class Engine { } /** - * Returns a list of all possible matches for a given algorithm. + * Returns a list of all possible matches for a given algorithm. Returns + * {@code null} if no matches were found. */ public ArrayList<Provider.Service> getServices(String algorithm) { int newCacheVersion = Services.getCacheVersion(); @@ -163,8 +164,7 @@ public final class Engine { && newCacheVersion == cacheEntry.cacheVersion) { return cacheEntry.services; } - String name = this.serviceName + "." + algoUC; - ArrayList<Provider.Service> services = Services.getServices(name); + ArrayList<Provider.Service> services = Services.getServices(serviceName, algoUC); this.serviceCache = new ServiceCacheEntry(algoUC, newCacheVersion, services); return services; } diff --git a/luni/src/main/java/org/apache/harmony/security/fortress/Services.java b/luni/src/main/java/org/apache/harmony/security/fortress/Services.java index c81bf6b..234f4a2 100644 --- a/luni/src/main/java/org/apache/harmony/security/fortress/Services.java +++ b/luni/src/main/java/org/apache/harmony/security/fortress/Services.java @@ -29,16 +29,6 @@ import java.util.Locale; * implementations for all "serviceName.algName". */ public class Services { - - /** - * The HashMap that contains information about preferred implementations for - * all serviceName.algName in the registered providers. - * Set the initial size to 600 so we don't grow to 1024 by default because - * initialization adds a few entries more than the growth threshold. - */ - private static final HashMap<String, ArrayList<Provider.Service>> services - = new HashMap<String, ArrayList<Provider.Service>>(600); - /** * Save default SecureRandom service as well. * Avoids similar provider/services iteration in SecureRandom constructor. @@ -71,7 +61,6 @@ public class Services { Provider p = (Provider) providerClass.newInstance(); providers.add(p); providersNames.put(p.getName(), p); - initServiceInfo(p); return true; } catch (ClassNotFoundException ignored) { } catch (IllegalAccessException ignored) { @@ -101,10 +90,11 @@ public class Services { } } Engine.door.renumProviders(); + setNeedRefresh(); } /** - * Returns a copy of the registered providers as an array. + * Returns the actual registered providers. */ public static synchronized ArrayList<Provider> getProviders() { return providers; @@ -144,54 +134,39 @@ public class Services { } /** - * Adds information about provider services into HashMap. - */ - public static synchronized void initServiceInfo(Provider p) { - for (Provider.Service service : p.getServices()) { - String type = service.getType(); - if (cachedSecureRandomService == null && type.equals("SecureRandom")) { - cachedSecureRandomService = service; - } - String key = type + "." + service.getAlgorithm().toUpperCase(Locale.US); - appendServiceLocked(key, service); - for (String alias : Engine.door.getAliases(service)) { - key = type + "." + alias.toUpperCase(Locale.US); - appendServiceLocked(key, service); + * Looks up the requested service by type and algorithm. The service + * {@code type} and should be provided in the same format used when + * registering a service with a provider, for example, "KeyFactory.RSA". + * Callers can cache the returned service information but such caches should + * be validated against the result of Service.getCacheVersion() before use. + * Returns {@code null} if there are no services found. + */ + public static synchronized ArrayList<Provider.Service> getServices(String type, + String algorithm) { + ArrayList<Provider.Service> services = null; + for (Provider p : providers) { + Provider.Service s = p.getService(type, algorithm); + if (s != null) { + if (services == null) { + services = new ArrayList<>(providers.size()); + } + services.add(s); } } + return services; } /** - * Add or append the service to the key. + * Finds the first service offered of {@code type} and returns it. */ - private static void appendServiceLocked(String key, Provider.Service service) { - ArrayList<Provider.Service> serviceList = services.get(key); - if (serviceList == null) { - serviceList = new ArrayList<Provider.Service>(1); - services.put(key, serviceList); + private static synchronized Provider.Service getFirstServiceOfType(String type) { + for (Provider p : providers) { + Provider.Service s = Engine.door.getService(p, type); + if (s != null) { + return s; + } } - serviceList.add(service); - } - - /** - * Returns true if services does not contain any provider information. - */ - public static synchronized boolean isEmpty() { - return services.isEmpty(); - } - - /** - * Looks up the requested service by type and algorithm. The - * service key should be provided in the same format used when - * registering a service with a provider, for example, - * "KeyFactory.RSA". - * - * Callers can cache the returned service information but such - * caches should be validated against the result of - * Service.getCacheVersion() before use. - */ - public static synchronized ArrayList<Provider.Service> getServices(String key) { - return services.get(key); + return null; } /** @@ -219,13 +194,7 @@ public class Services { public static synchronized int getCacheVersion() { if (needRefresh) { cacheVersion++; - synchronized (services) { - services.clear(); - } - cachedSecureRandomService = null; - for (Provider p : providers) { - initServiceInfo(p); - } + cachedSecureRandomService = getFirstServiceOfType("SecureRandom"); needRefresh = false; } return cacheVersion; diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp index 0f2d0ad..acc1e4f 100644 --- a/luni/src/main/native/Register.cpp +++ b/luni/src/main/native/Register.cpp @@ -69,7 +69,6 @@ jint JNI_OnLoad(JavaVM* vm, void*) { REGISTER(register_libcore_io_AsynchronousCloseMonitor); REGISTER(register_libcore_io_Memory); REGISTER(register_libcore_io_Posix); - REGISTER(register_libcore_util_CharsetUtils); REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget); REGISTER(register_org_apache_harmony_xml_ExpatParser); REGISTER(register_sun_misc_Unsafe); diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp index a9031f4..a11ea76 100644 --- a/luni/src/main/native/android_system_OsConstants.cpp +++ b/luni/src/main/native/android_system_OsConstants.cpp @@ -36,6 +36,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/wait.h> +#include <sys/xattr.h> #include <unistd.h> #include <net/if_arp.h> @@ -179,6 +180,7 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "ENOLINK", ENOLINK); initConstant(env, c, "ENOMEM", ENOMEM); initConstant(env, c, "ENOMSG", ENOMSG); + initConstant(env, c, "ENONET", ENONET); initConstant(env, c, "ENOPROTOOPT", ENOPROTOOPT); initConstant(env, c, "ENOSPC", ENOSPC); initConstant(env, c, "ENOSR", ENOSR); @@ -555,6 +557,8 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "WSTOPPED", WSTOPPED); initConstant(env, c, "WUNTRACED", WUNTRACED); initConstant(env, c, "W_OK", W_OK); + initConstant(env, c, "XATTR_CREATE", XATTR_CREATE); + initConstant(env, c, "XATTR_REPLACE", XATTR_REPLACE); initConstant(env, c, "X_OK", X_OK); initConstant(env, c, "_SC_2_CHAR_TERM", _SC_2_CHAR_TERM); initConstant(env, c, "_SC_2_C_BIND", _SC_2_C_BIND); diff --git a/luni/src/main/native/java_lang_RealToString.cpp b/luni/src/main/native/java_lang_RealToString.cpp index 7036fe8..9b412b5 100644 --- a/luni/src/main/native/java_lang_RealToString.cpp +++ b/luni/src/main/native/java_lang_RealToString.cpp @@ -80,7 +80,7 @@ void RealToString_bigIntDigitGenerator(JNIEnv* env, jobject obj, jlong f, jint e *R = f; *mplus = *mminus = 1; simpleShiftLeftHighPrecision (mminus, RM_SIZE, e); - if (f != (2 << (p - 1))) + if (f != (INT64_C(1) << p)) { simpleShiftLeftHighPrecision (R, RM_SIZE, e + 1); *S = 2; @@ -103,7 +103,7 @@ void RealToString_bigIntDigitGenerator(JNIEnv* env, jobject obj, jlong f, jint e } else { - if (isDenormalized || (f != (2 << (p - 1)))) + if (isDenormalized || (f != (INT64_C(1) << p))) { *R = f << 1; *S = 1; diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp index 82547bd..03d0784 100644 --- a/luni/src/main/native/java_util_jar_StrictJarFile.cpp +++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp @@ -60,6 +60,7 @@ static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileN ZipArchiveHandle handle; int32_t error = OpenArchive(fileChars.c_str(), &handle); if (error) { + CloseArchive(handle); throwIoException(env, error); return static_cast<jlong>(-1); } diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp index 0e744b7..d092978 100644 --- a/luni/src/main/native/libcore_icu_ICU.cpp +++ b/luni/src/main/native/libcore_icu_ICU.cpp @@ -890,9 +890,14 @@ void register_libcore_icu_ICU(JNIEnv* env) { } // Use the ICU data files that shipped with the device for everything else. + const char* systemPathPrefix = getenv("ANDROID_ROOT"); + if (systemPathPrefix == NULL) { + ALOGE("ANDROID_ROOT environment variable not set"); \ + abort(); + } std::string systemPath; - systemPath = u_getDataDirectory(); - systemPath += "/"; + systemPath = systemPathPrefix; + systemPath += "/usr/icu/"; systemPath += U_ICUDATA_NAME; systemPath += ".dat"; diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp index f6af483..99b76f9 100644 --- a/luni/src/main/native/libcore_io_Posix.cpp +++ b/luni/src/main/native/libcore_io_Posix.cpp @@ -59,6 +59,7 @@ #include <sys/uio.h> #include <sys/utsname.h> #include <sys/wait.h> +#include <sys/xattr.h> #include <termios.h> #include <unistd.h> #include <memory> @@ -1061,6 +1062,28 @@ static jint Posix_getuid(JNIEnv*, jobject) { return getuid(); } +static jint Posix_getxattr(JNIEnv* env, jobject, jstring javaPath, + jstring javaName, jbyteArray javaOutValue) { + ScopedUtfChars path(env, javaPath); + if (path.c_str() == NULL) { + return -1; + } + ScopedUtfChars name(env, javaName); + if (name.c_str() == NULL) { + return -1; + } + ScopedBytesRW outValue(env, javaOutValue); + if (outValue.get() == NULL) { + return -1; + } + size_t outValueLength = env->GetArrayLength(javaOutValue); + ssize_t size = getxattr(path.c_str(), name.c_str(), outValue.get(), outValueLength); + if (size < 0) { + throwErrnoException(env, "getxattr"); + } + return size; +} + static jstring Posix_if_indextoname(JNIEnv* env, jobject, jint index) { char buf[IF_NAMESIZE]; char* name = if_indextoname(index, buf); @@ -1424,6 +1447,22 @@ static void Posix_remove(JNIEnv* env, jobject, jstring javaPath) { throwIfMinusOne(env, "remove", TEMP_FAILURE_RETRY(remove(path.c_str()))); } +static void Posix_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) { + ScopedUtfChars path(env, javaPath); + if (path.c_str() == NULL) { + return; + } + ScopedUtfChars name(env, javaName); + if (name.c_str() == NULL) { + return; + } + + int res = removexattr(path.c_str(), name.c_str()); + if (res < 0) { + throwErrnoException(env, "removexattr"); + } +} + static void Posix_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) { ScopedUtfChars oldPath(env, javaOldPath); if (oldPath.c_str() == NULL) { @@ -1664,6 +1703,27 @@ static void Posix_setuid(JNIEnv* env, jobject, jint uid) { throwIfMinusOne(env, "setuid", TEMP_FAILURE_RETRY(setuid(uid))); } +static void Posix_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName, + jbyteArray javaValue, jint flags) { + ScopedUtfChars path(env, javaPath); + if (path.c_str() == NULL) { + return; + } + ScopedUtfChars name(env, javaName); + if (name.c_str() == NULL) { + return; + } + ScopedBytesRO value(env, javaValue); + if (value.get() == NULL) { + return; + } + size_t valueLength = env->GetArrayLength(javaValue); + int res = setxattr(path.c_str(), name.c_str(), value.get(), valueLength, flags); + if (res < 0) { + throwErrnoException(env, "setxattr"); + } +} + static void Posix_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) { int fd = jniGetFDFromFileDescriptor(env, javaFd); throwIfMinusOne(env, "shutdown", TEMP_FAILURE_RETRY(shutdown(fd, how))); @@ -1842,6 +1902,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"), NATIVE_METHOD(Posix, gettid, "()I"), NATIVE_METHOD(Posix, getuid, "()I"), + NATIVE_METHOD(Posix, getxattr, "(Ljava/lang/String;Ljava/lang/String;[B)I"), NATIVE_METHOD(Posix, if_indextoname, "(I)Ljava/lang/String;"), NATIVE_METHOD(Posix, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"), NATIVE_METHOD(Posix, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"), @@ -1873,6 +1934,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"), NATIVE_METHOD(Posix, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"), NATIVE_METHOD(Posix, remove, "(Ljava/lang/String;)V"), + NATIVE_METHOD(Posix, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"), NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"), NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"), NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"), @@ -1894,6 +1956,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"), NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"), NATIVE_METHOD(Posix, setuid, "(I)V"), + NATIVE_METHOD(Posix, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"), NATIVE_METHOD(Posix, shutdown, "(Ljava/io/FileDescriptor;I)V"), NATIVE_METHOD(Posix, socket, "(III)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"), diff --git a/luni/src/main/native/libcore_util_CharsetUtils.cpp b/luni/src/main/native/libcore_util_CharsetUtils.cpp deleted file mode 100644 index 57c8172..0000000 --- a/luni/src/main/native/libcore_util_CharsetUtils.cpp +++ /dev/null @@ -1,250 +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. - */ - -#define LOG_TAG "String" - -#include "JNIHelp.h" -#include "JniConstants.h" -#include "ScopedPrimitiveArray.h" -#include "jni.h" -#include "unicode/utf16.h" - -#include <string.h> - -/** - * Approximates java.lang.UnsafeByteSequence so we don't have to pay the cost of calling back into - * Java when converting a char[] to a UTF-8 byte[]. This lets us have UTF-8 conversions slightly - * faster than ICU for large char[]s without paying for the NIO overhead with small char[]s. - * - * We could avoid this by keeping the UTF-8 bytes on the native heap until we're done and only - * creating a byte[] on the Java heap when we know how big it needs to be, but one shouldn't lie - * to the garbage collector (nor hide potentially large allocations from it). - * - * Because a call to append might require an allocation, it might fail. Callers should always - * check the return value of append. - */ -class NativeUnsafeByteSequence { -public: - NativeUnsafeByteSequence(JNIEnv* env) - : mEnv(env), mJavaArray(NULL), mRawArray(NULL), mSize(-1), mOffset(0) - { - } - - ~NativeUnsafeByteSequence() { - // Release our pointer to the raw array, copying changes back to the Java heap. - if (mRawArray != NULL) { - mEnv->ReleaseByteArrayElements(mJavaArray, mRawArray, 0); - } - } - - bool append(jbyte b) { - if (mOffset == mSize && !resize(mSize * 2)) { - return false; - } - mRawArray[mOffset++] = b; - return true; - } - - bool resize(int newSize) { - if (newSize == mSize) { - return true; - } - - // Allocate a new array. - jbyteArray newJavaArray = mEnv->NewByteArray(newSize); - if (newJavaArray == NULL) { - return false; - } - jbyte* newRawArray = mEnv->GetByteArrayElements(newJavaArray, NULL); - if (newRawArray == NULL) { - return false; - } - - // Copy data out of the old array and then let go of it. - // Note that we may be trimming the array. - if (mRawArray != NULL) { - memcpy(newRawArray, mRawArray, mOffset); - mEnv->ReleaseByteArrayElements(mJavaArray, mRawArray, JNI_ABORT); - mEnv->DeleteLocalRef(mJavaArray); - } - - // Point ourselves at the new array. - mJavaArray = newJavaArray; - mRawArray = newRawArray; - mSize = newSize; - return true; - } - - jbyteArray toByteArray() { - // Trim any unused space, if necessary. - bool okay = resize(mOffset); - return okay ? mJavaArray : NULL; - } - -private: - JNIEnv* mEnv; - jbyteArray mJavaArray; - jbyte* mRawArray; - jint mSize; - jint mOffset; - - // Disallow copy and assignment. - NativeUnsafeByteSequence(const NativeUnsafeByteSequence&); - void operator=(const NativeUnsafeByteSequence&); -}; - -static void Charsets_asciiBytesToChars(JNIEnv* env, jclass, jbyteArray javaBytes, jint offset, jint length, jcharArray javaChars) { - ScopedByteArrayRO bytes(env, javaBytes); - if (bytes.get() == NULL) { - return; - } - ScopedCharArrayRW chars(env, javaChars); - if (chars.get() == NULL) { - return; - } - - const jbyte* src = &bytes[offset]; - jchar* dst = &chars[0]; - static const jchar REPLACEMENT_CHAR = 0xfffd; - for (int i = length - 1; i >= 0; --i) { - jchar ch = static_cast<jchar>(*src++ & 0xff); - *dst++ = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR; - } -} - -static void Charsets_isoLatin1BytesToChars(JNIEnv* env, jclass, jbyteArray javaBytes, jint offset, jint length, jcharArray javaChars) { - ScopedByteArrayRO bytes(env, javaBytes); - if (bytes.get() == NULL) { - return; - } - ScopedCharArrayRW chars(env, javaChars); - if (chars.get() == NULL) { - return; - } - - const jbyte* src = &bytes[offset]; - jchar* dst = &chars[0]; - for (int i = length - 1; i >= 0; --i) { - *dst++ = static_cast<jchar>(*src++ & 0xff); - } -} - -/** - * Translates the given characters to US-ASCII or ISO-8859-1 bytes, using the fact that - * Unicode code points between U+0000 and U+007f inclusive are identical to US-ASCII, while - * U+0000 to U+00ff inclusive are identical to ISO-8859-1. - */ -static jbyteArray charsToBytes(JNIEnv* env, jcharArray javaChars, jint offset, jint length, jchar maxValidChar) { - ScopedCharArrayRO chars(env, javaChars); - if (chars.get() == NULL) { - return NULL; - } - - jbyteArray javaBytes = env->NewByteArray(length); - ScopedByteArrayRW bytes(env, javaBytes); - if (bytes.get() == NULL) { - return NULL; - } - - const jchar* src = &chars[offset]; - jbyte* dst = &bytes[0]; - for (int i = length - 1; i >= 0; --i) { - jchar ch = *src++; - if (ch > maxValidChar) { - ch = '?'; - } - *dst++ = static_cast<jbyte>(ch); - } - - return javaBytes; -} - -static jbyteArray Charsets_toAsciiBytes(JNIEnv* env, jclass, jcharArray javaChars, jint offset, jint length) { - return charsToBytes(env, javaChars, offset, length, 0x7f); -} - -static jbyteArray Charsets_toIsoLatin1Bytes(JNIEnv* env, jclass, jcharArray javaChars, jint offset, jint length) { - return charsToBytes(env, javaChars, offset, length, 0xff); -} - -static jbyteArray Charsets_toUtf8Bytes(JNIEnv* env, jclass, jcharArray javaChars, jint offset, jint length) { - ScopedCharArrayRO chars(env, javaChars); - if (chars.get() == NULL) { - return NULL; - } - - NativeUnsafeByteSequence out(env); - if (!out.resize(length)) { - return NULL; - } - - const int end = offset + length; - for (int i = offset; i < end; ++i) { - jint ch = chars[i]; - if (ch < 0x80) { - // One byte. - if (!out.append(ch)) { - return NULL; - } - } else if (ch < 0x800) { - // Two bytes. - if (!out.append((ch >> 6) | 0xc0) || !out.append((ch & 0x3f) | 0x80)) { - return NULL; - } - } else if (U16_IS_SURROGATE(ch)) { - // A supplementary character. - jchar high = (jchar) ch; - jchar low = (i + 1 != end) ? chars[i + 1] : 0; - if (!U16_IS_SURROGATE_LEAD(high) || !U16_IS_SURROGATE_TRAIL(low)) { - if (!out.append('?')) { - return NULL; - } - continue; - } - // Now we know we have a *valid* surrogate pair, we can consume the low surrogate. - ++i; - ch = U16_GET_SUPPLEMENTARY(high, low); - // Four bytes. - jbyte b1 = (ch >> 18) | 0xf0; - jbyte b2 = ((ch >> 12) & 0x3f) | 0x80; - jbyte b3 = ((ch >> 6) & 0x3f) | 0x80; - jbyte b4 = (ch & 0x3f) | 0x80; - if (!out.append(b1) || !out.append(b2) || !out.append(b3) || !out.append(b4)) { - return NULL; - } - } else { - // Three bytes. - jbyte b1 = (ch >> 12) | 0xe0; - jbyte b2 = ((ch >> 6) & 0x3f) | 0x80; - jbyte b3 = (ch & 0x3f) | 0x80; - if (!out.append(b1) || !out.append(b2) || !out.append(b3)) { - return NULL; - } - } - } - return out.toByteArray(); -} - -static JNINativeMethod gMethods[] = { - NATIVE_METHOD(Charsets, asciiBytesToChars, "([BII[C)V"), - NATIVE_METHOD(Charsets, isoLatin1BytesToChars, "([BII[C)V"), - NATIVE_METHOD(Charsets, toAsciiBytes, "([CII)[B"), - NATIVE_METHOD(Charsets, toIsoLatin1Bytes, "([CII)[B"), - NATIVE_METHOD(Charsets, toUtf8Bytes, "([CII)[B"), -}; -void register_libcore_util_CharsetUtils(JNIEnv* env) { - jniRegisterNativeMethods(env, "libcore/util/CharsetUtils", gMethods, NELEM(gMethods)); -} diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk index a90c683..73ed7cb 100644 --- a/luni/src/main/native/sub.mk +++ b/luni/src/main/native/sub.mk @@ -49,7 +49,6 @@ LOCAL_SRC_FILES := \ libcore_io_AsynchronousCloseMonitor.cpp \ libcore_io_Memory.cpp \ libcore_io_Posix.cpp \ - libcore_util_CharsetUtils.cpp \ org_apache_harmony_xml_ExpatParser.cpp \ readlink.cpp \ sun_misc_Unsafe.cpp \ diff --git a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java index 8627225..48a175c 100644 --- a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java +++ b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java @@ -401,11 +401,6 @@ public class CertBlacklistTest extends TestCase { assertEquals(bl, getCurrentSerialBlacklist()); } - public void testTurkTrustIntermediate1SerialBlacklist() throws Exception { - CertBlacklist bl = new CertBlacklist(); - assertEquals(bl.isSerialNumberBlackListed(createSerialNumber(TURKTRUST_1)), true); - } - public void testTurkTrustIntermediate1PubkeyBlacklist() throws Exception { // build the public key PublicKey pk = createPublicKey(TURKTRUST_1); @@ -417,11 +412,6 @@ public class CertBlacklistTest extends TestCase { assertEquals(bl.isPublicKeyBlackListed(pk), true); } - public void testTurkTrustIntermediate2SerialBlacklist() throws Exception { - CertBlacklist bl = new CertBlacklist(); - assertEquals(bl.isSerialNumberBlackListed(createSerialNumber(TURKTRUST_2)), true); - } - public void testTurkTrustIntermediate2PubkeyBlacklist() throws Exception { // build the public key PublicKey pk = createPublicKey(TURKTRUST_2); @@ -431,11 +421,6 @@ public class CertBlacklistTest extends TestCase { assertEquals(bl.isPublicKeyBlackListed(pk), true); } - public void testANSSISerialBlacklist() throws Exception { - CertBlacklist bl = new CertBlacklist(); - assertEquals(bl.isSerialNumberBlackListed(createSerialNumber(ANSSI)), true); - } - public void testANSSIIntermediatePubkeyBlacklist() throws Exception { // build the public key PublicKey pk = createPublicKey(ANSSI); diff --git a/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java index 9e6d8d7..31e8fc7 100644 --- a/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java +++ b/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java @@ -17,9 +17,12 @@ package libcore.dalvik.system; import dalvik.system.PathClassLoader; +import java.lang.reflect.Method; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import libcore.io.Streams; import junit.framework.TestCase; public final class PathClassLoaderTest extends TestCase { @@ -52,6 +55,26 @@ public final class PathClassLoaderTest extends TestCase { return result; } + public void testAppUseOfPathClassLoader() throws Exception { + // Extract loading-test.jar from the resource. + ClassLoader pcl = PathClassLoaderTest.class.getClassLoader(); + File jar = File.createTempFile("loading-test", ".jar"); + try (InputStream in = pcl.getResourceAsStream("dalvik/system/loading-test.jar"); + FileOutputStream out = new FileOutputStream(jar)) { + Streams.copy(in, out); + } + + // Execute code from the jar file using a PathClassLoader. + PathClassLoader cl = new PathClassLoader(jar.getPath(), pcl); + Class c = cl.loadClass("test.Test1"); + Method m = c.getMethod("test", (Class[]) null); + String result = (String) m.invoke(null, (Object[]) null); + assertSame("blort", result); + + // Clean up the extracted jar file. + assertTrue(jar.delete()); + } + @Override protected void setUp() throws Exception { super.setUp(); } diff --git a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java index 7adad72..4c22371 100644 --- a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java +++ b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java @@ -423,4 +423,13 @@ public class DateIntervalFormatTest extends junit.framework.TestCase { assertEquals("11 AM – 1 PM", formatDateRange(l, utc, 11*HOUR, 13*HOUR, flags)); assertEquals("2 – 3 PM", formatDateRange(l, utc, 14*HOUR, 15*HOUR, flags)); } + + // http://b/20708022 + public void testEndOfDayOnLastDayOfMonth() throws Exception { + final ULocale locale = new ULocale("en"); + final TimeZone timeZone = TimeZone.getTimeZone("UTC"); + + assertEquals("11:00 PM – 12:00 AM", formatDateRange(locale, timeZone, + 1430434800000L, 1430438400000L, FORMAT_SHOW_TIME)); + } } diff --git a/luni/src/test/java/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/icu/ICUTest.java index 99679a7..5eab070 100644 --- a/luni/src/test/java/libcore/icu/ICUTest.java +++ b/luni/src/test/java/libcore/icu/ICUTest.java @@ -260,5 +260,8 @@ public class ICUTest extends junit.framework.TestCase { String icu4cTzVersion = ICU.getTZDataVersion(); String zoneInfoTzVersion = ZoneInfoDB.getInstance().getVersion(); assertEquals(icu4cTzVersion, zoneInfoTzVersion); + + String icu4jTzVersion = android.icu.util.TimeZone.getTZDataVersion(); + assertEquals(icu4jTzVersion, zoneInfoTzVersion); } } diff --git a/luni/src/test/java/libcore/io/OsTest.java b/luni/src/test/java/libcore/io/OsTest.java index e648e8a..9b38ee9 100644 --- a/luni/src/test/java/libcore/io/OsTest.java +++ b/luni/src/test/java/libcore/io/OsTest.java @@ -18,6 +18,7 @@ package libcore.io; import android.system.ErrnoException; import android.system.NetlinkSocketAddress; +import android.system.OsConstants; import android.system.PacketSocketAddress; import android.system.StructTimeval; import android.system.StructUcred; @@ -419,4 +420,59 @@ public class OsTest extends TestCase { checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, true); checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false); } + + private static void assertPartial(byte[] expected, byte[] actual) { + for (int i = 0; i < expected.length; i++) { + if (expected[i] != actual[i]) { + fail("Expected " + Arrays.toString(expected) + " but found " + + Arrays.toString(actual)); + } + } + } + + public void test_xattr() throws Exception { + final String NAME_TEST = "user.meow"; + + final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8); + final byte[] VALUE_PIE = "pie".getBytes(StandardCharsets.UTF_8); + + File file = File.createTempFile("xattr", "test"); + String path = file.getAbsolutePath(); + + byte[] tmp = new byte[1024]; + try { + try { + Libcore.os.getxattr(path, NAME_TEST, tmp); + fail("Expected ENODATA"); + } catch (ErrnoException e) { + assertEquals(OsConstants.ENODATA, e.errno); + } + + Libcore.os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE); + assertEquals(VALUE_CAKE.length, Libcore.os.getxattr(path, NAME_TEST, tmp)); + assertPartial(VALUE_CAKE, tmp); + + try { + Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_CREATE); + fail("Expected EEXIST"); + } catch (ErrnoException e) { + assertEquals(OsConstants.EEXIST, e.errno); + } + + Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_REPLACE); + assertEquals(VALUE_PIE.length, Libcore.os.getxattr(path, NAME_TEST, tmp)); + assertPartial(VALUE_PIE, tmp); + + Libcore.os.removexattr(path, NAME_TEST); + try { + Libcore.os.getxattr(path, NAME_TEST, tmp); + fail("Expected ENODATA"); + } catch (ErrnoException e) { + assertEquals(OsConstants.ENODATA, e.errno); + } + + } finally { + file.delete(); + } + } } diff --git a/luni/src/test/java/libcore/java/lang/OldSystemTest.java b/luni/src/test/java/libcore/java/lang/OldSystemTest.java index dee5bdd..93b06c8 100644 --- a/luni/src/test/java/libcore/java/lang/OldSystemTest.java +++ b/luni/src/test/java/libcore/java/lang/OldSystemTest.java @@ -260,12 +260,14 @@ public class OldSystemTest extends junit.framework.TestCase { while(rt.freeMemory() < beforeTest * 2/3) { vec.add(new StringBuffer(1000)); } - long beforeGC = rt.freeMemory(); + long beforeGC = rt.totalMemory() - rt.freeMemory(); + vec = null; System.gc(); - long afterGC = rt.freeMemory(); + System.runFinalization(); + long afterGC = rt.totalMemory() - rt.freeMemory(); assertTrue("memory was not released after calling System.gc()." + "before gc: " + beforeGC + "; after gc: " + afterGC, - beforeGC < afterGC); + beforeGC > afterGC); } public void test_getenv() { diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java index bf162e5..bd52e06 100644 --- a/luni/src/test/java/libcore/java/lang/StringTest.java +++ b/luni/src/test/java/libcore/java/lang/StringTest.java @@ -173,47 +173,6 @@ public class StringTest extends TestCase { } /** - * Tests a widely assumed performance characteristic of String.substring(): - * that it reuses the original's backing array. Although behavior should be - * correct even if this test fails, many applications may suffer - * significant performance degradation. - */ - public void testSubstringSharesBackingArray() throws IllegalAccessException { - String abcdefghij = "ABCDEFGHIJ"; - String cdefg = abcdefghij.substring(2, 7); - assertSame(getBackingArray(abcdefghij), getBackingArray(cdefg)); - } - - /** - * Tests a widely assumed performance characteristic of string's copy - * constructor: that it ensures the backing array is the same length as the - * string. Although behavior should be correct even if this test fails, - * many applications may suffer significant performance degradation. - */ - public void testStringCopiesAvoidHeapRetention() throws IllegalAccessException { - String abcdefghij = "ABCDEFGHIJ"; - assertSame(getBackingArray(abcdefghij), getBackingArray(new String(abcdefghij))); - - String cdefg = abcdefghij.substring(2, 7); - assertSame(getBackingArray(abcdefghij), getBackingArray(cdefg)); - assertEquals(5, getBackingArray(new String(cdefg)).length); - } - - /** - * Uses reflection to return the char[] backing the given string. This - * returns the actual backing array; which must not be modified. - */ - private char[] getBackingArray(String string) throws IllegalAccessException { - for (Field f : String.class.getDeclaredFields()) { - if (!Modifier.isStatic(f.getModifiers()) && f.getType() == char[].class) { - f.setAccessible(true); - return (char[]) f.get(string); - } - } - throw new UnsupportedOperationException("No chars[] field on String!"); - } - - /** * Test that strings interned manually and then later loaded as literals * maintain reference equality. http://b/3098960 */ diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java index 7e08b5f..10bb621 100644 --- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java +++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import javax.crypto.interfaces.DHPrivateKey; @@ -55,13 +56,32 @@ import junit.framework.TestCase; public class KeyPairGeneratorTest extends TestCase { - public void test_providerCount() { + private List<Provider> providers = new ArrayList<Provider>(); + + @Override + public void setUp() { Provider[] providers = Security.getProviders(); + for (Provider p : providers) { + // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for + // signature verification. It's OKish not to test here because it's tested by + // cts/tests/tests/keystore. + if (!p.getName().startsWith("AndroidKeyStore")) { + this.providers.add(p); + } + } + } + + @Override + public void tearDown() { + providers.clear(); + } + + public void test_providerCount() { // We expect there to be at least one provider. - assertTrue(providers.length > 0); + assertTrue(providers.size() > 0); // If this fails remember to add _provider methods below. This test is sharded because it // takes a long time to execute. - assertTrue(providers.length < 10); + assertTrue(providers.size() < 10); } public void test_getInstance_provider0() throws Exception { @@ -105,14 +125,14 @@ public class KeyPairGeneratorTest extends TestCase { } private void test_getInstance(int providerIndex) throws Exception { - Provider[] providers = Security.getProviders(); - if (providerIndex >= providers.length) { + if (providerIndex >= providers.size()) { // Providers can be added by vendors and other tests. We do not // specify a fixed number and silenty pass if the provider at the // specified index does not exist. return; } - Provider provider = providers[providerIndex]; + + Provider provider = providers.get(providerIndex); Set<Provider.Service> services = provider.getServices(); for (Provider.Service service : services) { String type = service.getType(); @@ -120,15 +140,6 @@ public class KeyPairGeneratorTest extends TestCase { continue; } String algorithm = service.getAlgorithm(); - - // Do not test AndroidKeyStore's KeyPairGenerator. It cannot be initialized without - // providing AndroidKeyStore-specific algorithm parameters. - // It's OKish not to test AndroidKeyStore's KeyPairGenerator here because it's tested - // by cts/tests/test/keystore. - if ("AndroidKeyStore".equals(provider.getName())) { - continue; - } - AlgorithmParameterSpec params = null; if ("DH".equals(algorithm)) { @@ -198,7 +209,6 @@ public class KeyPairGeneratorTest extends TestCase { putKeySize("DiffieHellman", 512); putKeySize("DiffieHellman", 512+64); putKeySize("DiffieHellman", 1024); - putKeySize("EC", 192); putKeySize("EC", 224); putKeySize("EC", 256); putKeySize("EC", 384); @@ -207,10 +217,10 @@ public class KeyPairGeneratorTest extends TestCase { /** Elliptic Curve Crypto named curves that should be supported. */ private static final String[] EC_NAMED_CURVES = { - // NIST P-192 aka SECG secp192r1 aka ANSI X9.62 prime192v1 - "secp192r1", "prime192v1", // NIST P-256 aka SECG secp256r1 aka ANSI X9.62 prime256v1 "secp256r1", "prime256v1", + // NIST P-521 aka SECG secp521r1 + "secp521r1", }; private void test_KeyPairGenerator(KeyPairGenerator kpg) throws Exception { @@ -267,7 +277,7 @@ public class KeyPairGeneratorTest extends TestCase { } private void test_Key(KeyPairGenerator kpg, Key k) throws Exception { - String expectedAlgorithm = kpg.getAlgorithm().toUpperCase(); + String expectedAlgorithm = kpg.getAlgorithm().toUpperCase(Locale.ROOT); if (StandardNames.IS_RI && expectedAlgorithm.equals("DIFFIEHELLMAN")) { expectedAlgorithm = "DH"; } @@ -306,8 +316,6 @@ public class KeyPairGeneratorTest extends TestCase { byte[] encoded = k.getEncoded(); String keyAlgo = k.getAlgorithm(); - - Provider[] providers = Security.getProviders(); for (Provider p : providers) { Set<Provider.Service> services = p.getServices(); for (Provider.Service service : services) { diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java index 0be558e..d3ccae1 100644 --- a/luni/src/test/java/libcore/java/security/ProviderTest.java +++ b/luni/src/test/java/libcore/java/security/ProviderTest.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.crypto.Cipher; @@ -178,8 +179,8 @@ public class ProviderTest extends TestCase { provider.get("Provider.id className")); // build map of all known aliases and implementations - Map<String,String> aliases = new HashMap<String,String>(); - Map<String,String> implementations = new HashMap<String,String>(); + Map<String,String> aliases = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + Map<String,String> implementations = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); for (Entry<Object,Object> entry : provider.entrySet()) { Object k = entry.getKey(); Object v = entry.getValue(); @@ -218,7 +219,8 @@ public class ProviderTest extends TestCase { } catch (ClassNotFoundException e) { // Sun forgot their own class if (!className.equals("sun.security.pkcs11.P11MAC")) { - fail("Could not find class " + className + " for " + typeAndAlgorithm); + fail("Could not find class " + className + " for " + typeAndAlgorithm + + " [provider=" + provider.getName() + "]"); } } } @@ -227,8 +229,9 @@ public class ProviderTest extends TestCase { for (Entry<String,String> entry : aliases.entrySet()) { String alias = entry.getKey(); String actual = entry.getValue(); - assertTrue("Could not find implementation " + actual + " for alias " + alias, - implementations.containsKey(actual)); + assertTrue("Could not find implementation " + actual + " for alias " + alias + + " [provider=" + provider.getName() + "]", + implementations.containsKey(actual)); } } } @@ -547,6 +550,15 @@ public class ProviderTest extends TestCase { } } + public void testProvider_removeProvider_Success() throws Exception { + MockProvider provider = new MockProvider("MockProvider"); + assertNull(Security.getProvider(provider.getName())); + Security.addProvider(provider); + assertNotNull(Security.getProvider(provider.getName())); + Security.removeProvider(provider.getName()); + assertNull(Security.getProvider(provider.getName())); + } + public static class MyCertStoreSpi extends CertStoreSpi { public MyCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); diff --git a/luni/src/test/java/libcore/java/security/SecureRandomTest.java b/luni/src/test/java/libcore/java/security/SecureRandomTest.java index f9edbaa..e296775 100644 --- a/luni/src/test/java/libcore/java/security/SecureRandomTest.java +++ b/luni/src/test/java/libcore/java/security/SecureRandomTest.java @@ -102,6 +102,7 @@ public class SecureRandomTest extends TestCase { public void testNewConstructors_Success() throws Exception { SecureRandom sr1 = new SecureRandom(); + assertNotNull(sr1.getProvider()); assertEquals(EXPECTED_PROVIDER, sr1.getProvider().getClass().getName()); test_SecureRandom(sr1); diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java index e546f4f..9aa75bd 100644 --- a/luni/src/test/java/libcore/java/security/SignatureTest.java +++ b/luni/src/test/java/libcore/java/security/SignatureTest.java @@ -31,6 +31,11 @@ import java.security.Signature; import java.security.SignatureException; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; +import java.security.spec.ECFieldFp; +import java.security.spec.ECParameterSpec; +import java.security.spec.ECPoint; +import java.security.spec.ECPublicKeySpec; +import java.security.spec.EllipticCurve; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPrivateKeySpec; @@ -89,6 +94,31 @@ public class SignatureTest extends TestCase { } } + /** + * Several exceptions can be thrown by init. Check that in this case we throw the right one, + * as the error could fall under the umbrella of other exceptions. + * http://b/18987633 + */ + public void testSignature_init_DoesNotSupportKeyClass_throwsInvalidKeyException() + throws Exception { + Provider mockProvider = new MockProvider("MockProvider") { + public void setup() { + put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName()); + put("Signature.FOO SupportedKeyClasses", "None"); + } + }; + + Security.addProvider(mockProvider); + try { + Signature s = Signature.getInstance("FOO"); + s.initSign(new MockPrivateKey()); + fail("Expected InvalidKeyException"); + } catch (InvalidKeyException expected) { + } finally { + Security.removeProvider(mockProvider.getName()); + } + } + public void testSignature_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success() throws Exception { Provider mockProvider = new MockProvider("MockProvider") { @@ -256,6 +286,12 @@ public class SignatureTest extends TestCase { public void test_getInstance() throws Exception { Provider[] providers = Security.getProviders(); for (Provider provider : providers) { + // Do not test AndroidKeyStore's Signature. It needs an AndroidKeyStore-specific key. + // It's OKish not to test AndroidKeyStore's Signature here because it's tested + // by cts/tests/test/keystore. + if (provider.getName().startsWith("AndroidKeyStore")) { + continue; + } Set<Provider.Service> services = provider.getServices(); for (Provider.Service service : services) { String type = service.getType(); @@ -388,9 +424,14 @@ public class SignatureTest extends TestCase { return data; } - // http://code.google.com/p/android/issues/detail?id=18566 - // http://b/5038554 - public void test18566() throws Exception { + /** + * This should actually fail because the ASN.1 encoding is incorrect. It is + * missing the NULL in the AlgorithmIdentifier field. + * <p> + * http://code.google.com/p/android/issues/detail?id=18566 <br/> + * http://b/5038554 + */ + public void test18566_AlgorithmOid_MissingNull_Failure() throws Exception { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey pk = keyFactory.generatePublic(keySpec); @@ -398,7 +439,7 @@ public class SignatureTest extends TestCase { Signature sig = Signature.getInstance("SHA256withRSA"); sig.initVerify(pk); sig.update(CONTENT); - assertTrue(sig.verify(SIGNATURE)); + assertFalse(sig.verify(SIGNATURE)); } /* @@ -1664,4 +1705,43 @@ public class SignatureTest extends TestCase { es.shutdown(); assertTrue("Test should not timeout", es.awaitTermination(1, TimeUnit.MINUTES)); } + + public void testArbitraryCurve() throws Exception { + // These are the parameters for the BitCoin curve (secp256k1). See + // https://en.bitcoin.it/wiki/Secp256k1. + final BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16); + final BigInteger a = BigInteger.valueOf(0); + final BigInteger b = BigInteger.valueOf(7); + final BigInteger x = new BigInteger("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16); + final BigInteger y = new BigInteger("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16); + final BigInteger order = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16); + final int cofactor = 1; + + final ECParameterSpec spec = new ECParameterSpec(new EllipticCurve(new ECFieldFp(p), a, b), new ECPoint(x, y), order, cofactor); + final KeyFactory factory = KeyFactory.getInstance("EC"); + + // $ openssl ecparam -name secp256k1 -genkey > key.pem + // $ openssl ec -text -noout < key.pem + final BigInteger Px = new BigInteger("2d45572747a625db5fd23b30f97044a682f2d42d31959295043c1fa0034c8ed3", 16); + final BigInteger Py = new BigInteger("4d330f52e4bba00145a331041c8bbcf300c4fbfdf3d63d8de7608155b2793808", 16); + + final ECPublicKeySpec keySpec = new ECPublicKeySpec(new ECPoint(Px, Py), spec); + final PublicKey pub = factory.generatePublic(keySpec); + + // $ echo -n "Satoshi Nakamoto" > signed + // $ openssl dgst -ecdsa-with-SHA1 -sign key.pem -out sig signed + final byte[] SIGNATURE = hexToBytes("304402205b41ece6dcc1c5bfcfdae74658d99c08c5e783f3926c11ecc1a8bea5d95cdf27022061a7d5fc687287e2e02dd7c6723e2e27fe0555f789590a37e96b1bb0355b4df0"); + + Signature ecdsaVerify = Signature.getInstance("SHA1withECDSA"); + ecdsaVerify.initVerify(pub); + ecdsaVerify.update("Satoshi Nakamoto".getBytes("UTF-8")); + boolean result = ecdsaVerify.verify(SIGNATURE); + assertEquals(true, result); + + ecdsaVerify = Signature.getInstance("SHA1withECDSA"); + ecdsaVerify.initVerify(pub); + ecdsaVerify.update("Not Satoshi Nakamoto".getBytes("UTF-8")); + result = ecdsaVerify.verify(SIGNATURE); + assertEquals(false, result); + } } diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java index c35f8e6..14c22ef 100644 --- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java +++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java @@ -339,6 +339,13 @@ public class X509CertificateTest extends TestCase { Provider[] providers = Security.getProviders("Signature." + c.getSigAlgName()); for (Provider p : providers) { + // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for + // signature verification. It's OKish not to test here because it's tested by + // cts/tests/tests/keystore. + if (p.getName().startsWith("AndroidKeyStore")) { + continue; + } + c.verify(signer, p.getName()); try { diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java index 3e0aeba..b1d37f3 100644 --- a/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java +++ b/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java @@ -86,4 +86,34 @@ public class DecimalFormatSymbolsTest extends junit.framework.TestCase { assertEquals("$", dfs.getCurrencySymbol()); assertEquals(null, dfs.getInternationalCurrencySymbol()); } + + // https://code.google.com/p/android/issues/detail?id=170718 + public void testSerializationOfMultiCharNegativeAndPercentage() throws Exception { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.forLanguageTag("ar-AR")); + assertTrue(dfs.getMinusSignString().length() > 1); + assertTrue(dfs.getPercentString().length() > 1); + + // Serialize... + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new ObjectOutputStream(out).writeObject(dfs); + byte[] bytes = out.toByteArray(); + + // Deserialize... + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); + DecimalFormatSymbols deserializedDfs = (DecimalFormatSymbols) in.readObject(); + assertEquals(-1, in.read()); + + assertEquals(dfs.getMinusSignString(), deserializedDfs.getMinusSignString()); + assertEquals(dfs.getPercentString(), deserializedDfs.getPercentString()); + } + + // http://b/18785260 + public void testMultiCharMinusSignAndPercentage() { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.forLanguageTag("ar-AR")); + assertTrue(dfs.getMinusSignString().length() > 1); + assertTrue(dfs.getPercentString().length() > 1); + + assertEquals('%', dfs.getPercent()); + assertEquals('-', dfs.getMinusSign()); + } } diff --git a/luni/src/test/java/libcore/java/util/DateTest.java b/luni/src/test/java/libcore/java/util/DateTest.java index 3ed0952..076c6e2 100644 --- a/luni/src/test/java/libcore/java/util/DateTest.java +++ b/luni/src/test/java/libcore/java/util/DateTest.java @@ -31,12 +31,13 @@ public class DateTest extends TestCase { assertEquals("Wed Dec 31 18:00:00 CST 1969", new Date(0).toString()); } + // https://code.google.com/p/android/issues/detail?id=81924 public void test_toString_nonUs() { // The string for the timezone depends on what the default locale is. Not every locale - // has a short-name for America/Chicago -> PST. - Locale.setDefault(Locale.UK); + // has a short-name for America/Chicago -> CST. + Locale.setDefault(Locale.CHINA); TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")); - assertEquals("Wed Dec 31 18:00:00 GMT-06:00 1969", new Date(0).toString()); + assertEquals("Wed Dec 31 18:00:00 CST 1969", new Date(0).toString()); } public void test_toGMTString_us() throws Exception { @@ -61,10 +62,10 @@ public class DateTest extends TestCase { Calendar c = Calendar.getInstance(); c.clear(); c.set(Calendar.YEAR, 21); - assertEquals("Wed Jan 01 00:00:00 GMT-08:00 21", c.getTime().toString()); + assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString()); assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString()); c.set(Calendar.YEAR, 321); - assertEquals("Sun Jan 01 00:00:00 GMT-08:00 321", c.getTime().toString()); + assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString()); assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString()); } } diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java index e1e84ab..9005f25 100644 --- a/luni/src/test/java/libcore/java/util/LocaleTest.java +++ b/luni/src/test/java/libcore/java/util/LocaleTest.java @@ -1203,4 +1203,38 @@ public class LocaleTest extends junit.framework.TestCase { System.setUnchangeableSystemProperty("user.locale", userLocale); } } + + // http://b/20252611 + public void testLegacyLocalesWithExtensions() { + Locale ja_JP_JP = new Locale("ja", "JP", "JP"); + assertEquals("ca-japanese", ja_JP_JP.getExtension(Locale.UNICODE_LOCALE_EXTENSION)); + assertEquals("japanese", ja_JP_JP.getUnicodeLocaleType("ca")); + + Locale th_TH_TH = new Locale("th", "TH", "TH"); + assertEquals("nu-thai", th_TH_TH.getExtension(Locale.UNICODE_LOCALE_EXTENSION)); + assertEquals("thai", th_TH_TH.getUnicodeLocaleType("nu")); + } + + // http://b/20252611 + public void testLowerCaseExtensionKeys() { + // We must lowercase extension keys in forLanguageTag.. + Locale ar_EG = Locale.forLanguageTag("ar-EG-U-nu-arab"); + assertEquals("nu-arab", ar_EG.getExtension(Locale.UNICODE_LOCALE_EXTENSION)); + assertEquals("ar-EG-u-nu-arab", ar_EG.toLanguageTag()); + + // ... and in builders. + Locale.Builder b = new Locale.Builder(); + b.setLanguage("ar"); + b.setRegion("EG"); + b.setExtension('U', "nu-arab"); + assertEquals("ar-EG-u-nu-arab", b.build().toLanguageTag()); + + // Corollary : extension keys are case insensitive. + b = new Locale.Builder(); + b.setLanguage("ar"); + b.setRegion("EG"); + b.setExtension('U', "nu-arab"); + b.setExtension('u', "nu-thai"); + assertEquals("ar-EG-u-nu-thai", b.build().toLanguageTag()); + } } diff --git a/luni/src/test/java/libcore/java/util/TimSortTest.java b/luni/src/test/java/libcore/java/util/TimSortTest.java new file mode 100644 index 0000000..0e928ba --- /dev/null +++ b/luni/src/test/java/libcore/java/util/TimSortTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package libcore.java.util; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * This test is based on test data generated by + * https://github.com/abstools/java-timsort-bug/blob/master/TestTimSort.java + */ +public class TimSortTest extends TestCase { + + private static final Comparator<Integer> NATURAL_ORDER_COMPARATOR = new Comparator<Integer>() { + public int compare(Integer first, Integer second) { + return first.compareTo(second); + } + }; + + private static final int BAD_DATA_SIZE = 65536; + + private static int[] BAD_RUN_OFFSETS = { + 20204, 20221, 20237, 20255, 20289, 20363, 20521, 20837, 21469, 22733, 25260, 30315, + 40408, 40425, 40441, 40459, 40493, 40567, 40725, 41041, 41673, 42936, 45463, 50500, + 50517, 50533, 50551, 50585, 50659, 50817, 51133, 51764, 53027, 55536, 55553, 55569, + 55587, 55621, 55695, 55853, 56168, 56799, 58044, 58061, 58077, 58095, 58129, 58203, + 58360, 58675, 59288, 59305, 59321, 59339, 59373, 59446, 59603, 59900, 59917, 59933, + 59951, 59985, 60059, 60196, 60217, 60236, 60274, 60332, 60351, 60369, 60389, 60405, + }; + + public void testBug19493779WithComparable() throws Exception { + Integer[] array = createBugTriggerData(); + Arrays.sort(array); + // The bug caused an ArrayIndexOutOfBoundsException, but we check this anyway. + assertSorted(array); + } + + public void testBug19493779WithComparator() throws Exception { + Integer[] array = createBugTriggerData(); + Arrays.sort(array, NATURAL_ORDER_COMPARATOR); + // The bug caused an ArrayIndexOutOfBoundsException, but we check this anyway. + assertSorted(array); + } + + private static void assertSorted(Integer[] arrayToSort) { + for (int i = 1; i < arrayToSort.length; i++) { + if (arrayToSort[i - 1] > arrayToSort[i]) { + fail("Array not sorted at element " + i + ": " + Arrays.toString(arrayToSort)); + } + } + } + + private static Integer[] createBugTriggerData() { + final Integer zero = 0; + final Integer one = 1; + + Integer[] bugTriggerData = new Integer[BAD_DATA_SIZE]; + for (int i = 0; i < bugTriggerData.length; i++) { + bugTriggerData[i] = zero; + } + + for (int i = 0; i < BAD_RUN_OFFSETS.length; i++) { + bugTriggerData[BAD_RUN_OFFSETS[i]] = one; + } + return bugTriggerData; + } +}
\ No newline at end of file diff --git a/luni/src/test/java/libcore/java/util/zip/Zip64Test.java b/luni/src/test/java/libcore/java/util/zip/Zip64Test.java new file mode 100644 index 0000000..e4b5baf --- /dev/null +++ b/luni/src/test/java/libcore/java/util/zip/Zip64Test.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package libcore.java.util.zip; + +import junit.framework.TestCase; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.zip.Zip64; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; + +public class Zip64Test extends TestCase { + + // We shouldn't attempt to look inside the extended info if we have valid fields + // in the regular file header / central directory entry. + public void testParseZip64ExtendedInfo_noFieldsPresent() throws Exception { + ZipEntry ze = createZipEntry(null, 100, 200, ZipEntry.STORED, 300); + Zip64.parseZip64ExtendedInfo(ze, false /* fromCentralDirectory */); + Zip64.parseZip64ExtendedInfo(ze, true /* fromCentralDirectory */); + } + + // We *should* attempt to look in the extended info if the local file header / central + // directory entry don't have the correct values. + public void testParseZip64ExtendedInfo_missingExtendedInfo() throws Exception { + ZipEntry ze = createZipEntry(null, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, + Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, ZipEntry.STORED, 300); + try { + Zip64.parseZip64ExtendedInfo(ze, false /* fromCentralDirectory */); + fail(); + } catch (ZipException expected) { + } + + try { + Zip64.parseZip64ExtendedInfo(ze, true /* fromCentralDirectory */); + fail(); + } catch (ZipException expected) { + } + } + + // Test the case where the compressed / uncompressed sizes are in the extended info + // but the header offset isn't. + public void testParseZip64ExtendedInfo_partialInfo() throws Exception { + byte[] extras = new byte[20]; + ByteBuffer buf = ByteBuffer.wrap(extras); + buf.order(ByteOrder.LITTLE_ENDIAN); + buf.putShort((short) 0x0001); + buf.putShort((short) 16); + buf.putLong(50); + buf.putLong(100); + + ZipEntry ze = createZipEntry(extras, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, + Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, ZipEntry.STORED, 300); + + Zip64.parseZip64ExtendedInfo(ze, false /*fromCentralDirectory */); + assertEquals(50, ze.getSize()); + assertEquals(100, ze.getCompressedSize()); + + ze = createZipEntry(extras, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, + Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, ZipEntry.STORED, 300); + Zip64.parseZip64ExtendedInfo(ze, true /*fromCentralDirectory */); + assertEquals(50, ze.getSize()); + assertEquals(100, ze.getCompressedSize()); + } + + public void testInsertZip64ExtendedInfo() throws Exception { + ZipEntry ze = createZipEntry(null, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 300, + Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 500, ZipEntry.STORED, 300); + Zip64.insertZip64ExtendedInfoToExtras(ze); + + assertNotNull(ze.getExtra()); + ByteBuffer buf = ByteBuffer.wrap(ze.getExtra()); + buf.order(ByteOrder.LITTLE_ENDIAN); + assertEquals(0x0001, buf.getShort()); + assertEquals(24, buf.getShort()); + assertEquals(Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 300, buf.getLong()); + assertEquals(Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 500, buf.getLong()); + } + + private static ZipEntry createZipEntry(byte[] extras, long size, long compressedSize, + int compressionMethod, long headerOffset) { + return new ZipEntry("name", "comment", 42 /* crc */, compressedSize, size, + compressionMethod, 42 /* time */, 42 /* modDate */, extras, headerOffset, + 42 /* data offset */); + } +} diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java index 494d15e..dd7d6e7 100644 --- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java +++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java @@ -21,11 +21,13 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; +import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; @@ -45,6 +47,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.crypto.AEADBadTagException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -231,6 +234,10 @@ public final class CipherTest extends TestCase { return algorithm.startsWith("PBE"); } + private static boolean isAEAD(String algorithm) { + return "GCM".equals(algorithm) || algorithm.contains("/GCM/"); + } + private static boolean isStreamMode(String algorithm) { return algorithm.contains("/CTR/") || algorithm.contains("/OFB") || algorithm.contains("/CFB"); @@ -295,10 +302,10 @@ public final class CipherTest extends TestCase { setExpectedBlockSize("AES/ECB/PKCS5PADDING", 16); setExpectedBlockSize("AES/ECB/PKCS7PADDING", 16); setExpectedBlockSize("AES/ECB/NOPADDING", 16); + setExpectedBlockSize("AES/GCM/NOPADDING", 16); setExpectedBlockSize("AES/OFB/PKCS5PADDING", 16); setExpectedBlockSize("AES/OFB/PKCS7PADDING", 16); setExpectedBlockSize("AES/OFB/NOPADDING", 16); - setExpectedBlockSize("GCM", 16); setExpectedBlockSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16); setExpectedBlockSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16); setExpectedBlockSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16); @@ -453,9 +460,9 @@ public final class CipherTest extends TestCase { setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16); setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16); setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16); + setExpectedOutputSize("AES/GCM/NOPADDING", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8); setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16); setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16); - setExpectedOutputSize("GCM", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8); setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16); setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16); setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16); @@ -486,9 +493,9 @@ public final class CipherTest extends TestCase { setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0); + setExpectedOutputSize("AES/GCM/NOPADDING", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0); - setExpectedOutputSize("GCM", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0); @@ -498,15 +505,8 @@ public final class CipherTest extends TestCase { setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0); setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0); - // AndroidOpenSSL returns the block size for the block ciphers - setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16); - setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16); - setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16); - setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16); - setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8); - setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8); - setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8); - setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8); + setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0); + setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0); if (StandardNames.IS_RI) { setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8); @@ -750,8 +750,8 @@ public final class CipherTest extends TestCase { new SecureRandom().nextBytes(salt); return new PBEParameterSpec(salt, 1024); } - if (algorithm.equals("GCM")) { - final byte[] iv = new byte[8]; + if (algorithm.equals("AES/GCM/NOPADDING")) { + final byte[] iv = new byte[12]; new SecureRandom().nextBytes(iv); return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv); } @@ -791,7 +791,7 @@ public final class CipherTest extends TestCase { } byte[] iv = encryptCipher.getIV(); if (iv != null) { - if ("GCM".equals(algorithm)) { + if ("AES/GCM/NOPADDING".equals(algorithm)) { return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv); } return new IvParameterSpec(iv); @@ -988,14 +988,130 @@ public final class CipherTest extends TestCase { Security.addProvider(mockProviderInvalid); try { - Cipher.getInstance("FOO"); - fail("Should not find any matching providers"); - } catch (NoSuchAlgorithmException expected) { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16], "FOO")); + fail("Should not find any matching providers; found: " + c); + } catch (ClassCastException expected) { } finally { Security.removeProvider(mockProviderInvalid.getName()); } } + public void testCipher_init_CallsInitWithParams_AlgorithmParameterSpec() throws Exception { + Provider mockProviderRejects = new MockProvider("MockProviderRejects") { + public void setup() { + put("Cipher.FOO", + MockCipherSpi.MustInitWithAlgorithmParameterSpec_RejectsAll.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + Provider mockProviderAccepts = new MockProvider("MockProviderAccepts") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + + Security.addProvider(mockProviderRejects); + Security.addProvider(mockProviderAccepts); + try { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.ENCRYPT_MODE, new MockKey(), new IvParameterSpec(new byte[12])); + assertEquals(mockProviderAccepts, c.getProvider()); + } finally { + Security.removeProvider(mockProviderRejects.getName()); + Security.removeProvider(mockProviderAccepts.getName()); + } + } + + public void testCipher_init_CallsInitWithParams_AlgorithmParameters() throws Exception { + Provider mockProviderRejects = new MockProvider("MockProviderRejects") { + public void setup() { + put("Cipher.FOO", + MockCipherSpi.MustInitWithAlgorithmParameters_RejectsAll.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + Provider mockProviderAccepts = new MockProvider("MockProviderAccepts") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + + Security.addProvider(mockProviderRejects); + Security.addProvider(mockProviderAccepts); + try { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.ENCRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES")); + assertEquals(mockProviderAccepts, c.getProvider()); + } finally { + Security.removeProvider(mockProviderRejects.getName()); + Security.removeProvider(mockProviderAccepts.getName()); + } + } + + public void testCipher_init_CallsInitIgnoresRuntimeException() throws Exception { + Provider mockProviderRejects = new MockProvider("MockProviderRejects") { + public void setup() { + put("Cipher.FOO", + MockCipherSpi.MustInitWithAlgorithmParameters_ThrowsNull.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + Provider mockProviderAccepts = new MockProvider("MockProviderAccepts") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + + Security.addProvider(mockProviderRejects); + Security.addProvider(mockProviderAccepts); + try { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.ENCRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES")); + assertEquals(mockProviderAccepts, c.getProvider()); + } finally { + Security.removeProvider(mockProviderRejects.getName()); + Security.removeProvider(mockProviderAccepts.getName()); + } + } + + public void testCipher_init_CallsInitWithMode() throws Exception { + Provider mockProviderOnlyEncrypt = new MockProvider("MockProviderOnlyEncrypt") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.MustInitForEncryptModeOrRejects.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + Provider mockProviderAcceptsAll = new MockProvider("MockProviderAcceptsAll") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName()); + put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName()); + } + }; + + Security.addProvider(mockProviderOnlyEncrypt); + Security.addProvider(mockProviderAcceptsAll); + try { + { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.DECRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES")); + assertEquals(mockProviderAcceptsAll, c.getProvider()); + } + + { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.ENCRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES")); + assertEquals(mockProviderOnlyEncrypt, c.getProvider()); + } + } finally { + Security.removeProvider(mockProviderOnlyEncrypt.getName()); + Security.removeProvider(mockProviderAcceptsAll.getName()); + } + } + public void test_getInstance() throws Exception { final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream(); PrintStream out = new PrintStream(errBuffer); @@ -1143,9 +1259,9 @@ public final class CipherTest extends TestCase { c.init(encryptMode, encryptKey, encryptSpec); assertEquals(cipherID + " getBlockSize() encryptMode", - getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize()); - assertEquals(cipherID + " getOutputSize(0) encryptMode", - getExpectedOutputSize(algorithm, encryptMode, providerName), c.getOutputSize(0)); + getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize()); + assertTrue(cipherID + " getOutputSize(0) encryptMode", + getExpectedOutputSize(algorithm, encryptMode, providerName) <= c.getOutputSize(0)); if ((algorithm.endsWith("/PKCS5PADDING") || algorithm.endsWith("/PKCS7PADDING")) && isStreamMode(algorithm)) { assertEquals(getExpectedOutputSize(algorithm, encryptMode, providerName), @@ -1209,7 +1325,7 @@ public final class CipherTest extends TestCase { // Test wrapping a key. Every cipher should be able to wrap. Except those that can't. /* Bouncycastle is broken for wrapping because getIV() fails. */ if (isSupportedForWrapping(algorithm) - && !algorithm.equals("GCM") && !providerName.equals("BC")) { + && !algorithm.equals("AES/GCM/NOPADDING") && !providerName.equals("BC")) { // Generate a small SecretKey for AES. KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(128); @@ -1233,16 +1349,28 @@ public final class CipherTest extends TestCase { if (!isOnlyWrappingAlgorithm(algorithm)) { c.init(Cipher.ENCRYPT_MODE, encryptKey, encryptSpec); + if (isAEAD(algorithm)) { + c.updateAAD(new byte[24]); + } byte[] cipherText = c.doFinal(getActualPlainText(algorithm)); + if (isAEAD(algorithm)) { + c.updateAAD(new byte[24]); + } byte[] cipherText2 = c.doFinal(getActualPlainText(algorithm)); assertEquals(cipherID, Arrays.toString(cipherText), Arrays.toString(cipherText2)); c.init(Cipher.DECRYPT_MODE, getDecryptKey(algorithm), decryptSpec); + if (isAEAD(algorithm)) { + c.updateAAD(new byte[24]); + } byte[] decryptedPlainText = c.doFinal(cipherText); assertEquals(cipherID, Arrays.toString(getExpectedPlainText(algorithm, providerName)), Arrays.toString(decryptedPlainText)); + if (isAEAD(algorithm)) { + c.updateAAD(new byte[24]); + } byte[] decryptedPlainText2 = c.doFinal(cipherText); assertEquals(cipherID, Arrays.toString(decryptedPlainText), @@ -1361,11 +1489,22 @@ public final class CipherTest extends TestCase { Cipher encryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider); encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey); byte[] cipherText = encryptCipher.doFinal(prePaddedPlainText); + encryptCipher.update(prePaddedPlainText); + encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey); + byte[] cipherText2 = encryptCipher.doFinal(prePaddedPlainText); + assertEquals(Arrays.toString(cipherText), + Arrays.toString(cipherText2)); + Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider); decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey); byte[] plainText = decryptCipher.doFinal(cipherText); assertEquals(Arrays.toString(ORIGINAL_PLAIN_TEXT), Arrays.toString(plainText)); + decryptCipher.update(prePaddedPlainText); + decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey); + byte[] plainText2 = decryptCipher.doFinal(cipherText); + assertEquals(Arrays.toString(plainText), + Arrays.toString(plainText2)); } public void testOutputPKCS1Padding() throws Exception { @@ -2491,6 +2630,80 @@ public final class CipherTest extends TestCase { }; /* + * Taken from BoringSSL test vectors. + */ + private static final byte[] AES_128_GCM_TestVector_1_Key = new byte[] { + (byte) 0xca, (byte) 0xbd, (byte) 0xcf, (byte) 0x54, (byte) 0x1a, (byte) 0xeb, + (byte) 0xf9, (byte) 0x17, (byte) 0xba, (byte) 0xc0, (byte) 0x19, (byte) 0xf1, + (byte) 0x39, (byte) 0x25, (byte) 0xd2, (byte) 0x67, + }; + + /* + * Taken from BoringSSL test vectors. + */ + private static final byte[] AES_128_GCM_TestVector_1_IV = new byte[] { + (byte) 0x2c, (byte) 0x34, (byte) 0xc0, (byte) 0x0c, (byte) 0x42, (byte) 0xda, + (byte) 0xe3, (byte) 0x82, (byte) 0x27, (byte) 0x9d, (byte) 0x79, (byte) 0x74, + }; + + /* + * Taken from BoringSSL test vectors. + */ + private static final byte[] AES_128_GCM_TestVector_1_AAD = new byte[] { + (byte) 0xdd, (byte) 0x10, (byte) 0xe3, (byte) 0x71, (byte) 0xb2, (byte) 0x2e, + (byte) 0x15, (byte) 0x67, (byte) 0x1c, (byte) 0x31, (byte) 0xaf, (byte) 0xee, + (byte) 0x55, (byte) 0x2b, (byte) 0xf1, (byte) 0xde, (byte) 0xa0, (byte) 0x7c, + (byte) 0xbb, (byte) 0xf6, (byte) 0x85, (byte) 0xe2, (byte) 0xca, (byte) 0xa0, + (byte) 0xe0, (byte) 0x36, (byte) 0x37, (byte) 0x16, (byte) 0xa2, (byte) 0x76, + (byte) 0xe1, (byte) 0x20, (byte) 0xc6, (byte) 0xc0, (byte) 0xeb, (byte) 0x4a, + (byte) 0xcb, (byte) 0x1a, (byte) 0x4d, (byte) 0x1b, (byte) 0xa7, (byte) 0x3f, + (byte) 0xde, (byte) 0x66, (byte) 0x15, (byte) 0xf7, (byte) 0x08, (byte) 0xaa, + (byte) 0xa4, (byte) 0x6b, (byte) 0xc7, (byte) 0x6c, (byte) 0x7f, (byte) 0xf3, + (byte) 0x45, (byte) 0xa4, (byte) 0xf7, (byte) 0x6b, (byte) 0xda, (byte) 0x11, + (byte) 0x7f, (byte) 0xe5, (byte) 0x6f, (byte) 0x0d, (byte) 0xc9, (byte) 0xb9, + (byte) 0x39, (byte) 0x04, (byte) 0x0d, (byte) 0xdd, + }; + + /* + * Taken from BoringSSL test vectors. + */ + private static final byte[] AES_128_GCM_TestVector_1_Plaintext = new byte[] { + (byte) 0x88, (byte) 0xcc, (byte) 0x1e, (byte) 0x07, (byte) 0xdf, (byte) 0xde, + (byte) 0x8e, (byte) 0x08, (byte) 0x08, (byte) 0x2e, (byte) 0x67, (byte) 0x66, + (byte) 0xe0, (byte) 0xa8, (byte) 0x81, (byte) 0x03, (byte) 0x38, (byte) 0x47, + (byte) 0x42, (byte) 0xaf, (byte) 0x37, (byte) 0x8d, (byte) 0x7b, (byte) 0x6b, + (byte) 0x8a, (byte) 0x87, (byte) 0xfc, (byte) 0xe0, (byte) 0x36, (byte) 0xaf, + (byte) 0x74, (byte) 0x41, (byte) 0xc1, (byte) 0x39, (byte) 0x61, (byte) 0xc2, + (byte) 0x5a, (byte) 0xfe, (byte) 0xa7, (byte) 0xf6, (byte) 0xe5, (byte) 0x61, + (byte) 0x93, (byte) 0xf5, (byte) 0x4b, (byte) 0xee, (byte) 0x00, (byte) 0x11, + (byte) 0xcb, (byte) 0x78, (byte) 0x64, (byte) 0x2c, (byte) 0x3a, (byte) 0xb9, + (byte) 0xe6, (byte) 0xd5, (byte) 0xb2, (byte) 0xe3, (byte) 0x58, (byte) 0x33, + (byte) 0xec, (byte) 0x16, (byte) 0xcd, (byte) 0x35, (byte) 0x55, (byte) 0x15, + (byte) 0xaf, (byte) 0x1a, (byte) 0x19, (byte) 0x0f, + }; + + /* + * Taken from BoringSSL test vectors. + */ + private static final byte[] AES_128_GCM_TestVector_1_Encrypted = new byte[] { + (byte) 0x04, (byte) 0x94, (byte) 0x53, (byte) 0xba, (byte) 0xf1, (byte) 0x57, + (byte) 0x87, (byte) 0x87, (byte) 0xd6, (byte) 0x8e, (byte) 0xd5, (byte) 0x47, + (byte) 0x87, (byte) 0x26, (byte) 0xc0, (byte) 0xb8, (byte) 0xa6, (byte) 0x36, + (byte) 0x33, (byte) 0x7a, (byte) 0x0b, (byte) 0x8a, (byte) 0x82, (byte) 0xb8, + (byte) 0x68, (byte) 0x36, (byte) 0xf9, (byte) 0x1c, (byte) 0xde, (byte) 0x25, + (byte) 0xe6, (byte) 0xe4, (byte) 0x4c, (byte) 0x34, (byte) 0x59, (byte) 0x40, + (byte) 0xe8, (byte) 0x19, (byte) 0xa0, (byte) 0xc5, (byte) 0x05, (byte) 0x75, + (byte) 0x1e, (byte) 0x60, (byte) 0x3c, (byte) 0xb8, (byte) 0xf8, (byte) 0xc4, + (byte) 0xfe, (byte) 0x98, (byte) 0x71, (byte) 0x91, (byte) 0x85, (byte) 0x56, + (byte) 0x27, (byte) 0x94, (byte) 0xa1, (byte) 0x85, (byte) 0xe5, (byte) 0xde, + (byte) 0xc4, (byte) 0x15, (byte) 0xc8, (byte) 0x1f, (byte) 0x2f, (byte) 0x16, + (byte) 0x2c, (byte) 0xdc, (byte) 0xd6, (byte) 0x50, (byte) 0xdc, (byte) 0xe7, + (byte) 0x19, (byte) 0x87, (byte) 0x28, (byte) 0xbf, (byte) 0xc1, (byte) 0xb5, + (byte) 0xf9, (byte) 0x49, (byte) 0xb9, (byte) 0xb5, (byte) 0x37, (byte) 0x41, + (byte) 0x99, (byte) 0xc6, + }; + + /* * Test key generation: * openssl rand -hex 16 * echo 'ceaa31952dfd3d0f5af4b2042ba06094' | sed 's/\(..\)/(byte) 0x\1, /g' @@ -2559,17 +2772,20 @@ public final class CipherTest extends TestCase { public final byte[] iv; + public final byte[] aad; + public final byte[] plaintext; public final byte[] ciphertext; public final byte[] plaintextPadded; - public CipherTestParam(String transformation, byte[] key, byte[] iv, byte[] plaintext, - byte[] plaintextPadded, byte[] ciphertext) { - this.transformation = transformation; + public CipherTestParam(String transformation, byte[] key, byte[] iv, byte[] aad, + byte[] plaintext, byte[] plaintextPadded, byte[] ciphertext) { + this.transformation = transformation.toUpperCase(Locale.ROOT); this.key = key; this.iv = iv; + this.aad = aad; this.plaintext = plaintext; this.plaintextPadded = plaintextPadded; this.ciphertext = ciphertext; @@ -2580,23 +2796,34 @@ public final class CipherTest extends TestCase { static { CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB/PKCS5Padding", AES_128_KEY, null, + null, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded, AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted)); // PKCS#5 is assumed to be equivalent to PKCS#7 -- same test vectors are thus used for both. CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB/PKCS7Padding", AES_128_KEY, null, + null, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded, AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted)); + CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/GCM/NOPADDING", + AES_128_GCM_TestVector_1_Key, + AES_128_GCM_TestVector_1_IV, + AES_128_GCM_TestVector_1_AAD, + AES_128_GCM_TestVector_1_Plaintext, + AES_128_GCM_TestVector_1_Plaintext, + AES_128_GCM_TestVector_1_Encrypted)); if (IS_UNLIMITED) { CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC/PKCS5Padding", AES_256_KEY, AES_256_CBC_PKCS5Padding_TestVector_1_IV, + null, AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext, AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded, AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext)); CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC/PKCS7Padding", AES_256_KEY, AES_256_CBC_PKCS5Padding_TestVector_1_IV, + null, AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext, AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded, AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext)); @@ -2632,62 +2859,98 @@ public final class CipherTest extends TestCase { private void checkCipher(CipherTestParam p, String provider) throws Exception { SecretKey key = new SecretKeySpec(p.key, "AES"); Cipher c = Cipher.getInstance(p.transformation, provider); + AlgorithmParameterSpec spec = null; if (p.iv != null) { - spec = new IvParameterSpec(p.iv); + if (isAEAD(p.transformation)) { + spec = new GCMParameterSpec((p.ciphertext.length - p.plaintext.length) * 8, p.iv); + } else { + spec = new IvParameterSpec(p.iv); + } } + c.init(Cipher.ENCRYPT_MODE, key, spec); + if (p.aad != null) { + c.updateAAD(p.aad); + } final byte[] actualCiphertext = c.doFinal(p.plaintext); - assertEquals(Arrays.toString(p.ciphertext), Arrays.toString(actualCiphertext)); + assertEquals(p.transformation + " " + provider, Arrays.toString(p.ciphertext), + Arrays.toString(actualCiphertext)); + c = Cipher.getInstance(p.transformation, provider); + c.init(Cipher.ENCRYPT_MODE, key, spec); byte[] emptyCipherText = c.doFinal(); assertNotNull(emptyCipherText); c.init(Cipher.DECRYPT_MODE, key, spec); - try { - c.updateAAD(new byte[8]); - fail("Cipher should not support AAD"); - } catch (UnsupportedOperationException expected) { + if (!isAEAD(p.transformation)) { + try { + c.updateAAD(new byte[8]); + fail("Cipher should not support AAD"); + } catch (UnsupportedOperationException | IllegalStateException expected) { + } } - byte[] emptyPlainText = c.doFinal(emptyCipherText); - assertEquals(Arrays.toString(new byte[0]), Arrays.toString(emptyPlainText)); + try { + byte[] emptyPlainText = c.doFinal(emptyCipherText); + assertEquals(Arrays.toString(new byte[0]), Arrays.toString(emptyPlainText)); + } catch (AEADBadTagException e) { + if (!"AndroidOpenSSL".equals(provider) || !isAEAD(p.transformation)) { + throw e; + } + } // empty decrypt { - if (StandardNames.IS_RI) { + if (!isAEAD(p.transformation) + && (StandardNames.IS_RI || provider.equals("AndroidOpenSSL"))) { assertEquals(Arrays.toString(new byte[0]), Arrays.toString(c.doFinal())); c.update(new byte[0]); assertEquals(Arrays.toString(new byte[0]), Arrays.toString(c.doFinal())); - } else if (provider.equals("BC")) { + } else if (provider.equals("BC") || isAEAD(p.transformation)) { try { c.doFinal(); fail(); - } catch (IllegalBlockSizeException expected) { + } catch (IllegalBlockSizeException maybe) { + if (isAEAD(p.transformation)) { + throw maybe; + } + } catch (AEADBadTagException maybe) { + if (!isAEAD(p.transformation)) { + throw maybe; + } } try { c.update(new byte[0]); c.doFinal(); fail(); - } catch (IllegalBlockSizeException expected) { + } catch (IllegalBlockSizeException maybe) { + if (isAEAD(p.transformation)) { + throw maybe; + } + } catch (AEADBadTagException maybe) { + if (!isAEAD(p.transformation)) { + throw maybe; + } } - } else if (provider.equals("AndroidOpenSSL")) { - assertNull(c.doFinal()); - - c.update(new byte[0]); - assertNull(c.doFinal()); } else { throw new AssertionError("Define your behavior here for " + provider); } } + // Cipher might be in unspecified state from failures above. + c.init(Cipher.DECRYPT_MODE, key, spec); + // .doFinal(input) { + if (p.aad != null) { + c.updateAAD(p.aad); + } final byte[] actualPlaintext = c.doFinal(p.ciphertext); assertEquals(Arrays.toString(p.plaintext), Arrays.toString(actualPlaintext)); } @@ -2697,6 +2960,12 @@ public final class CipherTest extends TestCase { final byte[] largerThanCiphertext = new byte[p.ciphertext.length + 5]; System.arraycopy(p.ciphertext, 0, largerThanCiphertext, 5, p.ciphertext.length); + if (p.aad != null) { + final byte[] largerThanAad = new byte[p.aad.length + 100]; + System.arraycopy(p.aad, 0, largerThanAad, 50, p.aad.length); + c.updateAAD(largerThanAad, 50, p.aad.length); + } + final byte[] actualPlaintext = new byte[c.getOutputSize(p.ciphertext.length)]; assertEquals(p.plaintext.length, c.doFinal(largerThanCiphertext, 5, p.ciphertext.length, actualPlaintext)); @@ -2709,6 +2978,12 @@ public final class CipherTest extends TestCase { final byte[] largerThanCiphertext = new byte[p.ciphertext.length + 10]; System.arraycopy(p.ciphertext, 0, largerThanCiphertext, 5, p.ciphertext.length); + if (p.aad != null) { + final byte[] largerThanAad = new byte[p.aad.length + 2]; + System.arraycopy(p.aad, 0, largerThanAad, 2, p.aad.length); + c.updateAAD(largerThanAad, 2, p.aad.length); + } + final byte[] actualPlaintext = new byte[c.getOutputSize(p.ciphertext.length) + 2]; assertEquals(p.plaintext.length, c.doFinal(largerThanCiphertext, 5, p.ciphertext.length, actualPlaintext, 1)); @@ -2716,13 +2991,18 @@ public final class CipherTest extends TestCase { Arrays.toString(Arrays.copyOfRange(actualPlaintext, 1, p.plaintext.length + 1))); } - Cipher cNoPad = Cipher.getInstance( - getCipherTransformationWithNoPadding(p.transformation), provider); - cNoPad.init(Cipher.DECRYPT_MODE, key, spec); + if (!p.transformation.endsWith("NOPADDING")) { + Cipher cNoPad = Cipher.getInstance( + getCipherTransformationWithNoPadding(p.transformation), provider); + cNoPad.init(Cipher.DECRYPT_MODE, key, spec); - final byte[] actualPlaintextPadded = cNoPad.doFinal(p.ciphertext); - assertEquals(provider + ":" + cNoPad.getAlgorithm(), Arrays.toString(p.plaintextPadded), - Arrays.toString(actualPlaintextPadded)); + if (p.aad != null) { + c.updateAAD(p.aad); + } + final byte[] actualPlaintextPadded = cNoPad.doFinal(p.ciphertext); + assertEquals(provider + ":" + cNoPad.getAlgorithm(), + Arrays.toString(p.plaintextPadded), Arrays.toString(actualPlaintextPadded)); + } // Test wrapping a key. Every cipher should be able to wrap. { @@ -2732,6 +3012,7 @@ public final class CipherTest extends TestCase { SecretKey sk = kg.generateKey(); // Wrap it + c = Cipher.getInstance(p.transformation, provider); c.init(Cipher.WRAP_MODE, key, spec); byte[] cipherText = c.wrap(sk); @@ -2838,6 +3119,27 @@ public final class CipherTest extends TestCase { fail("should not be able to call updateAAD with too large length"); } catch (IllegalArgumentException expected) { } + + try { + c.updateAAD(new byte[8]); + fail("should not be able to call updateAAD on non-AEAD cipher"); + } catch (UnsupportedOperationException | IllegalStateException expected) { + } + } + + public void testCipher_updateAAD_AfterInit_WithGcm_Success() throws Exception { + Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); + c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[128 / 8], "AES")); + c.updateAAD(new byte[8]); + c.updateAAD(new byte[8]); + } + + public void testCipher_updateAAD_AfterUpdate_WithGcm_Sucess() throws Exception { + Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); + c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[128 / 8], "AES")); + c.updateAAD(new byte[8]); + c.update(new byte[8]); + c.updateAAD(new byte[8]); } public void testCipher_ShortBlock_Failure() throws Exception { @@ -2877,6 +3179,12 @@ public final class CipherTest extends TestCase { } private void checkCipher_ShortBlock_Failure(CipherTestParam p, String provider) throws Exception { + // Do not try to test ciphers with no padding already. + String noPaddingTransform = getCipherTransformationWithNoPadding(p.transformation); + if (p.transformation.equals(noPaddingTransform)) { + return; + } + SecretKey key = new SecretKeySpec(p.key, "AES"); Cipher c = Cipher.getInstance( getCipherTransformationWithNoPadding(p.transformation), provider); @@ -2884,12 +3192,14 @@ public final class CipherTest extends TestCase { return; } - c.init(Cipher.ENCRYPT_MODE, key); - try { - c.doFinal(new byte[] { 0x01, 0x02, 0x03 }); - fail("Should throw IllegalBlockSizeException on wrong-sized block; provider=" - + provider); - } catch (IllegalBlockSizeException expected) { + if (!p.transformation.endsWith("NOPADDING")) { + c.init(Cipher.ENCRYPT_MODE, key); + try { + c.doFinal(new byte[] { 0x01, 0x02, 0x03 }); + fail("Should throw IllegalBlockSizeException on wrong-sized block; transform=" + + p.transformation + " provider=" + provider); + } catch (IllegalBlockSizeException expected) { + } } } @@ -3064,4 +3374,145 @@ public final class CipherTest extends TestCase { } } } + + /** + * Several exceptions can be thrown by init. Check that in this case we throw the right one, + * as the error could fall under the umbrella of other exceptions. + * http://b/18987633 + */ + public void testCipher_init_DoesNotSupportKeyClass_throwsInvalidKeyException() + throws Exception { + Provider mockProvider = new MockProvider("MockProvider") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName()); + put("Cipher.FOO SupportedKeyClasses", "none"); + } + }; + + Security.addProvider(mockProvider); + try { + Cipher c = Cipher.getInstance("FOO"); + c.init(Cipher.DECRYPT_MODE, new MockKey()); + fail("Expected InvalidKeyException"); + } catch (InvalidKeyException expected) { + } finally { + Security.removeProvider(mockProvider.getName()); + } + } + + /* + * When in decrypt mode and using padding, the buffer shouldn't necessarily have room for an + * extra block when using padding. + * http://b/19186852 + */ + public void testDecryptBufferMultipleBlockSize_mustNotThrowException() throws Exception { + String testString = "Hello, World!"; + byte[] testKey = "0123456789012345".getBytes(StandardCharsets.US_ASCII); + String testedCipher = "AES/ECB/PKCS7Padding"; + + Cipher encCipher = Cipher.getInstance(testedCipher); + encCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(testKey, "AES")); + byte[] plainBuffer = testString.getBytes(StandardCharsets.US_ASCII); + byte[] encryptedBuffer = new byte[16]; + int encryptedLength = encCipher.doFinal( + plainBuffer, 0, plainBuffer.length, encryptedBuffer); + assertEquals(16, encryptedLength); + + Cipher cipher = Cipher.getInstance(testedCipher); + cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(testKey, "AES")); + // Must not throw exception. + int unencryptedBytes = cipher.doFinal( + encryptedBuffer, 0, encryptedBuffer.length, encryptedBuffer); + assertEquals(testString, + new String(encryptedBuffer, 0, unencryptedBytes, StandardCharsets.US_ASCII)); + } + + /** + * When using padding in decrypt mode, ensure that empty buffers decode to empty strings + * (no padding needed for the empty buffer). + * http://b/19186852 + */ + public void testDecryptBufferZeroSize_mustDecodeToEmptyString() throws Exception { + String[] androidOpenSSLCiphers = { "AES/CBC/PKCS5PADDING", "AES/CBC/PKCS7PADDING", + "AES/ECB/PKCS5PADDING", "AES/ECB/PKCS7PADDING", "DESEDE/CBC/PKCS5PADDING", + "DESEDE/CBC/PKCS7PADDING" }; + for (String c : androidOpenSSLCiphers) { + Cipher cipher = Cipher.getInstance(c); + if (c.contains("/CBC/")) { + cipher.init(Cipher.DECRYPT_MODE, + new SecretKeySpec("0123456789012345".getBytes(StandardCharsets.US_ASCII), + (c.startsWith("AES/")) ? "AES" : "DESEDE"), + new IvParameterSpec( + ("01234567" + ((c.startsWith("AES/")) ? "89012345" : "")) + .getBytes(StandardCharsets.US_ASCII))); + } else { + cipher.init(Cipher.DECRYPT_MODE, + new SecretKeySpec("0123456789012345".getBytes(StandardCharsets.US_ASCII), + (c.startsWith("AES/")) ? "AES" : "DESEDE")); + } + + byte[] buffer = new byte[0]; + int bytesProduced = cipher.doFinal(buffer, 0, buffer.length, buffer); + assertEquals("", new String(buffer, 0, bytesProduced, StandardCharsets.US_ASCII)); + } + } + + /** + * If a provider rejects a key for "Cipher/Mode/Padding"", there might be another that + * accepts the key for "Cipher". Don't throw InvalidKeyException when trying the first one. + * http://b/22208820 + */ + public void testCipher_init_tryAllCombinationsBeforeThrowingInvalidKey() + throws Exception { + Provider mockProvider = new MockProvider("MockProvider") { + public void setup() { + put("Cipher.FOO/FOO/FOO", MockCipherSpi.AllKeyTypes.class.getName()); + put("Cipher.FOO/FOO/FOO SupportedKeyClasses", "none"); + } + }; + + Provider mockProvider2 = new MockProvider("MockProvider2") { + public void setup() { + put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName()); + } + }; + + Security.addProvider(mockProvider); + + try { + try { + // The provider installed doesn't accept the key. + Cipher c = Cipher.getInstance("FOO/FOO/FOO"); + c.init(Cipher.DECRYPT_MODE, new MockKey()); + fail("Expected InvalidKeyException"); + } catch (InvalidKeyException expected) { + } + + Security.addProvider(mockProvider2); + + try { + // The new provider accepts "FOO" with this key. Use it despite the other provider + // accepts "FOO/FOO/FOO" but doesn't accept the key. + Cipher c = Cipher.getInstance("FOO/FOO/FOO"); + c.init(Cipher.DECRYPT_MODE, new MockKey()); + assertEquals("MockProvider2", c.getProvider().getName()); + } finally { + Security.removeProvider(mockProvider2.getName()); + } + } finally { + Security.removeProvider(mockProvider.getName()); + } + } + + /** + * Check that RSA with OAEPPadding is supported. + * http://b/22208820 + */ + public void test_RSA_OAEPPadding() throws Exception { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); + keyGen.initialize(1024, SecureRandom.getInstance("SHA1PRNG")); + Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding"); + cipher.init(Cipher.ENCRYPT_MODE, keyGen.generateKeyPair().getPublic()); + cipher.doFinal(new byte[] {1,2,3,4}); + } } diff --git a/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java index cabe5c9..cc29640 100644 --- a/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java +++ b/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java @@ -38,7 +38,9 @@ import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; +import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; @@ -374,8 +376,8 @@ public class ECDHKeyAgreementTest extends TestCase { if (providers == null) { return new Provider[0]; } - // Sort providers by name to guarantee non-determinism in the order in which providers are - // used in the tests. + // Sort providers by name to guarantee deterministic order in which providers are used in + // the tests. return sortByName(providers); } @@ -384,8 +386,21 @@ public class ECDHKeyAgreementTest extends TestCase { if (providers == null) { return new Provider[0]; } - // Sort providers by name to guarantee non-determinism in the order in which providers are - // used in the tests. + + // Do not test AndroidKeyStore's KeyFactory. It only handles Android Keystore-backed keys. + // It's OKish not to test AndroidKeyStore's KeyFactory here because it's tested by + // cts/tests/test/keystore. + List<Provider> filteredProvidersList = new ArrayList<Provider>(providers.length); + for (Provider provider : providers) { + if ("AndroidKeyStore".equals(provider.getName())) { + continue; + } + filteredProvidersList.add(provider); + } + providers = filteredProvidersList.toArray(new Provider[filteredProvidersList.size()]); + + // Sort providers by name to guarantee deterministic order in which providers are used in + // the tests. return sortByName(providers); } diff --git a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java index ba03f75..9281b43 100644 --- a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java +++ b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java @@ -16,6 +16,7 @@ package libcore.javax.crypto; +import java.security.InvalidKeyException; import java.security.Provider; import java.security.Security; @@ -54,7 +55,6 @@ public class KeyAgreementTest extends TestCase { public void setup() { put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName()); put("KeyAgreement.FOO SupportedKeyClasses", "none"); - } }; @@ -67,4 +67,29 @@ public class KeyAgreementTest extends TestCase { Security.removeProvider(mockProvider.getName()); } } + + /** + * Several exceptions can be thrown by init. Check that in this case we throw the right one, + * as the error could fall under the umbrella of other exceptions. + * http://b/18987633 + */ + public void testKeyAgreement_init_DoesNotSupportKeyClass_throwsInvalidKeyException() + throws Exception { + Provider mockProvider = new MockProvider("MockProvider") { + public void setup() { + put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName()); + put("KeyAgreement.FOO SupportedKeyClasses", "none"); + } + }; + + Security.addProvider(mockProvider); + try { + KeyAgreement c = KeyAgreement.getInstance("FOO"); + c.init(new MockKey()); + fail("Expected InvalidKeyException"); + } catch (InvalidKeyException expected) { + } finally { + Security.removeProvider(mockProvider.getName()); + } + } } diff --git a/luni/src/test/java/libcore/javax/crypto/MacTest.java b/luni/src/test/java/libcore/javax/crypto/MacTest.java new file mode 100644 index 0000000..314a564 --- /dev/null +++ b/luni/src/test/java/libcore/javax/crypto/MacTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 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.crypto; + +import junit.framework.TestCase; + +import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.Security; + +import javax.crypto.Mac; + +public class MacTest extends TestCase { + private static abstract class MockProvider extends Provider { + public MockProvider(String name) { + super(name, 1.0, "Mock provider used for testing"); + setup(); + } + + public abstract void setup(); + } + + /** + * Several exceptions can be thrown by init. Check that in this case we throw the right one, + * as the error could fall under the umbrella of other exceptions. + * http://b/18987633 + */ + public void testMac_init_DoesNotSupportKeyClass_throwsInvalidKeyException() + throws Exception { + Provider mockProvider = new MockProvider("MockProvider") { + public void setup() { + put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName()); + put("Mac.FOO SupportedKeyClasses", "none"); + + } + }; + + Security.addProvider(mockProvider); + try { + Mac c = Mac.getInstance("FOO"); + c.init(new MockKey()); + fail("Expected InvalidKeyException"); + } catch (InvalidKeyException expected) { + } finally { + Security.removeProvider(mockProvider.getName()); + } + } +} diff --git a/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java b/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java index 6742cf3..c1b1bd2 100644 --- a/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java +++ b/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java @@ -25,6 +25,7 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; @@ -56,6 +57,92 @@ public class MockCipherSpi extends CipherSpi { public static class AllKeyTypes extends MockCipherSpi { } + public static class MustInitWithAlgorithmParameterSpec_RejectsAll extends MockCipherSpi { + @Override + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException { + throw new AssertionError("Must have AlgorithmParameterSpec"); + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new InvalidAlgorithmParameterException("expected rejection"); + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameters params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new AssertionError("Must have AlgorithmParameterSpec"); + } + } + + public static class MustInitWithAlgorithmParameters_RejectsAll extends MockCipherSpi { + @Override + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException { + throw new AssertionError("Must have AlgorithmParameterSpec"); + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new AssertionError("Must have AlgorithmParameterSpec"); + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameters params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new InvalidAlgorithmParameterException("expected rejection"); + } + } + + public static class MustInitWithAlgorithmParameters_ThrowsNull extends MockCipherSpi { + @Override + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException { + throw new NullPointerException("expected rejection"); + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new NullPointerException("expected rejection"); + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameters params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new NullPointerException("expected rejection"); + } + } + + public static class MustInitForEncryptModeOrRejects extends MockCipherSpi { + @Override + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException { + if (opmode != Cipher.ENCRYPT_MODE) { + throw new InvalidKeyException("expected rejection"); + } + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + if (opmode != Cipher.ENCRYPT_MODE) { + throw new InvalidKeyException("expected rejection"); + } + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameters params, + SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + if (opmode != Cipher.ENCRYPT_MODE) { + throw new InvalidKeyException("expected rejection"); + } + } + } + public void checkKeyType(Key key) throws InvalidKeyException { } diff --git a/luni/src/test/java/libcore/javax/crypto/MockKey.java b/luni/src/test/java/libcore/javax/crypto/MockKey.java index 248e2de..1c758f3 100644 --- a/luni/src/test/java/libcore/javax/crypto/MockKey.java +++ b/luni/src/test/java/libcore/javax/crypto/MockKey.java @@ -25,7 +25,7 @@ import java.security.Key; public class MockKey implements Key { @Override public String getAlgorithm() { - throw new UnsupportedOperationException("not implemented"); + return "MOCK"; } @Override diff --git a/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java b/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java new file mode 100644 index 0000000..0edeba7 --- /dev/null +++ b/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 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.crypto; + +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.MacSpi; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.ShortBufferException; + +/** + * Mock CipherSpi used by {@link libcore.javax.crypto.CipherTest}. + */ +public class MockMacSpi extends MacSpi { + public static class SpecificKeyTypes extends MockMacSpi { + @Override + public void checkKeyType(Key key) throws InvalidKeyException { + if (!(key instanceof MockKey)) { + throw new InvalidKeyException("Must be MockKey!"); + } + } + } + + public static class SpecificKeyTypes2 extends MockMacSpi { + @Override + public void checkKeyType(Key key) throws InvalidKeyException { + System.err.println("Checking key of type " + key.getClass().getName()); + if (!(key instanceof MockKey2)) { + throw new InvalidKeyException("Must be MockKey2!"); + } + } + } + + public static class AllKeyTypes extends MockMacSpi { + } + + public void checkKeyType(Key key) throws InvalidKeyException { + } + + @Override + protected int engineGetMacLength() { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected void engineInit(Key key, AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected void engineUpdate(byte input) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected void engineUpdate(byte[] input, int inputOffset, int inputLen) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected byte[] engineDoFinal() { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected void engineReset() { + throw new UnsupportedOperationException("not implemented"); + } +} 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 8e4519d..bf2d0f8 100644 --- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java +++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java @@ -420,6 +420,37 @@ public class SSLSocketTest extends TestCase { 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()); @@ -1678,13 +1709,6 @@ public class SSLSocketTest extends TestCase { return null; } finally { IoUtils.closeQuietly(client); - - // Cancel the reading task. If this task succeeded, then the reading task - // is done and this will have no effect. If this task failed prematurely, - // then the reading task might get unblocked (we're interrupting the thread - // it's running on), will fail early, and we'll thus save some time in this - // test. - readFirstReceivedChunkFuture.cancel(true); } } }); @@ -1798,6 +1822,11 @@ public class SSLSocketTest extends TestCase { 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(); @@ -1823,8 +1852,7 @@ public class SSLSocketTest extends TestCase { } catch (SSLHandshakeException expected) { Throwable cause = expected.getCause(); assertEquals(SSLProtocolException.class, cause.getClass()); - assertTrue(cause.getMessage(), - cause.getMessage().contains("inappropriate fallback")); + assertInappropriateFallbackIsCause(cause); } return null; } @@ -1839,8 +1867,7 @@ public class SSLSocketTest extends TestCase { } catch (SSLHandshakeException expected) { Throwable cause = expected.getCause(); assertEquals(SSLProtocolException.class, cause.getClass()); - assertTrue(cause.getMessage(), - cause.getMessage().contains("inappropriate fallback")); + assertInappropriateFallbackIsCause(cause); } return null; } diff --git a/luni/src/test/java/libcore/util/HexEncodingTest.java b/luni/src/test/java/libcore/util/HexEncodingTest.java index ef79f5c..f5cfb3e 100644 --- a/luni/src/test/java/libcore/util/HexEncodingTest.java +++ b/luni/src/test/java/libcore/util/HexEncodingTest.java @@ -26,8 +26,10 @@ public class HexEncodingTest extends TestCase { public void testEncode() { final byte[] avocados = "avocados".getBytes(StandardCharsets.UTF_8); - assertArraysEqual("61766f6361646f73".toCharArray(), encode(avocados)); + assertArraysEqual("61766F6361646F73".toCharArray(), encode(avocados)); assertArraysEqual(avocados, decode(encode(avocados), false)); + // Make sure we can handle lower case hex encodings as well. + assertArraysEqual(avocados, decode("61766f6361646f73".toCharArray(), false)); } public void testDecode_allow4Bit() { @@ -45,7 +47,7 @@ public class HexEncodingTest extends TestCase { public void testDecode_invalid() { try { - decode("deadbard".toCharArray(), false); + decode("DEADBARD".toCharArray(), false); fail(); } catch (IllegalArgumentException expected) { } @@ -54,13 +56,13 @@ public class HexEncodingTest extends TestCase { // commons uses Character.isDigit and would successfully decode a string with // arabic and devanagari characters. try { - decode("६१٧٥٥f6361646f73".toCharArray(), false); + decode("६१٧٥٥F6361646F73".toCharArray(), false); fail(); } catch (IllegalArgumentException expected) { } try { - decode("#%6361646f73".toCharArray(), false); + decode("#%6361646F73".toCharArray(), false); fail(); } catch (IllegalArgumentException expected) { } diff --git a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java index 9875647..a90bb8e 100644 --- a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java +++ b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java @@ -98,6 +98,13 @@ public class ZoneInfoDBTest extends junit.framework.TestCase { public void testMakeTimeZone_notFound() throws Exception { ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT); assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST")); + assertFalse(data.hasTimeZone("THIS_TZ_DOES_NOT_EXIST")); + } + + public void testMakeTimeZone_found() throws Exception { + ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT); + assertNotNull(data.makeTimeZone("Europe/London")); + assertTrue(data.hasTimeZone("Europe/London")); } private static String makeCorruptFile() throws Exception { diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java index e90452d..48d945b 100644 --- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java +++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java @@ -76,8 +76,13 @@ public class MacTest extends TestCase { static { for (int i = 0; i < validAlgorithmsMac.length; i++) { - defaultProvider = SpiEngUtils.isSupport(validAlgorithmsMac[i], - srvMac); + try { + Mac mac = Mac.getInstance(validAlgorithmsMac[i]); + mac.init(new SecretKeySpec(new byte[64], validAlgorithmsMac[i])); + defaultProvider = mac.getProvider(); + } catch (NoSuchAlgorithmException ignored) { + } catch (InvalidKeyException ignored) {} + DEFSupported = (defaultProvider != null); if (DEFSupported) { defaultAlgorithm = validAlgorithmsMac[i]; @@ -103,7 +108,7 @@ public class MacTest extends TestCase { // Do not test AndroidKeyStore's Mac. It cannot be initialized without providing an // AndroidKeyStore-backed SecretKey instance. It's OKish not to test here because it's // tested by cts/tests/test/keystore. - if ("AndroidKeyStore".equals(p.getName())) { + if (p.getName().startsWith("AndroidKeyStore")) { continue; } macList.add(Mac.getInstance(defaultAlgorithm, p)); @@ -854,7 +859,7 @@ public class MacTest extends TestCase { // Do not test AndroidKeyStore's Mac. It cannot be initialized without providing an // AndroidKeyStore-backed SecretKey instance. It's OKish not to test here because it's // tested by cts/tests/test/keystore. - if ("AndroidKeyStore".equals(providers[i].getName())) { + if (providers[i].getName().startsWith("AndroidKeyStore")) { continue; } diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java index ad084e1..22e6795 100644 --- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java +++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java @@ -478,17 +478,10 @@ public class Signature2Test extends junit.framework.TestCase { } catch (IllegalArgumentException expected) { } - if (StandardNames.IS_RI) { - try { - sig.verify(signature, signature.length, 0); - fail(); - } catch (SignatureException expected) { - } - } else { - // Calling Signature.verify a second time should not throw - // http://code.google.com/p/android/issues/detail?id=34933 - boolean verified = sig.verify(signature, signature.length, 0); - assertFalse(verified); + try { + sig.verify(signature, signature.length, 0); + fail(); + } catch (SignatureException expected) { } try { diff --git a/luni/src/test/java/tests/security/cert/CertificateTest.java b/luni/src/test/java/tests/security/cert/CertificateTest.java index d13e16b..194bfdb 100644 --- a/luni/src/test/java/tests/security/cert/CertificateTest.java +++ b/luni/src/test/java/tests/security/cert/CertificateTest.java @@ -300,17 +300,10 @@ public class MyModifiablePublicKey implements PublicKey { private Certificate cert; - private Provider wrongProvider; - - private Provider usefulProvider; - public void setUp() throws Exception { super.setUp(); TestUtils.initCertPathSSCertChain(); cert = TestUtils.rootCertificateSS; - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - wrongProvider = cf.getProvider(); - usefulProvider = Signature.getInstance("SHA1WithRSA").getProvider(); } /** @@ -326,8 +319,11 @@ public class MyModifiablePublicKey implements PublicKey { CertificateException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException { + final Signature sig = Signature.getInstance("SHA1WithRSA"); + sig.initVerify(cert.getPublicKey()); + final Provider provider = sig.getProvider(); // real test - cert.verify(cert.getPublicKey(), usefulProvider.getName()); + cert.verify(cert.getPublicKey(), provider.getName()); // Exception tests @@ -342,6 +338,9 @@ public class MyModifiablePublicKey implements PublicKey { // a new provider, test if it works, then remove it and test if the // exception is thrown. // + // CertificateFactory cf = CertificateFactory.getInstance("X.509"); + // Provider wrongProvider = cf.getProvider(); + // // Security.removeProvider(wrongProvider.getName()); // // try { diff --git a/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java b/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java index 6cebda5..5f4abdd 100644 --- a/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java +++ b/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java @@ -32,9 +32,7 @@ public class DSAPrivateKeyTest extends TestCase { */ public void test_getX() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); - keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G), - new SecureRandom(new MySecureRandomSpi(), null) { - }); + keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G), new SecureRandom()); KeyPair keyPair = keyGen.generateKeyPair(); DSAPrivateKey key = (DSAPrivateKey) keyPair.getPrivate(); assertNotNull("Invalid X value", key.getX()); diff --git a/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java b/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java index 9fe4910..09e936d 100644 --- a/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java +++ b/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java @@ -42,9 +42,7 @@ public class DSAPublicKeyTest extends TestCase { // Case 1: check with predefined p, q, g, x keyGen = KeyPairGenerator.getInstance("DSA"); - keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G), - new SecureRandom(new MySecureRandomSpi(), null) { - }); + keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G), new SecureRandom()); keys = keyGen.generateKeyPair(); priv = (DSAPrivateKey) keys.getPrivate(); publ = (DSAPublicKey) keys.getPublic(); diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java index 9aab942..cfd519a 100644 --- a/support/src/test/java/libcore/java/security/StandardNames.java +++ b/support/src/test/java/libcore/java/security/StandardNames.java @@ -180,7 +180,6 @@ public final class StandardNames extends Assert { provide("Cipher", "DES"); provide("Cipher", "DESede"); provide("Cipher", "DESedeWrap"); - provide("Cipher", "GCM"); provide("Cipher", "PBEWithMD5AndDES"); provide("Cipher", "PBEWithMD5AndTripleDES"); provide("Cipher", "PBEWithSHA1AndDESede"); @@ -394,12 +393,23 @@ public final class StandardNames extends Assert { provide("Signature", "NONEwithRSA"); provide("Cipher", "RSA/ECB/NOPADDING"); provide("Cipher", "RSA/ECB/PKCS1PADDING"); + provide("Cipher", "RSA/ECB/OAEPPadding"); + provide("Cipher", "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + provide("Cipher", "RSA/ECB/OAEPWithSHA-224AndMGF1Padding"); + provide("Cipher", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); + provide("Cipher", "RSA/ECB/OAEPWithSHA-384AndMGF1Padding"); + provide("Cipher", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); provide("SecretKeyFactory", "AES"); provide("SecretKeyFactory", "HmacSHA1"); provide("SecretKeyFactory", "HmacSHA224"); provide("SecretKeyFactory", "HmacSHA256"); provide("SecretKeyFactory", "HmacSHA384"); provide("SecretKeyFactory", "HmacSHA512"); + provide("Signature", "SHA1withRSA/PSS"); + provide("Signature", "SHA224withRSA/PSS"); + provide("Signature", "SHA256withRSA/PSS"); + provide("Signature", "SHA384withRSA/PSS"); + provide("Signature", "SHA512withRSA/PSS"); // different names: ARCFOUR vs ARC4 unprovide("Cipher", "ARCFOUR"); @@ -479,6 +489,7 @@ public final class StandardNames extends Assert { provide("Cipher", "AES/ECB/NOPADDING"); provide("Cipher", "AES/ECB/PKCS5PADDING"); provide("Cipher", "AES/ECB/PKCS7PADDING"); + provide("Cipher", "AES/GCM/NOPADDING"); provide("Cipher", "AES/OFB/NOPADDING"); provide("Cipher", "AES/OFB/PKCS5PADDING"); provide("Cipher", "AES/OFB/PKCS7PADDING"); @@ -714,30 +725,18 @@ public final class StandardNames extends Assert { addBoth( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"); addBoth( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"); addBoth( "TLS_RSA_WITH_AES_256_CBC_SHA"); - addBoth( "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); - addBoth( "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"); addBoth( "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"); addBoth( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"); addBoth( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"); addBoth( "TLS_RSA_WITH_AES_128_CBC_SHA"); - addBoth( "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"); - addBoth( "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"); addBoth( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); addBoth( "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"); addBoth( "TLS_ECDHE_RSA_WITH_RC4_128_SHA"); addBoth( "SSL_RSA_WITH_RC4_128_SHA"); - addBoth( "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"); - addBoth( "TLS_ECDH_RSA_WITH_RC4_128_SHA"); - addBoth( "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"); - addBoth( "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"); addBoth( "SSL_RSA_WITH_3DES_EDE_CBC_SHA"); - addBoth( "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"); - addBoth( "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"); - addBoth( "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); addBoth( "SSL_RSA_WITH_RC4_128_MD5"); // TLSv1.2 cipher suites - addBoth( "TLS_RSA_WITH_NULL_SHA256"); addBoth( "TLS_RSA_WITH_AES_128_CBC_SHA256"); addBoth( "TLS_RSA_WITH_AES_256_CBC_SHA256"); addOpenSsl("TLS_RSA_WITH_AES_128_GCM_SHA256"); @@ -746,14 +745,6 @@ public final class StandardNames extends Assert { addBoth( "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"); addOpenSsl("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"); addOpenSsl("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"); - addBoth( "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"); - addBoth( "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"); - addOpenSsl("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"); - addOpenSsl("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"); - addBoth( "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"); - addBoth( "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"); addBoth( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); addBoth( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"); addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); @@ -762,14 +753,9 @@ public final class StandardNames extends Assert { addBoth( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"); addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"); - addBoth( "TLS_DH_anon_WITH_AES_128_CBC_SHA256"); - addBoth( "TLS_DH_anon_WITH_AES_256_CBC_SHA256"); - addOpenSsl("TLS_DH_anon_WITH_AES_128_GCM_SHA256"); - addOpenSsl("TLS_DH_anon_WITH_AES_256_GCM_SHA384"); // Pre-Shared Key (PSK) cipher suites addOpenSsl("TLS_PSK_WITH_RC4_128_SHA"); - addOpenSsl("TLS_PSK_WITH_3DES_EDE_CBC_SHA"); addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA"); addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA"); addOpenSsl("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"); @@ -783,29 +769,6 @@ public final class StandardNames extends Assert { addOpenSsl(CIPHER_SUITE_FALLBACK); // non-defaultCipherSuites - addBoth( "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"); - addBoth( "TLS_DH_anon_WITH_AES_256_CBC_SHA"); - addBoth( "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"); - addBoth( "TLS_DH_anon_WITH_AES_128_CBC_SHA"); - addBoth( "TLS_ECDH_anon_WITH_RC4_128_SHA"); - addBoth( "SSL_DH_anon_WITH_RC4_128_MD5"); - addBoth( "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"); - addBoth( "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"); - addBoth( "TLS_ECDHE_ECDSA_WITH_NULL_SHA"); - addBoth( "TLS_ECDHE_RSA_WITH_NULL_SHA"); - addBoth( "SSL_RSA_WITH_NULL_SHA"); - addBoth( "TLS_ECDH_ECDSA_WITH_NULL_SHA"); - addBoth( "TLS_ECDH_RSA_WITH_NULL_SHA"); - addBoth( "TLS_ECDH_anon_WITH_NULL_SHA"); - addBoth( "SSL_RSA_WITH_NULL_MD5"); - addBoth( "SSL_RSA_WITH_DES_CBC_SHA"); - addBoth( "SSL_DHE_RSA_WITH_DES_CBC_SHA"); - addBoth( "SSL_DH_anon_WITH_DES_CBC_SHA"); - addBoth( "SSL_RSA_EXPORT_WITH_RC4_40_MD5"); - addBoth( "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"); - addBoth( "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"); - addBoth( "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"); - addBoth( "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"); // Android does not have Kerberos support addRi( "TLS_KRB5_WITH_RC4_128_SHA"); @@ -833,6 +796,54 @@ public final class StandardNames extends Assert { // Dropped addNeither("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"); addNeither("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"); + addRi( "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"); + addRi( "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "SSL_DHE_RSA_WITH_DES_CBC_SHA"); + addRi( "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"); + addRi( "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"); + addRi( "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"); + addRi( "SSL_DH_anon_WITH_DES_CBC_SHA"); + addRi( "SSL_DH_anon_WITH_RC4_128_MD5"); + addRi( "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"); + addRi( "SSL_RSA_EXPORT_WITH_RC4_40_MD5"); + addRi( "SSL_RSA_WITH_DES_CBC_SHA"); + addRi( "SSL_RSA_WITH_NULL_MD5"); + addRi( "SSL_RSA_WITH_NULL_SHA"); + addRi( "TLS_DH_anon_WITH_AES_128_CBC_SHA"); + addRi( "TLS_DH_anon_WITH_AES_128_CBC_SHA256"); + addNeither("TLS_DH_anon_WITH_AES_128_GCM_SHA256"); + addRi( "TLS_DH_anon_WITH_AES_256_CBC_SHA"); + addRi( "TLS_DH_anon_WITH_AES_256_CBC_SHA256"); + addNeither("TLS_DH_anon_WITH_AES_256_GCM_SHA384"); + addRi( "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "TLS_ECDHE_ECDSA_WITH_NULL_SHA"); + addRi( "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "TLS_ECDHE_RSA_WITH_NULL_SHA"); + addRi( "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"); + addRi( "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"); + addNeither("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"); + addRi( "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); + addRi( "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"); + addNeither("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"); + addRi( "TLS_ECDH_ECDSA_WITH_NULL_SHA"); + addRi( "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"); + addRi( "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"); + addRi( "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"); + addNeither("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"); + addRi( "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"); + addRi( "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"); + addNeither("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"); + addRi( "TLS_ECDH_RSA_WITH_NULL_SHA"); + addRi( "TLS_ECDH_RSA_WITH_RC4_128_SHA"); + addRi( "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"); + addRi( "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"); + addRi( "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"); + addRi( "TLS_ECDH_anon_WITH_NULL_SHA"); + addRi( "TLS_ECDH_anon_WITH_RC4_128_SHA"); + addNeither("TLS_PSK_WITH_3DES_EDE_CBC_SHA"); + addRi( "TLS_RSA_WITH_NULL_SHA256"); // Old non standard exportable encryption addNeither("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA"); diff --git a/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java b/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java index 6e2ff9d..b497c85 100644 --- a/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java +++ b/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java @@ -72,6 +72,8 @@ public final class ConfigBundle { // Validate the entry name: make sure the unpacked file will exist beneath the // targetDir. String name = entry.getName(); + // Note, we assume that nothing will quickly insert a symlink after createSubFile() + // that might invalidate the guarantees about name existing beneath targetDir. File entryFile = FileUtils.createSubFile(targetDir, name); if (entry.isDirectory()) { diff --git a/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java b/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java index 8b7da78..652b786 100644 --- a/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java +++ b/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java @@ -37,19 +37,18 @@ public final class FileUtils { /** * Creates a new {@link java.io.File} from the {@code parentDir} and {@code name}, but only if - * the - * resulting file would exist beneath {@code parentDir}. Useful if {@code name} could contain - * "/../" or symlinks. The returned object has an absolute path. + * the resulting file would exist beneath {@code parentDir}. Useful if {@code name} could + * contain "/../" or symlinks. The returned object has a canonicalized path. * - * @throws java.io.IOException - * if the file would not exist beneath {@code parentDir} + * @throws java.io.IOException if the file would not exist beneath {@code parentDir} */ public static File createSubFile(File parentDir, String name) throws IOException { // The subFile must exist beneath parentDir. If name contains "/../" this may not be the // case so we check. - File subFile = canonicalizeDirPath(new File(parentDir, name)); + File subFile = new File(parentDir, name).getCanonicalFile(); if (!subFile.getPath().startsWith(parentDir.getCanonicalPath())) { - throw new IOException(name + " must exist beneath " + parentDir); + throw new IOException(name + " must exist beneath " + parentDir + + ". Canonicalized subpath: " + subFile); } return subFile; } @@ -61,8 +60,8 @@ public final class FileUtils { * directories explicitly created will have their permissions set; existing directories are * untouched. * - * @throws IOException - * if the directory or one of its parents did not already exist and could not be created + * @throws IOException if the directory or one of its parents did not already exist and could + * not be created */ public static void ensureDirectoriesExist(File dir, boolean makeWorldReadable) throws IOException { @@ -87,14 +86,6 @@ public final class FileUtils { } } - /** - * Returns a file with all symlinks and relative paths such as "/../" resolved <em>except</em> - * for the base name (the last element of the path). Useful for detecting symlinks. - */ - public static File canonicalizeDirPath(File file) throws IOException { - return new File(file.getParentFile().getCanonicalFile(), file.getName()); - } - public static void makeDirectoryWorldAccessible(File directory) throws IOException { if (!directory.isDirectory()) { throw new IOException(directory + " must be a directory"); @@ -150,7 +141,10 @@ public final class FileUtils { } public static boolean isSymlink(File file) throws IOException { - return !file.getCanonicalPath().equals(canonicalizeDirPath(file).getPath()); + String baseName = file.getName(); + String canonicalPathExceptBaseName = + new File(file.getParentFile().getCanonicalFile(), baseName).getPath(); + return !file.getCanonicalPath().equals(canonicalPathExceptBaseName); } public static void deleteRecursive(File toDelete) throws IOException { diff --git a/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java b/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java index ce02bfe..d002820 100644 --- a/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java +++ b/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java @@ -113,21 +113,30 @@ public class FileUtilsTest extends TestCase { } public void testCreateSubFile() throws Exception { - File dir1 = createTempDir(); - File subFile = FileUtils.createSubFile(dir1, "file"); - assertFileCanonicalEquals(new File(dir1, "file"), subFile); + File dir1 = createTempDir().getCanonicalFile(); + + File actualSubFile = FileUtils.createSubFile(dir1, "file"); + assertEquals(new File(dir1, "file"), actualSubFile); + + File existingSubFile = createRegularFile(dir1, "file"); + actualSubFile = FileUtils.createSubFile(dir1, "file"); + assertEquals(existingSubFile, actualSubFile); + + File existingSubDir = createDir(dir1, "subdir"); + actualSubFile = FileUtils.createSubFile(dir1, "subdir"); + assertEquals(existingSubDir, actualSubFile); assertCreateSubFileThrows(dir1, "../file"); assertCreateSubFileThrows(dir1, "../../file"); assertCreateSubFileThrows(dir1, "../otherdir/file"); - File dir2 = createTempDir(); - File dir2Subdir = createDir(dir2, "dir2Subdir"); - File expectedSymlinkToDir2 = createSymlink(dir2Subdir, dir1, "symlinkToDir2"); + File dir2 = createTempDir().getCanonicalFile(); + createSymlink(dir2, dir1, "symlinkToDir2"); + assertCreateSubFileThrows(dir1, "symlinkToDir2"); - File actualSymlinkToDir2 = FileUtils.createSubFile(dir1, "symlinkToDir2"); - assertEquals(expectedSymlinkToDir2, actualSymlinkToDir2); + assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir"); + createRegularFile(dir1, "symlinkToDir2/fileInSymlinkedDir"); assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir"); } @@ -295,10 +304,6 @@ public class FileUtilsTest extends TestCase { (sb.st_mode & mask) == mask); } - private static void assertFileCanonicalEquals(File expected, File actual) throws IOException { - assertEquals(expected.getCanonicalFile(), actual.getCanonicalFile()); - } - private File createTempDir() { final String tempPrefix = getClass().getSimpleName(); File tempDir = IoUtils.createTemporaryDirectory(tempPrefix); diff --git a/tzdata/update_test_app/AndroidManifest.xml b/tzdata/update_test_app/AndroidManifest.xml index 67a8450..081aae5 100644 --- a/tzdata/update_test_app/AndroidManifest.xml +++ b/tzdata/update_test_app/AndroidManifest.xml @@ -2,8 +2,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="libcore.tzdata.update_test_app.installupdatetestapp" > - <uses-permission android:name="android.permission.WRITE_SETTINGS" /> - <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> + <uses-permission android:name="android.permission.UPDATE_CONFIG" /> <application android:allowBackup="false" diff --git a/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java b/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java index f9d911b..2348e43 100644 --- a/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java +++ b/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java @@ -29,17 +29,12 @@ import android.widget.Button; import android.widget.EditText; import android.widget.TextView; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.spec.PKCS8EncodedKeySpec; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -47,45 +42,9 @@ import java.util.concurrent.Executors; public class MainActivity extends Activity implements View.OnClickListener { - private static final String UPDATE_CERTIFICATE_KEY = "config_update_certificate"; private static final String EXTRA_REQUIRED_HASH = "REQUIRED_HASH"; - private static final String EXTRA_SIGNATURE = "SIGNATURE"; private static final String EXTRA_VERSION_NUMBER = "VERSION"; - public static final String TEST_CERT = "" + - "MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" + - "MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" + - "Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" + - "AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" + - "mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" + - "ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" + - "bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" + - "A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" + - "E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" + - "sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" + - "L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" + - "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" + - "MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" + - "cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" + - "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" + - "orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" + - "mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM="; - - - public static final String TEST_KEY = "" + - "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKMYYcBMFiWZqz7SwQQKSejwtnUo" + - "+CVv+Z97pWkJPcaFKv7tuvs0b9nAZmcSEuoTtggfh/GW0eZALdPP6MzVg36QxpCBFGOj8sEIl04p" + - "ozBRuRXKcAfo5iwp6+Os4+TyV8zlIVDMkwawD35N+imvnGDQHBnW8D/4TeYTtOvczZS/AgMBAAEC" + - "gYBxwFalNSwZK3WJipq+g6KLCiBn1JxGGDQlLKrweFaSuFyFky9fd3IvkIabirqQchD612sMb+GT" + - "0t1jptW6z4w2w6++IW0A3apDOCwoD+uvDBXrbFqI0VbyAWUNqHVdaFFIRk2IHGEE6463mGRdmILX" + - "IlCd/85RTHReg4rl/GFqWQJBANgLAIR4pWbl5Gm+DtY18wp6Q3pJAAMkmP/lISCBIidu1zcqYIKt" + - "PoDW4Knq9xnhxPbXrXKv4YzZWHBK8GkKhQ0CQQDBQnXufQcMew+PwiS0oJvS+eQ6YJwynuqG2ejg" + - "WE+T7489jKtscRATpUXpZUYmDLGg9bLt7L62hFvFSj2LO2X7AkBcdrD9AWnBFWlh/G77LVHczSEu" + - "KCoyLiqxcs5vy/TjLaQ8vw1ZQG580/qJnr+tOxyCjSJ18GK3VppsTRaBznfNAkB3nuCKNp9HTWCL" + - "dfrsRsFMrFpk++mSt6SoxXaMbn0LL2u1CD4PCEiQMGt+lK3/3TmRTKNs+23sYS7Ahjxj0udDAkEA" + - "p57Nj65WNaWeYiOfTwKXkLj8l29H5NbaGWxPT0XkWr4PvBOFZVH/wj0/qc3CMVGnv11+DyO+QUCN" + - "SqBB5aRe8g=="; - private EditText actionEditText; private EditText versionEditText; private EditText contentPathEditText; @@ -137,27 +96,10 @@ public class MainActivity extends Activity implements View.OnClickListener { } publishProgress("Created copy of " + contentFile + " at " + copyOfContentFile); - String originalCert = null; try { - originalCert = overrideCert(TEST_CERT); - sleep(1000); - publishProgress("Overridden update cert"); - - String signature = createSignature(copyOfContentFile, version, requiredHash); - sendIntent(copyOfContentFile, action, version, requiredHash, signature); - publishProgress("Sent update intent"); + sendIntent(copyOfContentFile, action, version, requiredHash); } catch (Exception e) { publishProgress("Error", exceptionToString(e)); - } finally { - if (originalCert != null) { - sleep(1000); - try { - overrideCert(originalCert); - publishProgress("Reverted update cert"); - } catch (Exception e) { - publishProgress("Unable to revert update cert", exceptionToString(e)); - } - } } publishProgress("Update intent sent successfully"); return null; @@ -172,15 +114,6 @@ public class MainActivity extends Activity implements View.OnClickListener { }.executeOnExecutor(executor); } - private String overrideCert(String cert) throws Exception { - final String key = UPDATE_CERTIFICATE_KEY; - String originalCert = Settings.Secure.getString(getContentResolver(), key); - if (!Settings.Secure.putString(getContentResolver(), key, cert)) { - throw new Exception("Unable to override update certificate"); - } - return originalCert; - } - private void sleep(long millisDelay) { try { Thread.sleep(millisDelay); @@ -190,7 +123,7 @@ public class MainActivity extends Activity implements View.OnClickListener { } private void sendIntent( - File contentFile, String action, String version, String required, String sig) { + File contentFile, String action, String version, String required) { Intent i = new Intent(); i.setAction(action); Uri contentUri = @@ -201,7 +134,6 @@ public class MainActivity extends Activity implements View.OnClickListener { i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); i.putExtra(EXTRA_VERSION_NUMBER, version); i.putExtra(EXTRA_REQUIRED_HASH, required); - i.putExtra(EXTRA_SIGNATURE, sig); sendBroadcast(i); } @@ -220,36 +152,6 @@ public class MainActivity extends Activity implements View.OnClickListener { logView.scrollTo(0, scrollAmount); } - private static String createSignature(File contentFile, String version, String requiredHash) - throws Exception { - byte[] contentBytes = readBytes(contentFile); - Signature signer = Signature.getInstance("SHA512withRSA"); - signer.initSign(createKey()); - signer.update(contentBytes); - signer.update(version.trim().getBytes()); - signer.update(requiredHash.getBytes()); - return new String(Base64.encode(signer.sign(), Base64.DEFAULT)); - } - - private static byte[] readBytes(File contentFile) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (FileInputStream fis = new FileInputStream(contentFile)) { - int count; - byte[] buffer = new byte[8192]; - while ((count = fis.read(buffer)) != -1) { - baos.write(buffer, 0, count); - } - } - return baos.toByteArray(); - } - - private static PrivateKey createKey() throws Exception { - byte[] derKey = Base64.decode(TEST_KEY.getBytes(), Base64.DEFAULT); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(derKey); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(keySpec); - } - private static String exceptionToString(Exception e) { StringWriter writer = new StringWriter(); e.printStackTrace(new PrintWriter(writer)); |