summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NativeCode.mk6
-rw-r--r--benchmarks/src/benchmarks/regression/ProviderBenchmark.java50
-rw-r--r--dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java18
-rw-r--r--dalvik/src/main/java/dalvik/system/DexFile.java4
-rw-r--r--dalvik/src/main/java/dalvik/system/DexPathList.java193
-rw-r--r--dalvik/src/main/java/dalvik/system/StaleDexCacheError.java41
-rw-r--r--expectations/knownfailures.txt17
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java5
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java57
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java21
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java13
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java43
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java37
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java51
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java49
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNonFairTest.java (renamed from jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java)2
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java118
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java66
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java19
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java28
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java19
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java19
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java28
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicLongTest.java19
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java17
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java21
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java32
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java19
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java17
-rw-r--r--jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java239
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java79
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java56
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java51
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java72
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java22
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java92
-rw-r--r--jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java280
-rw-r--r--jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java102
-rw-r--r--jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java17
-rw-r--r--jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java42
-rw-r--r--jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java17
-rw-r--r--jsr166-tests/src/test/java/jsr166/DelayQueueTest.java106
-rw-r--r--jsr166-tests/src/test/java/jsr166/EntryTest.java16
-rw-r--r--jsr166-tests/src/test/java/jsr166/ExchangerTest.java18
-rw-r--r--jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java24
-rw-r--r--jsr166-tests/src/test/java/jsr166/ExecutorsTest.java37
-rw-r--r--jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java47
-rw-r--r--jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java46
-rw-r--r--jsr166-tests/src/test/java/jsr166/FutureTaskTest.java57
-rw-r--r--jsr166-tests/src/test/java/jsr166/JSR166TestCase.java202
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java120
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java91
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedListTest.java45
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java72
-rw-r--r--jsr166-tests/src/test/java/jsr166/LockSupportTest.java16
-rw-r--r--jsr166-tests/src/test/java/jsr166/PhaserTest.java21
-rw-r--r--jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java105
-rw-r--r--jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java50
-rw-r--r--jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java28
-rw-r--r--jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java21
-rw-r--r--jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java58
-rw-r--r--jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java51
-rw-r--r--jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java97
-rw-r--r--jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java92
-rw-r--r--jsr166-tests/src/test/java/jsr166/SemaphoreTest.java22
-rw-r--r--jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java53
-rw-r--r--jsr166-tests/src/test/java/jsr166/SystemTest.java12
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java134
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java15
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java43
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java39
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadTest.java48
-rw-r--r--jsr166-tests/src/test/java/jsr166/TimeUnitTest.java245
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeMapTest.java37
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeSetTest.java70
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java35
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java87
-rw-r--r--libart/src/main/java/dalvik/system/VMRuntime.java25
-rw-r--r--libart/src/main/java/java/lang/AbstractStringBuilder.java (renamed from luni/src/main/java/java/lang/AbstractStringBuilder.java)19
-rw-r--r--libart/src/main/java/java/lang/CaseMapper.java (renamed from luni/src/main/java/java/lang/CaseMapper.java)76
-rw-r--r--libart/src/main/java/java/lang/Class.java23
-rw-r--r--libart/src/main/java/java/lang/Daemons.java10
-rw-r--r--libart/src/main/java/java/lang/DexCache.java3
-rw-r--r--libart/src/main/java/java/lang/String.java506
-rw-r--r--libart/src/main/java/java/lang/StringFactory.java251
-rw-r--r--libart/src/main/java/java/lang/reflect/AbstractMethod.java3
-rw-r--r--libart/src/main/java/java/lang/reflect/ArtMethod.java78
-rw-r--r--luni/src/main/files/cacerts/0d188d89.080
-rw-r--r--luni/src/main/files/cacerts/0d5a4e1c.082
-rw-r--r--luni/src/main/files/cacerts/2afc57aa.091
-rw-r--r--luni/src/main/files/cacerts/2fb1850a.0124
-rw-r--r--luni/src/main/files/cacerts/3c6676aa.0120
-rw-r--r--luni/src/main/files/cacerts/4be590e0.0120
-rw-r--r--luni/src/main/files/cacerts/5021a0a2.084
-rw-r--r--luni/src/main/files/cacerts/5a250ea7.0120
-rw-r--r--luni/src/main/files/cacerts/6645de82.082
-rw-r--r--luni/src/main/files/cacerts/72fa7371.054
-rw-r--r--luni/src/main/files/cacerts/74c26bd0.060
-rw-r--r--luni/src/main/files/cacerts/7a481e66.091
-rw-r--r--luni/src/main/files/cacerts/9282e51c.0123
-rw-r--r--luni/src/main/files/cacerts/bda4cc84.082
-rw-r--r--luni/src/main/files/cacerts/c33a80d4.058
-rw-r--r--luni/src/main/files/cacerts/d18e9066.0120
-rw-r--r--luni/src/main/files/cacerts/d6e6eab9.0123
-rw-r--r--luni/src/main/files/cacerts/ddc328ff.057
-rw-r--r--luni/src/main/files/cacerts/e7b8d656.060
-rw-r--r--luni/src/main/files/cacerts/eb375c3e.077
-rw-r--r--luni/src/main/java/android/system/Os.java6
-rw-r--r--luni/src/main/java/android/system/OsConstants.java24
-rw-r--r--luni/src/main/java/java/lang/IllegalAccessError.java10
-rw-r--r--luni/src/main/java/java/lang/Runtime.java26
-rw-r--r--luni/src/main/java/java/lang/System.java32
-rw-r--r--luni/src/main/java/java/lang/ref/FinalizerReference.java21
-rw-r--r--luni/src/main/java/java/net/HttpURLConnection.java20
-rw-r--r--luni/src/main/java/java/security/Provider.java4
-rw-r--r--luni/src/main/java/java/security/Signature.java57
-rw-r--r--luni/src/main/java/java/text/DecimalFormatSymbols.java52
-rw-r--r--luni/src/main/java/java/util/ComparableTimSort.java27
-rw-r--r--luni/src/main/java/java/util/Date.java22
-rw-r--r--luni/src/main/java/java/util/List.java7
-rw-r--r--luni/src/main/java/java/util/Locale.java38
-rw-r--r--luni/src/main/java/java/util/TimSort.java28
-rw-r--r--luni/src/main/java/java/util/concurrent/AbstractExecutorService.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java161
-rw-r--r--luni/src/main/java/java/util/concurrent/BlockingDeque.java10
-rw-r--r--luni/src/main/java/java/util/concurrent/BlockingQueue.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java425
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java6
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentMap.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java11
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/CountDownLatch.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/CountedCompleter.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/CyclicBarrier.java3
-rw-r--r--luni/src/main/java/java/util/concurrent/DelayQueue.java3
-rw-r--r--luni/src/main/java/java/util/concurrent/Exchanger.java3
-rw-r--r--luni/src/main/java/java/util/concurrent/Executor.java6
-rw-r--r--luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/ExecutorService.java5
-rw-r--r--luni/src/main/java/java/util/concurrent/Executors.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ForkJoinPool.java13
-rw-r--r--luni/src/main/java/java/util/concurrent/ForkJoinTask.java18
-rw-r--r--luni/src/main/java/java/util/concurrent/FutureTask.java106
-rw-r--r--luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java7
-rw-r--r--luni/src/main/java/java/util/concurrent/Phaser.java6
-rw-r--r--luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/RecursiveTask.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java8
-rw-r--r--luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java122
-rw-r--r--luni/src/main/java/java/util/concurrent/Semaphore.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/SynchronousQueue.java10
-rw-r--r--luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java4
-rw-r--r--luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java5
-rw-r--r--luni/src/main/java/java/util/concurrent/TimeUnit.java73
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java5
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java4
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java12
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java16
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java25
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java25
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/Condition.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/Lock.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/LockSupport.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java9
-rw-r--r--luni/src/main/java/java/util/concurrent/package-info.java34
-rw-r--r--luni/src/main/java/java/util/zip/Zip64.java74
-rw-r--r--luni/src/main/java/java/util/zip/ZipEntry.java3
-rw-r--r--luni/src/main/java/java/util/zip/ZipOutputStream.java6
-rw-r--r--luni/src/main/java/javax/crypto/Cipher.java303
-rw-r--r--luni/src/main/java/javax/crypto/KeyAgreement.java61
-rw-r--r--luni/src/main/java/javax/crypto/Mac.java62
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLEngine.java364
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSocket.java372
-rw-r--r--luni/src/main/java/libcore/icu/DateIntervalFormat.java2
-rw-r--r--luni/src/main/java/libcore/io/ForwardingOs.java3
-rw-r--r--luni/src/main/java/libcore/io/Os.java3
-rw-r--r--luni/src/main/java/libcore/io/Posix.java3
-rw-r--r--luni/src/main/java/libcore/util/CharsetUtils.java26
-rw-r--r--luni/src/main/java/libcore/util/HexEncoding.java2
-rw-r--r--luni/src/main/java/libcore/util/ZoneInfoDB.java4
-rw-r--r--luni/src/main/java/org/apache/harmony/security/fortress/Engine.java6
-rw-r--r--luni/src/main/java/org/apache/harmony/security/fortress/Services.java89
-rw-r--r--luni/src/main/native/Register.cpp1
-rw-r--r--luni/src/main/native/android_system_OsConstants.cpp4
-rw-r--r--luni/src/main/native/java_lang_RealToString.cpp4
-rw-r--r--luni/src/main/native/java_util_jar_StrictJarFile.cpp1
-rw-r--r--luni/src/main/native/libcore_icu_ICU.cpp9
-rw-r--r--luni/src/main/native/libcore_io_Posix.cpp63
-rw-r--r--luni/src/main/native/libcore_util_CharsetUtils.cpp250
-rw-r--r--luni/src/main/native/sub.mk1
-rw-r--r--luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java15
-rw-r--r--luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java23
-rw-r--r--luni/src/test/java/libcore/icu/DateIntervalFormatTest.java9
-rw-r--r--luni/src/test/java/libcore/icu/ICUTest.java3
-rw-r--r--luni/src/test/java/libcore/io/OsTest.java56
-rw-r--r--luni/src/test/java/libcore/java/lang/OldSystemTest.java8
-rw-r--r--luni/src/test/java/libcore/java/lang/StringTest.java41
-rw-r--r--luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java50
-rw-r--r--luni/src/test/java/libcore/java/security/ProviderTest.java22
-rw-r--r--luni/src/test/java/libcore/java/security/SecureRandomTest.java1
-rw-r--r--luni/src/test/java/libcore/java/security/SignatureTest.java88
-rw-r--r--luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java7
-rw-r--r--luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java30
-rw-r--r--luni/src/test/java/libcore/java/util/DateTest.java11
-rw-r--r--luni/src/test/java/libcore/java/util/LocaleTest.java34
-rw-r--r--luni/src/test/java/libcore/java/util/TimSortTest.java82
-rw-r--r--luni/src/test/java/libcore/java/util/zip/Zip64Test.java100
-rw-r--r--luni/src/test/java/libcore/javax/crypto/CipherTest.java559
-rw-r--r--luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java23
-rw-r--r--luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java27
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MacTest.java62
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java87
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MockKey.java2
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MockMacSpi.java92
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java49
-rw-r--r--luni/src/test/java/libcore/util/HexEncodingTest.java10
-rw-r--r--luni/src/test/java/libcore/util/ZoneInfoDBTest.java7
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java13
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java15
-rw-r--r--luni/src/test/java/tests/security/cert/CertificateTest.java15
-rw-r--r--luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java4
-rw-r--r--luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java4
-rw-r--r--support/src/test/java/libcore/java/security/StandardNames.java109
-rw-r--r--tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java2
-rw-r--r--tzdata/update/src/main/libcore/tzdata/update/FileUtils.java30
-rw-r--r--tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java29
-rw-r--r--tzdata/update_test_app/AndroidManifest.xml3
-rw-r--r--tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java102
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 &lt;init&gt; 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 &lt;init&gt; 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.&lt;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>
+ * {&lt;algorithm&gt;, &lt;mode&gt;, &lt;padding&gt;}
+ * </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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
- * <td>9+</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;19</td>
* </tr>
* <tr>
* <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
* <td>9+</td>
- * <td>9-19</td>
+ * <td>9&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_RSA_WITH_DES_CBC_SHA</td>
- * <td>9+</td>
- * <td>9-19</td>
+ * <td>9&ndash;22</td>
+ * <td>9&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_RSA_WITH_NULL_MD5</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_RSA_WITH_NULL_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
* <tr>
* <td>SSL_RSA_WITH_RC4_128_MD5</td>
* <td>9+</td>
- * <td>9-19</td>
+ * <td>9&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>9&ndash;22</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
- * <td>20-22</td>
+ * <td>20&ndash;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&ndash;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&ndash;22</td>
+ * <td>20&ndash;22</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
- * <td>20-22</td>
+ * <td>20&ndash;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&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;8</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
- * <td>1-8</td>
+ * <td>1&ndash;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&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_DSS_WITH_DES_CBC_SHA</td>
- * <td>1-8</td>
+ * <td>1&ndash;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&ndash;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&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_RSA_WITH_DES_CBC_SHA</td>
- * <td>1-8</td>
+ * <td>1&ndash;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&ndash;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&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_DES_CBC_SHA</td>
- * <td>1-8</td>
+ * <td>1&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;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&ndash;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&ndash;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&ndash;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&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
- * <td>20+</td>
+ * <td>20&ndash;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&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
- * <td>21+</td>
+ * <td>21&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;8</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_RSA_WITH_NULL_MD5</td>
- * <td>1-8</td>
+ * <td>1&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_RSA_WITH_NULL_SHA</td>
- * <td>1-8</td>
+ * <td>1&ndash;8</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_RSA_WITH_NULL_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
- * <td>9+</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;19</td>
* </tr>
* <tr>
* <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
* <td>9+</td>
- * <td>9-19</td>
+ * <td>9&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_RSA_WITH_DES_CBC_SHA</td>
- * <td>9+</td>
- * <td>9-19</td>
+ * <td>9&ndash;22</td>
+ * <td>9&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_RSA_WITH_NULL_MD5</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>SSL_RSA_WITH_NULL_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
* <tr>
* <td>SSL_RSA_WITH_RC4_128_MD5</td>
* <td>9+</td>
- * <td>9-19</td>
+ * <td>9&ndash;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&ndash;22</td>
+ * <td>9&ndash;22</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
- * <td>20-22</td>
+ * <td>20&ndash;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&ndash;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&ndash;22</td>
+ * <td>11&ndash;22</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
- * <td>20-22</td>
+ * <td>20&ndash;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&ndash;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&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
- * <td>9+</td>
+ * <td>9&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;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&ndash;22</td>
+ * <td>11&ndash;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&ndash;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&ndash;22</td>
+ * <td>11&ndash;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&ndash;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&ndash;22</td>
+ * <td>11&ndash;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&ndash;22</td>
+ * <td>11&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;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&ndash;22</td>
+ * <td>11&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;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&ndash;22</td>
+ * <td>11&ndash;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&ndash;22</td>
+ * <td>11&ndash;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&ndash;22</td>
+ * <td>11&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
- * <td>20+</td>
+ * <td>20&ndash;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&ndash;22</td>
+ * <td>11&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
- * <td>20+</td>
+ * <td>20&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;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&ndash;22</td>
+ * <td>11&ndash;19</td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;22</td>
* <td></td>
* </tr>
- * <tr>
+ * <tr class="deprecated">
* <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
- * <td>11+</td>
+ * <td>11&ndash;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&ndash;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&ndash;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&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;8, 11&ndash;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&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;22</td>
+ * <td>1&ndash;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&ndash;8</td>
+ * <td>1&ndash;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&ndash;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));