Merge "Remove IoUtils#deleteContents from CorePlatformApi set"
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 4837be7..5fcdd4c 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -649,11 +649,9 @@
"harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/*.java",
"luni/src/test/java/libcore/javax/crypto/**/*.java",
"luni/src/test/java/libcore/javax/net/ssl/**/*.java",
+ "luni/src/test/java/libcore/libcore/util/SerializationTester.java",
"luni/src/test/java/org/apache/harmony/crypto/**/*.java",
],
- exclude_srcs: [
- "luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java",
- ],
java_resource_dirs: [
"luni/src/test/java",
diff --git a/NativeCode.bp b/NativeCode.bp
index dac2387..228a284 100644
--- a/NativeCode.bp
+++ b/NativeCode.bp
@@ -202,10 +202,6 @@
"liblog",
"libnativehelper",
],
-
- strip: {
- keep_symbols: true,
- },
}
// Set of gtest unit tests.
diff --git a/OWNERS b/OWNERS
index 2de3abb..56d718b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -6,7 +6,6 @@
# People who can approve changes for submission; don't send review emails to them
# unless you know what you're doing.
dauletz@google.com
-mast@google.com
mingaleev@google.com
nfuller@google.com
nikitai@google.com
diff --git a/api/current.txt b/api/current.txt
index 659c529..d91a31b 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -46,6 +46,7 @@
method public static int getpid();
method public static int getppid();
method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException;
+ method @Nullable public static android.system.StructLinger getsockoptLinger(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
method @NonNull public static android.system.StructTimeval getsockoptTimeval(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
method public static int gettid();
method public static int getuid();
@@ -100,6 +101,7 @@
method @Deprecated public static void setgid(int) throws android.system.ErrnoException;
method public static int setsid() throws android.system.ErrnoException;
method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException;
+ method public static void setsockoptLinger(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructLinger) throws android.system.ErrnoException;
method public static void setsockoptTimeval(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructTimeval) throws android.system.ErrnoException;
method @Deprecated public static void setuid(int) throws android.system.ErrnoException;
method public static void setxattr(String, String, byte[], int) throws android.system.ErrnoException;
@@ -651,6 +653,13 @@
field public final int cmsg_type;
}
+ public final class StructLinger {
+ ctor public StructLinger(int, int);
+ method public boolean isOn();
+ field public final int l_linger;
+ field public final int l_onoff;
+ }
+
public final class StructMsghdr {
ctor public StructMsghdr(@Nullable java.net.SocketAddress, @NonNull java.nio.ByteBuffer[], @Nullable android.system.StructCmsghdr[], int);
field @Nullable public android.system.StructCmsghdr[] msg_control;
@@ -2962,7 +2971,7 @@
method public static void enable();
}
- @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE}) public @interface Deprecated {
+ @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE, java.lang.annotation.ElementType.MODULE, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE}) public @interface Deprecated {
method public abstract boolean forRemoval() default false;
method public abstract String since() default "";
}
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index afbc9ec..aef8adf 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -29,6 +29,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
import sun.misc.CompoundEnumeration;
/**
@@ -228,7 +230,7 @@
*/
@UnsupportedAppUsage
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public void addDexPath(String dexPath) {
+ public void addDexPath(@Nullable String dexPath) {
addDexPath(dexPath, false /*isTrusted*/);
}
@@ -249,7 +251,7 @@
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public void addNativePath(Collection<String> libPaths) {
+ public void addNativePath(@NonNull Collection<String> libPaths) {
pathList.addNativePath(libPaths);
}
@@ -345,7 +347,7 @@
*/
@UnsupportedAppUsage
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public String getLdLibraryPath() {
+ public @NonNull String getLdLibraryPath() {
StringBuilder result = new StringBuilder();
for (File directory : pathList.getNativeLibraryDirectories()) {
if (result.length() > 0) {
@@ -366,11 +368,11 @@
* Once set, all new instances of BaseDexClassLoader will report upon
* constructions the loaded dex files.
*
- * @param newReporter the new Reporter. Setting null will cancel reporting.
+ * @param newReporter the new Reporter. Setting {@code null} will cancel reporting.
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public static void setReporter(Reporter newReporter) {
+ public static void setReporter(@Nullable Reporter newReporter) {
reporter = newReporter;
}
@@ -400,6 +402,6 @@
* each dex file.
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- void report(Map<String, String> contextsMap);
+ void report(@NonNull Map<String, String> contextsMap);
}
}
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index 93a4865..a4ad9ce 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -118,7 +118,7 @@
* for reading or writing.
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- void onPathAccess(String path);
+ void onPathAccess(@NonNull String path);
}
/**
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 149f757..a705e24 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -41,6 +41,7 @@
* startAllocCounting to the trace key file.
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ // Must match android.os.Debug.TRACE_COUNT_ALLOCS.
public static final int TRACE_COUNT_ALLOCS = 1;
/* constants for getAllocCount */
@@ -496,6 +497,8 @@
runtimeStatsMap.put("art.gc.blocking-gc-time", 5);
runtimeStatsMap.put("art.gc.gc-count-rate-histogram", 6);
runtimeStatsMap.put("art.gc.blocking-gc-count-rate-histogram", 7);
+ runtimeStatsMap.put("art.gc.objects-allocated", 8);
+ runtimeStatsMap.put("art.gc.total-time-waiting-for-gc", 9);
}
/**
diff --git a/json/src/main/java/org/json/JSONObject.java b/json/src/main/java/org/json/JSONObject.java
index 40d15bb..2a2df62 100644
--- a/json/src/main/java/org/json/JSONObject.java
+++ b/json/src/main/java/org/json/JSONObject.java
@@ -674,11 +674,13 @@
*
* See {@link #keys()}.
*
+ * @return set of keys in this object
+ *
* @hide.
*/
@UnsupportedAppUsage
- @libcore.api.CorePlatformApi
- public Set<String> keySet() {
+ @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @NonNull public Set<@NonNull String> keySet() {
return nameValuePairs.keySet();
}
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 4a26c4b..21b035b 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -186,6 +186,7 @@
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ // Must match android.os.Build.VERSION_CODES.CUR_DEVELOPMENT.
public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
private static Consumer<String> nonSdkApiUsageConsumer = null;
@@ -651,7 +652,6 @@
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public native void requestConcurrentGC();
- public native void concurrentGC();
public native void requestHeapTrim();
public native void trimHeap();
public native void startHeapTaskProcessor();
diff --git a/luni/src/main/java/android/compat/Compatibility.java b/luni/src/main/java/android/compat/Compatibility.java
index 5d472bb..317ed07 100644
--- a/luni/src/main/java/android/compat/Compatibility.java
+++ b/luni/src/main/java/android/compat/Compatibility.java
@@ -25,6 +25,7 @@
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
+import libcore.util.NonNull;
/**
* Internal APIs for logging and gating compatibility changes.
@@ -55,8 +56,8 @@
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
@IntraCoreApi
- public static void reportChange(@ChangeId long changeId) {
- sCallbacks.reportChange(changeId);
+ public static void reportUnconditionalChange(@ChangeId long changeId) {
+ sCallbacks.onChangeReported(changeId);
}
/**
@@ -68,7 +69,7 @@
* {@code false}, the calling code should behave as it did in earlier releases.
*
* <p>When this method returns {@code true}, it will also report the change as
- * {@link #reportChange(long)} would, so there is no need to call that method directly.
+ * {@link #reportUnconditionalChange(long)} would, so there is no need to call that method directly.
*
* @param changeId The ID of the compatibility change in question.
* @return {@code true} if the change is enabled for the current app.
@@ -79,13 +80,32 @@
return sCallbacks.isChangeEnabled(changeId);
}
- private volatile static Callbacks sCallbacks = new Callbacks();
+ private static final BehaviorChangeDelegate DEFAULT_CALLBACKS = new BehaviorChangeDelegate(){};
+ private volatile static BehaviorChangeDelegate sCallbacks = DEFAULT_CALLBACKS;
+
+ /**
+ * Sets the behavior change delegate.
+ *
+ * All changes reported via the {@link Compatibility} class will be forwarded to this class.
+ */
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public static void setCallbacks(Callbacks callbacks) {
+ public static void setBehaviorChangeDelegate(BehaviorChangeDelegate callbacks) {
sCallbacks = Objects.requireNonNull(callbacks);
}
+ /**
+ * Removes a behavior change delegate previously set via {@link #setBehaviorChangeDelegate}.
+ */
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+ public static void clearBehaviorChangeDelegate() {
+ sCallbacks = DEFAULT_CALLBACKS;
+ }
+
+ /**
+ * For use by tests only. Causes values from {@code overrides} to be returned instead of the
+ * real value.
+ */
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static void setOverrides(ChangeConfig overrides) {
// Setting overrides twice in a row does not need to be supported because
@@ -99,6 +119,9 @@
sCallbacks = new OverrideCallbacks(sCallbacks, overrides);
}
+ /**
+ * For use by tests only. Removes overrides set by {@link #setOverrides}.
+ */
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static void clearOverrides() {
if (!(sCallbacks instanceof OverrideCallbacks)) {
@@ -115,17 +138,21 @@
* breaking @CorePlatformApi binary compatibility.
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public static class Callbacks {
+ public interface BehaviorChangeDelegate {
+ /**
+ * Called when a change is reported via {@link Compatibility#reportUnconditionalChange}
+ */
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- protected Callbacks() {
- }
- @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- protected void reportChange(long changeId) {
+ default void onChangeReported(long changeId) {
// Do not use String.format here (b/160912695)
System.logW("No Compatibility callbacks set! Reporting change " + changeId);
}
+
+ /**
+ * Called when a change is queried via {@link Compatibility#isChangeEnabled}
+ */
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- protected boolean isChangeEnabled(long changeId) {
+ default boolean isChangeEnabled(long changeId) {
// Do not use String.format here (b/160912695)
System.logW("No Compatibility callbacks set! Querying change " + changeId);
return true;
@@ -138,7 +165,7 @@
private final Set<Long> enabled;
private final Set<Long> disabled;
- public ChangeConfig(Set<Long> enabled, Set<Long> disabled) {
+ public ChangeConfig(@NonNull Set<@NonNull Long> enabled, @NonNull Set<@NonNull Long> disabled) {
this.enabled = Objects.requireNonNull(enabled);
this.disabled = Objects.requireNonNull(disabled);
if (enabled.contains(null)) {
@@ -168,19 +195,19 @@
return result;
}
- public long[] forceEnabledChangesArray() {
+ public @NonNull long[] getEnabledChangesArray() {
return toLongArray(enabled);
}
- public long[] forceDisabledChangesArray() {
+ public @NonNull long[] getDisabledChangesArray() {
return toLongArray(disabled);
}
- public Set<Long> forceEnabledSet() {
+ public @NonNull Set<@NonNull Long> getEnabledSet() {
return Collections.unmodifiableSet(enabled);
}
- public Set<Long> forceDisabledSet() {
+ public @NonNull Set<@NonNull Long> getDisabledSet() {
return Collections.unmodifiableSet(disabled);
}
@@ -214,16 +241,16 @@
}
}
- private static class OverrideCallbacks extends Callbacks {
- private final Callbacks delegate;
+ private static class OverrideCallbacks implements BehaviorChangeDelegate {
+ private final BehaviorChangeDelegate delegate;
private final ChangeConfig changeConfig;
- private OverrideCallbacks(Callbacks delegate, ChangeConfig changeConfig) {
+ private OverrideCallbacks(BehaviorChangeDelegate delegate, ChangeConfig changeConfig) {
this.delegate = Objects.requireNonNull(delegate);
this.changeConfig = Objects.requireNonNull(changeConfig);
}
@Override
- protected boolean isChangeEnabled(long changeId) {
+ public boolean isChangeEnabled(long changeId) {
if (changeConfig.isForceEnabled(changeId)) {
return true;
}
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index 437edc6..6f1a131 100755
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -82,7 +82,7 @@
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public static @Nullable StructCapUserData[] capget(@NonNull StructCapUserHeader hdr) throws ErrnoException {
+ public static @Nullable StructUserCapData[] capget(@NonNull StructUserCapHeader hdr) throws ErrnoException {
return Libcore.os.capget(hdr);
}
@@ -97,7 +97,7 @@
* set, or to set a capability in the effective set that is
* not in the permitted set; or
* the caller attempted to use
- * {@link capset(StructCapUserHeader, StructCapUserData[])}
+ * {@link capset( StructUserCapHeader , StructUserCapData[])}
* to modify the capabilities of a thread other than itself,
* but lacked sufficient privilege;
* or there is no such thread.
@@ -105,7 +105,7 @@
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public static void capset(@NonNull StructCapUserHeader hdr, @NonNull StructCapUserData[] data)
+ public static void capset(@NonNull StructUserCapHeader hdr, @NonNull StructUserCapData[] data)
throws ErrnoException {
Libcore.os.capset(hdr, data);
}
@@ -331,8 +331,6 @@
* @param option name of the option to get
* @return {@link StructLinger} associated with given {@code fd}
* @throws ErrnoException
- *
- * @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public static @Nullable StructLinger getsockoptLinger(@NonNull FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
@@ -793,8 +791,6 @@
* @param value {@link StructLinger} to set for {@code fd}
* @throws ErrnoException if {@code fd} is invalid; or
* {@code option} is unknown at given {@code level}
- *
- * @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public static void setsockoptLinger(@NonNull FileDescriptor fd, int level, int option, @NonNull StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index dabb41a..ce8747f 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -27,11 +27,11 @@
}
/**
- * Returns the index of the element in the {@link StructCapUserData} (cap_user_data)
+ * Returns the index of the element in the {@link StructUserCapData} (cap_user_data)
* array that this capability is stored in.
*
* @param x capability
- * @return index of the element in the {@link StructCapUserData} array storing this capability
+ * @return index of the element in the {@link StructUserCapData} array storing this capability
*
* @hide
*/
@@ -41,7 +41,7 @@
/**
* Returns the mask for the given capability. This is relative to the capability's
- * {@link StructCapUserData} (cap_user_data) element, the index of which can be
+ * {@link StructUserCapData} (cap_user_data) element, the index of which can be
* retrieved with {@link CAP_TO_INDEX}.
*
* @param x capability
@@ -412,9 +412,9 @@
public static final int IP_TOS = placeholder();
public static final int IP_TTL = placeholder();
/**
- * Version constant to be used in {@link StructCapUserHeader} with
- * {@link Os#capset(StructCapUserHeader, StructCapUserData[])} and
- * {@link Os#capget(StructCapUserHeader)}.
+ * Version constant to be used in {@link StructUserCapHeader} with
+ * {@link Os#capset(StructUserCapHeader, StructUserCapData[])} and
+ * {@link Os#capget(StructUserCapHeader)}.
*
* See <a href="https://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
*
diff --git a/luni/src/main/java/android/system/StructLinger.java b/luni/src/main/java/android/system/StructLinger.java
index 6726d59..8622dfa 100644
--- a/luni/src/main/java/android/system/StructLinger.java
+++ b/luni/src/main/java/android/system/StructLinger.java
@@ -22,8 +22,8 @@
* Corresponds to C's {@code struct linger} from
* <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html"><sys/socket.h></a>
*
- * When enabled, a {@link Os.close(java.io.FileDescriptor) or
- * {@link Os.shutdown(java.io.FileDescriptor, int)} will
+ * When enabled, a {@link Os#close(java.io.FileDescriptor)} or
+ * {@link Os#shutdown(java.io.FileDescriptor, int)} will
* not return until all queued messages for the socket have been successfully sent or the
* linger timeout has been reached. Otherwise, the call returns immediately and the closing is
* done in the background.
@@ -31,18 +31,14 @@
* See <a href="https://man7.org/linux/man-pages/man7/socket.7.html">socket(7)</a>
* for linger struct description.
*
- * @see {@link Os.getsockoptLinger(java.io.FileDescriptor, int, int)}.
- * @see {@link OsConstants.SO_LINGER}.
- *
- * @hide
+ * @see Os#getsockoptLinger(java.io.FileDescriptor, int, int).
+ * @see OsConstants#SO_LINGER
*/
-@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public final class StructLinger {
/** Whether or not linger is enabled. Non-zero is on. */
public final int l_onoff;
/** Linger time in seconds. */
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public final int l_linger;
/**
@@ -51,7 +47,6 @@
* @param l_onoff whether or not linger is enabled, non-zero is on
* @param l_linger linger time, in seconds
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public StructLinger(int l_onoff, int l_linger) {
this.l_onoff = l_onoff;
this.l_linger = l_linger;
@@ -62,7 +57,6 @@
*
* @return {@code true} if linger is enabled, and {@code false} otherwise
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public boolean isOn() {
return l_onoff != 0;
}
diff --git a/luni/src/main/java/android/system/StructCapUserData.java b/luni/src/main/java/android/system/StructUserCapData.java
similarity index 89%
rename from luni/src/main/java/android/system/StructCapUserData.java
rename to luni/src/main/java/android/system/StructUserCapData.java
index f8865fa..ce9691f 100644
--- a/luni/src/main/java/android/system/StructCapUserData.java
+++ b/luni/src/main/java/android/system/StructUserCapData.java
@@ -20,15 +20,15 @@
/**
* Corresponds to Linux' __user_cap_data_struct for capget and capset.
- * Used in {@link Os.capget(StructCapUserHeader)} and
- * {@link Os.capset(StructCapUserHeader, StructCapUserData[])}.
+ * Used in {@link Os.capget( StructUserCapHeader )} and
+ * {@link Os.capset( StructUserCapHeader , StructUserCapData[])}.
*
* See <a href="https://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
*
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
-public final class StructCapUserData {
+public final class StructUserCapData {
/** Effective capability mask. */
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public final int effective; /* __u32 */
@@ -49,7 +49,7 @@
* @param inheritable inheritable capability mask
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public StructCapUserData(int effective, int permitted, int inheritable) {
+ public StructUserCapData(int effective, int permitted, int inheritable) {
this.effective = effective;
this.permitted = permitted;
this.inheritable = inheritable;
diff --git a/luni/src/main/java/android/system/StructCapUserHeader.java b/luni/src/main/java/android/system/StructUserCapHeader.java
similarity index 88%
rename from luni/src/main/java/android/system/StructCapUserHeader.java
rename to luni/src/main/java/android/system/StructUserCapHeader.java
index 424db1b..42108e8 100644
--- a/luni/src/main/java/android/system/StructCapUserHeader.java
+++ b/luni/src/main/java/android/system/StructUserCapHeader.java
@@ -20,14 +20,14 @@
/**
* Corresponds to Linux' __user_cap_header_struct for capget and capset.
- * Used in {@link Os.capget(StructCapUserHeader)} and
- * {@link Os.capset(StructCapUserHeader, StructCapUserData[])}.
+ * Used in {@link Os.capget( StructUserCapHeader )} and
+ * {@link Os.capset( StructUserCapHeader , StructUserCapData[])}.
*
* Capabilities defined in <a href="https://man7.org/linux/man-pages/man7/capabilities.7.html">capabilities(7)</a>
* @hide
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
-public final class StructCapUserHeader {
+public final class StructUserCapHeader {
/**
* Version of the header. Note this is not final as capget() may mutate the field when an
* invalid version is provided.
@@ -48,7 +48,7 @@
* @param pid process id
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
- public StructCapUserHeader(int version, int pid) {
+ public StructUserCapHeader(int version, int pid) {
this.version = version;
this.pid = pid;
}
diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java
index 037af4a..a71044c 100644
--- a/luni/src/main/java/java/lang/ref/FinalizerReference.java
+++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java
@@ -160,16 +160,15 @@
synchronized void awaitFinalization(long timeout) throws InterruptedException {
final long startTime = System.nanoTime();
- final long endTime = startTime + timeout;
+ final long endTime = startTime + timeout; // May wrap.
while (!finalized) {
// 0 signifies no timeout.
if (timeout != 0) {
- final long currentTime = System.nanoTime();
- if (currentTime >= endTime) {
+ final long deltaTime = endTime - System.nanoTime();
+ if (deltaTime <= 0) {
break;
} else {
- final long deltaTime = endTime - currentTime;
- wait(deltaTime / 1000000, (int)(deltaTime % 1000000));
+ wait(deltaTime / 1_000_000, (int)(deltaTime % 1_000_000));
}
} else {
wait();
diff --git a/luni/src/main/java/libcore/content/type/MimeMap.java b/luni/src/main/java/libcore/content/type/MimeMap.java
index 3822022..8931524 100644
--- a/luni/src/main/java/libcore/content/type/MimeMap.java
+++ b/luni/src/main/java/libcore/content/type/MimeMap.java
@@ -42,10 +42,10 @@
*
* @return builder
*
- * @see {@link MimeMap.Builder}
+ * @see MimeMap.Builder
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public static Builder builder() {
+ public static @NonNull Builder builder() {
return new Builder();
}
@@ -55,10 +55,10 @@
*
* @return builder
*
- * @see {@link MimeMap.Builder}
+ * @see MimeMap.Builder
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public Builder buildUpon() {
+ public @NonNull Builder buildUpon() {
return new Builder(mimeToExt, extToMime);
}
@@ -75,12 +75,12 @@
private static volatile MemoizingSupplier<@NonNull MimeMap> instanceSupplier =
new MemoizingSupplier<>(
() -> builder()
- .put("application/pdf", "pdf")
- .put("image/jpeg", "jpg")
- .put("image/x-ms-bmp", "bmp")
- .put("text/html", Arrays.asList("htm", "html"))
- .put("text/plain", Arrays.asList("text", "txt"))
- .put("text/x-java", "java")
+ .addMimeMapping("application/pdf", "pdf")
+ .addMimeMapping("image/jpeg", "jpg")
+ .addMimeMapping("image/x-ms-bmp", "bmp")
+ .addMimeMapping("text/html", Arrays.asList("htm", "html"))
+ .addMimeMapping("text/plain", Arrays.asList("text", "txt"))
+ .addMimeMapping("text/x-java", "java")
.build());
private MimeMap(Map<String, String> mimeToExt, Map<String, String> extToMime) {
@@ -245,7 +245,7 @@
/**
* A builder for mapping of MIME types to extensions and back.
- * Use {@link #put(String, List)} and {@link #put(String, String)} to add
+ * Use {@link #addMimeMapping(String, List)} and {@link #addMimeMapping(String, String)} to add
* mapping entries and build final {@link MimeMap} with {@link #build()}.
*
* @hide
@@ -353,7 +353,7 @@
* @return This builder.
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public Builder put(@NonNull String mimeSpec, @NonNull List<@NonNull String> extensionSpecs)
+ public @NonNull Builder addMimeMapping(@NonNull String mimeSpec, @NonNull List<@NonNull String> extensionSpecs)
{
Element mimeElement = Element.ofMimeSpec(mimeSpec); // validate mimeSpec unconditionally
if (extensionSpecs.isEmpty()) {
@@ -374,8 +374,8 @@
*
* @hide
*/
- public Builder put(@NonNull String mimeSpec, @NonNull String extensionSpec) {
- return put(mimeSpec, Collections.singletonList(extensionSpec));
+ public @NonNull Builder addMimeMapping(@NonNull String mimeSpec, @NonNull String extensionSpec) {
+ return addMimeMapping(mimeSpec, Collections.singletonList(extensionSpec));
}
/**
@@ -384,7 +384,7 @@
* @return {@link MimeMap} containing previously added MIME mapping entries
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public MimeMap build() {
+ public @NonNull MimeMap build() {
return new MimeMap(mimeToExt, extToMime);
}
diff --git a/luni/src/main/java/libcore/internal/StringPool.java b/luni/src/main/java/libcore/internal/StringPool.java
index 546a404..fccc354 100644
--- a/luni/src/main/java/libcore/internal/StringPool.java
+++ b/luni/src/main/java/libcore/internal/StringPool.java
@@ -23,12 +23,10 @@
*
* @hide
*/
-@libcore.api.CorePlatformApi
public final class StringPool {
private final String[] pool = new String[512];
- @libcore.api.CorePlatformApi
public StringPool() {
}
@@ -47,7 +45,6 @@
/**
* Returns a string equal to {@code new String(array, start, length)}.
*/
- @libcore.api.CorePlatformApi
public String get(char[] array, int start, int length) {
// Compute an arbitrary hash of the content
int hashCode = 0;
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index 4ae124e..702b62c 100755
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -21,8 +21,8 @@
import android.system.Int32Ref;
import android.system.Int64Ref;
import android.system.StructAddrinfo;
-import android.system.StructCapUserData;
-import android.system.StructCapUserHeader;
+import android.system.StructUserCapData;
+import android.system.StructUserCapHeader;
import android.system.StructGroupReq;
import android.system.StructIfaddrs;
import android.system.StructLinger;
@@ -111,11 +111,11 @@
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.bind(fd, address); }
@Override
- public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+ public StructUserCapData[] capget(StructUserCapHeader hdr) throws ErrnoException {
return os.capget(hdr);
}
@Override
- public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException {
+ public void capset(StructUserCapHeader hdr, StructUserCapData[] data) throws ErrnoException {
os.capset(hdr, data);
}
@UnsupportedAppUsage
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
index 4ecb785..0cc032e 100755
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -21,8 +21,8 @@
import android.system.Int32Ref;
import android.system.Int64Ref;
import android.system.StructAddrinfo;
-import android.system.StructCapUserData;
-import android.system.StructCapUserHeader;
+import android.system.StructUserCapData;
+import android.system.StructUserCapHeader;
import android.system.StructGroupReq;
import android.system.StructIfaddrs;
import android.system.StructLinger;
@@ -54,9 +54,9 @@
public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public native void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
@Override
- public native StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+ public native StructUserCapData[] capget(StructUserCapHeader hdr) throws ErrnoException;
@Override
- public native void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+ public native void capset(StructUserCapHeader hdr, StructUserCapData[] data)
throws ErrnoException;
public native void chmod(String path, int mode) throws ErrnoException;
public native void chown(String path, int uid, int gid) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Memory.java b/luni/src/main/java/libcore/io/Memory.java
index b760919..4af1675 100644
--- a/luni/src/main/java/libcore/io/Memory.java
+++ b/luni/src/main/java/libcore/io/Memory.java
@@ -23,21 +23,23 @@
import dalvik.annotation.optimization.FastNative;
+import libcore.api.CorePlatformApi;
import libcore.util.NonNull;
-import libcore.util.Nullable;
/**
* Unsafe access to memory.
*
* @hide
*/
-@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public final class Memory {
private Memory() { }
/**
* Used to optimize nio heap buffer bulk get operations. 'dst' must be a primitive array.
* 'dstOffset' is measured in units of 'sizeofElements' bytes.
+ *
+ * @hide
*/
public static native void unsafeBulkGet(Object dst, int dstOffset, int byteCount,
byte[] src, int srcOffset, int sizeofElements, boolean swap);
@@ -45,6 +47,7 @@
/**
* Used to optimize nio heap buffer bulk put operations. 'src' must be a primitive array.
* 'srcOffset' is measured in units of 'sizeofElements' bytes.
+ * @hide
*/
public static native void unsafeBulkPut(byte[] dst, int dstOffset, int byteCount,
Object src, int srcOffset, int sizeofElements, boolean swap);
@@ -57,8 +60,10 @@
* @param offset offset in {@code src} to get bytes from
* @param order byte order
* @return int value
+ *
+ * @hide
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static int peekInt(@NonNull byte[] src, int offset, @NonNull ByteOrder order) {
if (order == ByteOrder.BIG_ENDIAN) {
return (((src[offset++] & 0xff) << 24) |
@@ -73,6 +78,9 @@
}
}
+ /**
+ * @hide
+ */
public static long peekLong(byte[] src, int offset, ByteOrder order) {
if (order == ByteOrder.BIG_ENDIAN) {
int h = ((src[offset++] & 0xff) << 24) |
@@ -105,8 +113,10 @@
* @param offset offset in {@code src} to get bytes from
* @param order byte order
* @return short value
+ *
+ * @hide
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static short peekShort(@NonNull byte[] src, int offset, @NonNull ByteOrder order) {
if (order == ByteOrder.BIG_ENDIAN) {
return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff));
@@ -123,8 +133,10 @@
* @param offset offset in {@code dst} to put value to
* @param value int value to write
* @param order byte order
+ *
+ * @hide
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static void pokeInt(@NonNull byte[] dst, int offset, int value, @NonNull ByteOrder order) {
if (order == ByteOrder.BIG_ENDIAN) {
dst[offset++] = (byte) ((value >> 24) & 0xff);
@@ -147,8 +159,10 @@
* @param offset offset in {@code dst} to put value to
* @param value long value to write
* @param order byte order
+ *
+ * @hide
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static void pokeLong(@NonNull byte[] dst, int offset, long value, @NonNull ByteOrder order) {
if (order == ByteOrder.BIG_ENDIAN) {
int i = (int) (value >> 32);
@@ -183,8 +197,10 @@
* @param offset offset in {@code dst} to put value to
* @param value short value to write
* @param order byte order
+ *
+ * @hide
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static void pokeShort(@NonNull byte[] dst, int offset, short value, @NonNull ByteOrder order) {
if (order == ByteOrder.BIG_ENDIAN) {
dst[offset++] = (byte) ((value >> 8) & 0xff);
@@ -214,13 +230,19 @@
*
* @hide make type-safe before making public?
*/
- @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+ @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public static native void memmove(@NonNull Object dstObject, int dstOffset, @NonNull Object srcObject, int srcOffset, long byteCount);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
@FastNative
public static native byte peekByte(long address);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public static int peekInt(long address, boolean swap) {
int result = peekIntNative(address);
@@ -232,6 +254,9 @@
@FastNative
private static native int peekIntNative(long address);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public static long peekLong(long address, boolean swap) {
long result = peekLongNative(address);
@@ -243,6 +268,9 @@
@FastNative
private static native long peekLongNative(long address);
+ /**
+ * @hide
+ */
public static short peekShort(long address, boolean swap) {
short result = peekShortNative(address);
if (swap) {
@@ -253,19 +281,52 @@
@FastNative
private static native short peekShortNative(long address);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount);
+
+ /**
+ * @hide
+ */
public static native void peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void peekDoubleArray(long address, double[] dst, int dstOffset, int doubleCount, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void peekFloatArray(long address, float[] dst, int dstOffset, int floatCount, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void peekIntArray(long address, int[] dst, int dstOffset, int intCount, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void peekLongArray(long address, long[] dst, int dstOffset, int longCount, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
@FastNative
public static native void pokeByte(long address, byte value);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public static void pokeInt(long address, int value, boolean swap) {
if (swap) {
@@ -276,6 +337,9 @@
@FastNative
private static native void pokeIntNative(long address, int value);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public static void pokeLong(long address, long value, boolean swap) {
if (swap) {
@@ -286,6 +350,9 @@
@FastNative
private static native void pokeLongNative(long address, long value);
+ /**
+ * @hide
+ */
public static void pokeShort(long address, short value, boolean swap) {
if (swap) {
value = Short.reverseBytes(value);
@@ -295,12 +362,39 @@
@FastNative
private static native void pokeShortNative(long address, short value);
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public static native void pokeByteArray(long address, byte[] src, int offset, int count);
+
+ /**
+ * @hide
+ */
public static native void pokeCharArray(long address, char[] src, int offset, int count, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void pokeDoubleArray(long address, double[] src, int offset, int count, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void pokeFloatArray(long address, float[] src, int offset, int count, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void pokeIntArray(long address, int[] src, int offset, int count, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void pokeLongArray(long address, long[] src, int offset, int count, boolean swap);
+
+ /**
+ * @hide
+ */
public static native void pokeShortArray(long address, short[] src, int offset, int count, boolean swap);
}
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index fe02877..b127275 100755
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -21,8 +21,8 @@
import android.system.Int32Ref;
import android.system.Int64Ref;
import android.system.StructAddrinfo;
-import android.system.StructCapUserData;
-import android.system.StructCapUserHeader;
+import android.system.StructUserCapData;
+import android.system.StructUserCapHeader;
import android.system.StructGroupReq;
import android.system.StructIfaddrs;
import android.system.StructLinger;
@@ -62,8 +62,8 @@
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
- public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
- public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException;
+ public StructUserCapData[] capget(StructUserCapHeader hdr) throws ErrnoException;
+ public void capset(StructUserCapHeader hdr, StructUserCapData[] data) throws ErrnoException;
@UnsupportedAppUsage
public void chmod(String path, int mode) throws ErrnoException;
public void chown(String path, int uid, int gid) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/net/http/Dns.java b/luni/src/main/java/libcore/net/http/Dns.java
index 7a14aad..9526211 100644
--- a/luni/src/main/java/libcore/net/http/Dns.java
+++ b/luni/src/main/java/libcore/net/http/Dns.java
@@ -21,6 +21,8 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
/**
* A domain name service that resolves IP addresses for host names.
@@ -30,10 +32,10 @@
public interface Dns extends com.android.okhttp.internalandroidapi.Dns {
/**
* Returns the IP addresses of {@code hostname}, in the order they should
- * be attempted.
+ * be attempted. Returns loopback addresses for {@code null} host.
*
* @param hostname The host name will be looked up.
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- List<InetAddress> lookup(String hostname) throws UnknownHostException;
+ @NonNull List<@NonNull InetAddress> lookup(@Nullable String hostname) throws UnknownHostException;
}
\ No newline at end of file
diff --git a/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java b/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java
index 1c46020..b54f5f8 100644
--- a/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java
+++ b/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java
@@ -25,6 +25,7 @@
import java.util.concurrent.TimeUnit;
import javax.net.SocketFactory;
+import libcore.util.NonNull;
/**
* A HttpURLConnectionFactory that supports some configuration on a per-factory or per-connection
@@ -41,7 +42,7 @@
* Create a new {@link HttpURLConnectionFactory} instance.
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public static HttpURLConnectionFactory createInstance() {
+ @NonNull public static HttpURLConnectionFactory createInstance() {
return new HttpURLConnectionFactory();
}
@@ -59,7 +60,7 @@
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
public void setNewConnectionPool(int maxIdleConnections, long keepAliveDuration,
- TimeUnit timeUnit) {
+ @NonNull TimeUnit timeUnit) {
mFactory.setNewConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);
}
@@ -69,7 +70,7 @@
* @param dns the dns resolver for looking up.
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public void setDns(Dns dns) {
+ public void setDns(@NonNull Dns dns) {
mFactory.setDns(dns);
}
@@ -85,8 +86,8 @@
* configuration.
*/
@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
- public URLConnection openConnection(URL url, SocketFactory socketFactory, Proxy proxy) throws
- IOException {
+ public URLConnection openConnection(@NonNull URL url, @NonNull SocketFactory socketFactory,
+ @NonNull Proxy proxy) throws IOException {
return mFactory.openConnection(url, socketFactory, proxy);
}
}
diff --git a/luni/src/main/java/libcore/util/FP16.java b/luni/src/main/java/libcore/util/FP16.java
index cc1d4d6..49fd926 100644
--- a/luni/src/main/java/libcore/util/FP16.java
+++ b/luni/src/main/java/libcore/util/FP16.java
@@ -87,7 +87,7 @@
*/
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
-public class FP16 {
+public final class FP16 {
/**
* The number of bits used to represent a half-precision float value.
*/
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index d7b6c22..7c47129 100755
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -878,14 +878,14 @@
// We assume the calls are rare enough that it does not make sense to cache class objects. The
// advantage is lower maintenance burden.
-static bool ReadStructCapUserHeader(
+static bool ReadStructUserCapHeader(
JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
if (java_header == nullptr) {
jniThrowNullPointerException(env, "header is null");
return false;
}
- ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+ ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructUserCapHeader"));
if (header_class.get() == nullptr) {
return false;
}
@@ -909,9 +909,9 @@
return true;
}
-static void SetStructCapUserHeaderVersion(
+static void SetStructUserCapHeaderVersion(
JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
- ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+ ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructUserCapHeader"));
if (header_class.get() == nullptr) {
env->ExceptionClear();
return;
@@ -925,7 +925,7 @@
env->SetIntField(java_header, version_fid, c_header->version);
}
-static jobject CreateStructCapUserData(
+static jobject CreateStructUserCapData(
JNIEnv* env, jclass data_class, __user_cap_data_struct* c_data) {
if (c_data == nullptr) {
// Should not happen.
@@ -944,13 +944,13 @@
return env->NewObject(data_class, data_cons, e, p, i);
}
-static bool ReadStructCapUserData(JNIEnv* env, jobject java_data, __user_cap_data_struct* c_data) {
+static bool ReadStructUserCapData(JNIEnv* env, jobject java_data, __user_cap_data_struct* c_data) {
if (java_data == nullptr) {
jniThrowNullPointerException(env, "data is null");
return false;
}
- ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+ ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructUserCapData"));
if (data_class.get() == nullptr) {
return false;
}
@@ -1072,7 +1072,7 @@
static jobjectArray Linux_capget(JNIEnv* env, jobject, jobject header) {
// Convert Java header struct to kernel datastructure.
__user_cap_header_struct cap_header;
- if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+ if (!ReadStructUserCapHeader(env, header, &cap_header)) {
AssertException(env);
return nullptr;
}
@@ -1083,7 +1083,7 @@
// Check for EINVAL. In that case, mutate the header.
if (errno == EINVAL) {
int saved_errno = errno;
- SetStructCapUserHeaderVersion(env, header, &cap_header);
+ SetStructUserCapHeaderVersion(env, header, &cap_header);
errno = saved_errno;
}
throwErrnoException(env, "capget");
@@ -1091,7 +1091,7 @@
}
// Create the result array.
- ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+ ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructUserCapData"));
if (data_class.get() == nullptr) {
return nullptr;
}
@@ -1104,7 +1104,7 @@
// Translate the values we got.
for (size_t i = 0; i < result_size; ++i) {
ScopedLocalRef<jobject> value(
- env, CreateStructCapUserData(env, data_class.get(), &cap_data[i]));
+ env, CreateStructUserCapData(env, data_class.get(), &cap_data[i]));
if (value.get() == nullptr) {
AssertException(env);
return nullptr;
@@ -1118,7 +1118,7 @@
JNIEnv* env, jobject, jobject header, jobjectArray data) {
// Convert Java header struct to kernel datastructure.
__user_cap_header_struct cap_header;
- if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+ if (!ReadStructUserCapHeader(env, header, &cap_header)) {
AssertException(env);
return;
}
@@ -1137,7 +1137,7 @@
// Translate the values we got.
for (size_t i = 0; i < result_size; ++i) {
ScopedLocalRef<jobject> value(env, env->GetObjectArrayElement(data, i));
- if (!ReadStructCapUserData(env, value.get(), &cap_data[i])) {
+ if (!ReadStructUserCapData(env, value.get(), &cap_data[i])) {
AssertException(env);
return;
}
@@ -2752,9 +2752,9 @@
NATIVE_METHOD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
NATIVE_METHOD_OVERLOAD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
NATIVE_METHOD(Linux, capget,
- "(Landroid/system/StructCapUserHeader;)[Landroid/system/StructCapUserData;"),
+ "(Landroid/system/StructUserCapHeader;)[Landroid/system/StructUserCapData;"),
NATIVE_METHOD(Linux, capset,
- "(Landroid/system/StructCapUserHeader;[Landroid/system/StructCapUserData;)V"),
+ "(Landroid/system/StructUserCapHeader;[Landroid/system/StructUserCapData;)V"),
NATIVE_METHOD(Linux, chmod, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Linux, chown, "(Ljava/lang/String;II)V"),
NATIVE_METHOD(Linux, close, "(Ljava/io/FileDescriptor;)V"),
diff --git a/luni/src/test/java/libcore/java/lang/BootstrapMethodErrorTest.java b/luni/src/test/java/libcore/java/lang/BootstrapMethodErrorTest.java
new file mode 100644
index 0000000..613ad00
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/BootstrapMethodErrorTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class BootstrapMethodErrorTest {
+
+ private final String causeMessage = "Cause";
+ private final String errorMessage = "Error message";
+
+ @Test
+ public void constructor() {
+ BootstrapMethodError error = new BootstrapMethodError();
+
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+
+ @Test
+ public void constructorLString() {
+ BootstrapMethodError error = new BootstrapMethodError(errorMessage);
+
+ assertEquals(errorMessage, error.getMessage());
+ assertNull(error.getCause());
+ }
+
+ @Test
+ public void constructorLString_withNull() {
+ BootstrapMethodError error = new BootstrapMethodError((String) null);
+
+ assertNull(error.getMessage());
+ assertNull(error.getCause());
+ }
+
+ @Test
+ public void constructorLString_LThrowable() {
+ Exception cause = new Exception(causeMessage);
+ BootstrapMethodError error = new BootstrapMethodError(errorMessage, cause);
+
+ assertEquals(cause, error.getCause());
+ assertEquals(errorMessage, error.getMessage());
+ }
+
+ @Test
+ public void constructorLString_LThrowable_nullMessage() {
+ Exception cause = new Exception(causeMessage);
+ BootstrapMethodError error = new BootstrapMethodError(null, cause);
+
+ assertNull(error.getMessage());
+ assertEquals(cause, error.getCause());
+ }
+
+ @Test
+ public void constructorLString_LThrowable_nullCause() {
+ BootstrapMethodError error = new BootstrapMethodError(errorMessage, null /* cause */);
+
+ assertNull(error.getCause());
+ assertEquals(errorMessage, error.getMessage());
+ }
+
+ @Test
+ public void constructorLString_LThrowable_bothArgumentsNull() {
+ BootstrapMethodError error = new BootstrapMethodError(null, null);
+
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+
+ @Test
+ public void constructorLThrowable() {
+ Exception cause = new Exception(causeMessage);
+ BootstrapMethodError error = new BootstrapMethodError(cause);
+
+ assertEquals(cause, error.getCause());
+ assertEquals(cause.toString(), error.getMessage());
+ }
+
+ @Test
+ public void constructorLThrowable_withNull() {
+ BootstrapMethodError error = new BootstrapMethodError((Throwable) null /* cause */);
+
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/ErrorTest.java b/luni/src/test/java/libcore/java/lang/ErrorTest.java
new file mode 100644
index 0000000..1962b07
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/ErrorTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ErrorTest {
+
+ @Test
+ public void withNonWritableStackTrace_getStackTraceIsEmpty() {
+ Error error = new TestError("message", null /* cause */,
+ false /* enableSuppression */,
+ false /* writableStackTrace */);
+
+ assertEquals(0, error.getStackTrace().length);
+ }
+
+ @Test
+ public void withWritableStackTrace_nonEmptyGetStackTrace() {
+ Error error = new TestError("message", null /* cause */,
+ false /* enableSuppression */,
+ true /* writableStackTrace */);
+
+ assertNotEquals(0, error.getStackTrace().length);
+
+ StackTraceElement topStackTraceElement = error.getStackTrace()[0];
+ assertEquals("withWritableStackTrace_nonEmptyGetStackTrace",
+ topStackTraceElement.getMethodName());
+ }
+
+ @Test
+ public void whenSuppressionDisabled_addSuppressHasNoEffect() {
+ Error error = new TestError("Message", null, false /* enableSuppression */, true);
+
+ assertEquals(0, error.getSuppressed().length);
+ error.addSuppressed(new Exception("suppressed exception"));
+ assertEquals(0, error.getSuppressed().length);
+ }
+
+ @Test
+ public void whenSuppressionEnabled_addsSuppressed() {
+ Error error = new TestError("message", null /* cause */, true /* enableSuppression */,
+ true /* writableStackTrace */);
+
+ assertEquals(0, error.getSuppressed().length);
+
+ Exception suppressed = new Exception("suppressed");
+ error.addSuppressed(suppressed);
+ assertArrayEquals(new Throwable[] {suppressed}, error.getSuppressed());
+ }
+
+
+ private static final class TestError extends Error {
+ protected TestError(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/InheritableThreadLocalTest.java b/luni/src/test/java/libcore/java/lang/InheritableThreadLocalTest.java
new file mode 100644
index 0000000..afba40a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/InheritableThreadLocalTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class InheritableThreadLocalTest {
+
+ @Test
+ public void childValue_shouldReturnInputArgument() {
+ TestInheritableThreadLocal<Object> threadLocal = new TestInheritableThreadLocal<>();
+
+ assertNull(threadLocal.childValue(null));
+ Object parentValue = new Object();
+ assertEquals(parentValue, threadLocal.childValue(parentValue));
+ }
+
+ private static final class TestInheritableThreadLocal<T> extends InheritableThreadLocal<T> {
+
+ @Override
+ public T childValue(T parentValue) {
+ return super.childValue(parentValue);
+ }
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/lang/InternalErrorTest.java b/luni/src/test/java/libcore/java/lang/InternalErrorTest.java
new file mode 100644
index 0000000..acf588e
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/InternalErrorTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class InternalErrorTest {
+
+ @Test
+ public void constructorLThrowable() {
+ Throwable cause = new Exception("cause");
+ InternalError error = new InternalError(cause);
+
+ assertEquals(cause, error.getCause());
+ assertEquals("java.lang.Exception: cause", error.getMessage());
+ }
+
+ @Test
+ public void constructorLThrowable_withNull() {
+ InternalError error = new InternalError((Throwable) null);
+
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/LinkageErrorTest.java b/luni/src/test/java/libcore/java/lang/LinkageErrorTest.java
new file mode 100644
index 0000000..2a853d7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/LinkageErrorTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class LinkageErrorTest {
+
+ private final String errorMessage = "error message";
+
+ @Test
+ public void constructorLString_LThrowable() {
+ Exception cause = new Exception();
+ LinkageError error = new LinkageError(errorMessage, cause);
+
+ assertEquals(cause, error.getCause());
+ assertEquals(errorMessage, error.getMessage());
+ }
+
+ @Test
+ public void constructorLString_LThrowable_nullMessage() {
+ Exception cause = new Exception();
+ LinkageError error = new LinkageError(null, cause);
+
+ assertNull(error.getMessage());
+ assertEquals(cause, error.getCause());
+ }
+
+ @Test
+ public void constructorLString_LThrowable_nullCause() {
+ LinkageError error = new LinkageError(errorMessage, null /* cause */);
+
+ assertEquals(errorMessage, error.getMessage());
+ assertNull(error.getCause());
+ }
+
+ @Test
+ public void constructorLString_LThrowable_bothArgumentsNull() {
+ LinkageError error = new LinkageError(null, null);
+
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/lang/PackageTest.java b/luni/src/test/java/libcore/java/lang/PackageTest.java
index 0ea412c..ff1a9c3 100644
--- a/luni/src/test/java/libcore/java/lang/PackageTest.java
+++ b/luni/src/test/java/libcore/java/lang/PackageTest.java
@@ -17,6 +17,8 @@
package libcore.java.lang;
import dalvik.system.VMRuntime;
+
+import java.net.URL;
import java.util.Arrays;
import java.util.List;
import libcore.junit.junit3.TestCaseWithRules;
@@ -24,6 +26,7 @@
import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
import org.junit.Rule;
import org.junit.rules.TestRule;
+import org.mockito.internal.matchers.Null;
public final class PackageTest extends TestCaseWithRules {
@@ -70,4 +73,137 @@
public void testGetPackages() {
assertTrue(packages.contains(getClass().getPackage()));
}
+
+ public void testGetAnnotationsByType() {
+ Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+
+ assertEquals(1, libcoreJavaLang.getAnnotationsByType(TestPackageAnnotation.class).length);
+ assertEquals(0, libcoreJavaLang.getAnnotationsByType(Override.class).length);
+ }
+
+ public void testGetAnnotationsByType_shouldThrowNPE_whenNullIsPassed() {
+ Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+
+ try {
+ libcoreJavaLang.getAnnotationsByType(null);
+ fail();
+ } catch (NullPointerException ignored) {
+ // expected
+ }
+ }
+
+ public void testIsSealed_nonSealedPackage() throws Exception {
+ TestClassLoader testClassLoader = new TestClassLoader();
+ Package nonSealedPackage = testClassLoader.definePackage(
+ "libcore.java.lang.nonsealed",
+ "spec title",
+ "spec version",
+ "spec vendor",
+ "impl title",
+ "impl version",
+ "impl vendor",
+ null /* sealBase */);
+
+ assertFalse(nonSealedPackage.isSealed());
+ assertFalse(nonSealedPackage.isSealed(new URL("file://libcore/java/lang/nonsealed")));
+ }
+
+ public void testIsSealed_sealedPackage() throws Exception {
+ TestClassLoader testClassLoader = new TestClassLoader();
+ URL sealBase = new URL("file://libcore/java/lang/sealed");
+ Package sealedPackage = testClassLoader.definePackage(
+ "libcore.java.lang.sealed",
+ "spec title",
+ "spec version",
+ "spec vendor",
+ "impl title",
+ "impl version",
+ "impl vendor",
+ sealBase);
+
+ assertTrue(sealedPackage.isSealed());
+ assertTrue(sealedPackage.isSealed(sealBase));
+ assertFalse(sealedPackage.isSealed(new URL("file://libcore/java/lang")));
+ try {
+ sealedPackage.isSealed(null);
+ fail();
+ } catch (NullPointerException ignored) {
+ // expected
+ }
+ }
+
+ public void testGetSpecificationVendor() {
+ String specVendor = "specification vendor";
+ TestClassLoader testClassLoader = new TestClassLoader();
+ Package aPackage = testClassLoader.definePackage(
+ "libcore.java.lang.nonsealed",
+ "spec title",
+ "spec version",
+ specVendor,
+ "impl title",
+ "impl version",
+ "impl vendor",
+ null /* sealBase */);
+
+ assertEquals(specVendor, aPackage.getSpecificationVendor());
+ }
+
+ public void testGetSpecificationVersion() {
+ String specVersion = "specification version";
+ TestClassLoader testClassLoader = new TestClassLoader();
+ Package aPackage = testClassLoader.definePackage(
+ "libcore.java.lang.nonsealed",
+ "spec title",
+ specVersion,
+ "spec vendor",
+ "impl title",
+ "impl version",
+ "impl vendor",
+ null /* sealBase */);
+
+ assertEquals(specVersion, aPackage.getSpecificationVersion());
+ }
+
+ public void testIsCompatibleWith() {
+ String specVersion = "2.3.1";
+ TestClassLoader testClassLoader = new TestClassLoader();
+ Package aPackage = testClassLoader.definePackage(
+ "libcore.java.lang.nonsealed",
+ "spec title",
+ specVersion,
+ "spec vendor",
+ "impl title",
+ "impl version",
+ "impl vendor",
+ null /* sealBase */);
+
+ assertTrue(aPackage.isCompatibleWith(specVersion));
+ assertTrue(aPackage.isCompatibleWith("2.2.99.1"));
+ assertTrue(aPackage.isCompatibleWith("1.0"));
+ assertTrue(aPackage.isCompatibleWith("2.3.1.0"));
+ assertTrue(aPackage.isCompatibleWith("2.3"));
+ assertFalse(aPackage.isCompatibleWith("2.4"));
+ try {
+ aPackage.isCompatibleWith(null);
+ fail();
+ } catch (NullPointerException ignored) {
+ // expected
+ }
+ }
+
+
+ /**
+ * {@link java.lang.Package} constructors are package-private and
+ * {@link java.lang.ClassLoader#definePackage(String, String, String, String, String, String, String, URL)}
+ * is other way to create instance of {@link java.lang.Package}
+ */
+ private static final class TestClassLoader extends ClassLoader {
+ @Override
+ public Package definePackage(String name, String specTitle, String specVersion,
+ String specVendor, String implTitle, String implVersion, String implVendor,
+ URL sealBase) throws IllegalArgumentException {
+ return super.definePackage(name, specTitle, specVersion, specVendor, implTitle,
+ implVersion, implVendor, sealBase);
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/RuntimeExceptionTest.java b/luni/src/test/java/libcore/java/lang/RuntimeExceptionTest.java
new file mode 100644
index 0000000..35ab3d4
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/RuntimeExceptionTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RuntimeExceptionTest {
+
+ @Test
+ public void withNonWritableStackTrace_getStackTraceIsEmpty() {
+ RuntimeException exception = new TestRuntimeException("message", null /* cause */,
+ false /* enableSuppression */,
+ false /* writableStackTrace */);
+
+ assertEquals(0, exception.getStackTrace().length);
+ }
+
+ @Test
+ public void withWritableStackTrace_nonEmptyGetStackTrace() {
+ RuntimeException exception = new TestRuntimeException("message", null /* cause */,
+ false /* enableSuppression */,
+ true /* writableStackTrace */);
+
+ assertNotEquals(0, exception.getStackTrace().length);
+
+ StackTraceElement topStackTraceElement = exception.getStackTrace()[0];
+ assertEquals("withWritableStackTrace_nonEmptyGetStackTrace",
+ topStackTraceElement.getMethodName());
+ }
+
+ @Test
+ public void whenSuppressionDisabled_addSuppressHasNoEffect() {
+ RuntimeException exception = new TestRuntimeException("Message", null,
+ false /* enableSuppression */, true /* writableStackTrace */);
+
+ assertEquals(0, exception.getSuppressed().length);
+ exception.addSuppressed(new Exception("suppressed exception"));
+ assertEquals(0, exception.getSuppressed().length);
+ }
+
+ @Test
+ public void whenSuppressionEnabled_addsSuppressed() {
+ RuntimeException error = new TestRuntimeException("message", null /* cause */,
+ true /* enableSuppression */, true /* writableStackTrace */);
+
+ assertEquals(0, error.getSuppressed().length);
+
+ Exception suppressed = new Exception("suppressed");
+ error.addSuppressed(suppressed);
+ assertArrayEquals(new Throwable[] {suppressed}, error.getSuppressed());
+ }
+
+ private static final class TestRuntimeException extends RuntimeException {
+ TestRuntimeException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/RuntimePermissionTest.java b/luni/src/test/java/libcore/java/lang/RuntimePermissionTest.java
new file mode 100644
index 0000000..33c0898
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/RuntimePermissionTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RuntimePermissionTest {
+
+ @Test
+ public void constructorLString_LString() {
+ RuntimePermission runtimePermission = new RuntimePermission(null, null);
+ assertEquals("", runtimePermission.getActions());
+ assertEquals("", runtimePermission.getName());
+
+ runtimePermission = new RuntimePermission("non empty", "non empty");
+ assertEquals("", runtimePermission.getActions());
+ assertEquals("", runtimePermission.getName());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index fa69c07..258f8a1 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -273,4 +273,12 @@
} catch (SecurityException expected) {
}
}
+
+ /**
+ * Overall {@link System#console()} return value depends on how exactly runtime was started, but
+ * for Android apps it will be null.
+ */
+ public void testSystem_console() {
+ assertNull(System.console());
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/ThreadGroupTest.java b/luni/src/test/java/libcore/java/lang/ThreadGroupTest.java
new file mode 100644
index 0000000..4076bd1
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/ThreadGroupTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public class ThreadGroupTest {
+
+ private CountDownLatch mLatch;
+
+ @Before
+ public void setup() {
+ mLatch = new CountDownLatch(2);
+ }
+
+ @Test
+ public void interrupt_shouldInterruptAllThreadsInAGroup() throws Exception {
+ ThreadGroup group = new ThreadGroup("group under test");
+
+ Thread first = createHangThread(group);
+ Thread second = createHangThread(group);
+
+ first.start();
+ second.start();
+
+ group.interrupt();
+
+ assertTrue("Some thread was not interrupted", mLatch.await(5, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void interrupt_shouldInterruptThreadsInSubgroups() throws Exception {
+ ThreadGroup parentGroup = new ThreadGroup("parent thread group");
+ ThreadGroup childGroup = new ThreadGroup(parentGroup, "child thread group");
+
+ Thread first = createHangThread(parentGroup);
+ Thread second = createHangThread(childGroup);
+
+ first.start();
+ second.start();
+
+ parentGroup.interrupt();
+
+ assertTrue("Some thread was not interrupted", mLatch.await(5, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void interrupt_shouldNotInterruptThreadsInParentGroup() throws Exception {
+ ThreadGroup parentGroup = new ThreadGroup("parent thread group");
+ ThreadGroup childGroup = new ThreadGroup(parentGroup, "child thread group");
+
+ Thread first = createHangThread(parentGroup);
+ Thread second = createHangThread(childGroup);
+
+ first.start();
+ second.start();
+
+ childGroup.interrupt();
+
+ assertFalse("Both threads were interrupted", mLatch.await(5, TimeUnit.SECONDS));
+
+ assertEquals("Thread from parent group was interrupted", 1, mLatch.getCount());
+ }
+
+ @Test
+ public void suspend_shouldThrowUnsupportedOperationException() throws Exception {
+ ThreadGroup threadGroup = new ThreadGroup("test group");
+
+ Thread thread = createHangThread(threadGroup);
+ thread.start();
+
+ try {
+ threadGroup.suspend();
+ fail("suspend() didn't throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException ignored) {
+ // expected
+ } finally {
+ thread.join();
+ }
+ }
+
+ @Test
+ public void stop_shouldThrowUnsupportedOperationException() throws Exception {
+ ThreadGroup threadGroup = new ThreadGroup("test group");
+
+ Thread thread = createHangThread(threadGroup);
+ thread.start();
+
+ try {
+ threadGroup.stop();
+ fail("stop() didn't throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException ignored) {
+ // expected
+ } finally {
+ thread.join();
+ }
+ }
+
+ private Thread createHangThread(ThreadGroup threadGroup) {
+ return new Thread(threadGroup, () -> {
+ try {
+ Thread.sleep(20_000);
+ } catch (InterruptedException e) {
+ mLatch.countDown();
+ }
+ });
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index e91e567..19ca2b6 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -16,6 +16,13 @@
package libcore.java.lang;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
import dalvik.system.InMemoryDexClassLoader;
import java.io.InputStream;
@@ -31,13 +38,17 @@
import junit.framework.Assert;
import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
import org.mockito.InOrder;
import org.mockito.Mockito;
import libcore.io.Streams;
import libcore.java.lang.ref.FinalizationTester;
-public final class ThreadTest extends TestCase {
+@RunWith(JUnit4.class)
+public final class ThreadTest {
static {
System.loadLibrary("javacoretests");
}
@@ -46,12 +57,14 @@
* getContextClassLoader returned a non-application class loader.
* http://code.google.com/p/android/issues/detail?id=5697
*/
- public void testJavaContextClassLoader() throws Exception {
+ @Test
+ public void javaContextClassLoader() throws Exception {
Assert.assertNotNull("Must have a Java context ClassLoader",
Thread.currentThread().getContextClassLoader());
}
- public void testLeakingStartedThreads() {
+ @Test
+ public void leakingStartedThreads() {
final AtomicInteger finalizedThreadsCount = new AtomicInteger();
for (int i = 0; true; i++) {
try {
@@ -64,7 +77,8 @@
assertTrue("Started threads were never finalized!", finalizedThreadsCount.get() > 0);
}
- public void testLeakingUnstartedThreads() {
+ @Test
+ public void leakingUnstartedThreads() {
final AtomicInteger finalizedThreadsCount = new AtomicInteger();
for (int i = 0; true; i++) {
try {
@@ -77,7 +91,8 @@
assertTrue("Unstarted threads were never finalized!", finalizedThreadsCount.get() > 0);
}
- public void testThreadSleep() throws Exception {
+ @Test
+ public void threadSleep() throws Exception {
int millis = 1000;
long start = System.currentTimeMillis();
@@ -89,7 +104,8 @@
assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250);
}
- public void testThreadInterrupted() throws Exception {
+ @Test
+ public void threadInterrupted() throws Exception {
Thread.currentThread().interrupt();
try {
Thread.sleep(0);
@@ -99,7 +115,8 @@
}
}
- public void testThreadSleepIllegalArguments() throws Exception {
+ @Test
+ public void threadSleepIllegalArguments() throws Exception {
try {
Thread.sleep(-1);
@@ -120,7 +137,8 @@
}
}
- public void testThreadWakeup() throws Exception {
+ @Test
+ public void threadWakeup() throws Exception {
WakeupTestThread t1 = new WakeupTestThread();
WakeupTestThread t2 = new WakeupTestThread();
@@ -135,22 +153,26 @@
assertTrue("Threads did not finish", t1.done && t2.done);
}
- public void testContextClassLoaderIsNotNull() {
+ @Test
+ public void contextClassLoaderIsNotNull() {
assertNotNull(Thread.currentThread().getContextClassLoader());
}
- public void testContextClassLoaderIsInherited() {
+ @Test
+ public void contextClassLoaderIsInherited() {
Thread other = new Thread();
assertSame(Thread.currentThread().getContextClassLoader(), other.getContextClassLoader());
}
- public void testSetPriority_unstarted() throws Exception {
+ @Test
+ public void setPriority_unstarted() {
Thread thread = new Thread();
checkSetPriority_inBounds_succeeds(thread);
checkSetPriority_outOfBounds_fails(thread);
}
- public void testSetPriority_starting() throws Exception {
+ @Test
+ public void setPriority_starting() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
Thread thread = new Thread("starting thread") {
@Override public void run() { try { latch.await(); } catch (Exception e) { } }
@@ -167,7 +189,8 @@
thread.join();
}
- public void testSetPriority_started() throws Exception {
+ @Test
+ public void setPriority_started() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
Thread startedThread = new Thread("started thread") {
@Override public void run() { try { latch.await(); } catch (Exception e) { } }
@@ -179,7 +202,8 @@
startedThread.join();
}
- public void testSetPriority_joined() throws Exception {
+ @Test
+ public void setPriority_joined() throws Exception {
Thread joinedThread = new Thread();
joinedThread.start();
joinedThread.join();
@@ -223,7 +247,8 @@
assertEquals(oldPriority, thread.getPriority()); // priority shouldn't have changed
}
- public void testUncaughtExceptionPreHandler_calledBeforeDefaultHandler() {
+ @Test
+ public void uncaughtExceptionPreHandler_calledBeforeDefaultHandler() {
UncaughtExceptionHandler initialHandler = Mockito.mock(UncaughtExceptionHandler.class);
UncaughtExceptionHandler defaultHandler = Mockito.mock(UncaughtExceptionHandler.class);
InOrder inOrder = Mockito.inOrder(initialHandler, defaultHandler);
@@ -245,7 +270,8 @@
}
}
- public void testUncaughtExceptionPreHandler_noDefaultHandler() {
+ @Test
+ public void uncaughtExceptionPreHandler_noDefaultHandler() {
UncaughtExceptionHandler initialHandler = Mockito.mock(UncaughtExceptionHandler.class);
UncaughtExceptionHandler originalDefaultHandler
= Thread.getDefaultUncaughtExceptionHandler();
@@ -266,7 +292,8 @@
/**
* Thread.getStackTrace() is broken. http://b/1252043
*/
- public void testGetStackTrace() throws Exception {
+ @Test
+ public void getStackTrace() throws Exception {
Thread t1 = new Thread("t1") {
@Override public void run() {
doSomething();
@@ -294,7 +321,8 @@
* (source-filename, line number) hard-coded in a class loaded from
* pre-built test resources.
*/
- public void testGetStackTrace_debugInfo() throws Exception {
+ @Test
+ public void getStackTrace_debugInfo() throws Exception {
StackTraceElement ste = getStackTraceElement("debugInfo");
// Verify that this StackTraceElement appears as we expect it to
@@ -315,7 +343,8 @@
* a line number when debug info is missing for a method; the method is
* declared on a class loaded from pre-built test resources.
*/
- public void testGetStackTrace_noDebugInfo() throws Exception {
+ @Test
+ public void getStackTrace_noDebugInfo() throws Exception {
StackTraceElement ste = getStackTraceElement("noDebugInfo");
// Verify that this StackTraceElement appears as we expect it to
@@ -367,7 +396,8 @@
return result;
}
- public void testGetAllStackTracesIncludesAllGroups() throws Exception {
+ @Test
+ public void getAllStackTracesIncludesAllGroups() throws Exception {
final AtomicInteger visibleTraces = new AtomicInteger();
ThreadGroup group = new ThreadGroup("1");
Thread t2 = new Thread(group, "t2") {
@@ -383,7 +413,8 @@
}
// http://b/27748318
- public void testNativeThreadNames() throws Exception {
+ @Test
+ public void nativeThreadNames() {
String testResult = nativeTestNativeThreadNames();
// Not using assertNull here because this results in a better error message.
if (testResult != null) {
@@ -392,7 +423,8 @@
}
// http://b/29746125
- public void testParkUntilWithUnderflowValue() throws Exception {
+ @Test
+ public void parkUntilWithUnderflowValue() throws Exception {
final Thread current = Thread.currentThread();
// watchdog to unpark the tread in case it will be parked
@@ -449,7 +481,8 @@
/**
* Test that large timeout arguments don't cause crashes. b/161006928 .
*/
- public void testParkNanosHugeTimeout() throws InterruptedException {
+ @Test
+ public void parkNanosHugeTimeout() throws InterruptedException {
for (long i = 0; i < 5; ++i) {
LongParker p = new LongParker(Long.MAX_VALUE - 800_000_000L * i);
Thread.sleep(10);
@@ -467,7 +500,8 @@
* Check that call Thread.start for already started thread
* throws {@code IllegalThreadStateException}
*/
- public void testThreadDoubleStart() {
+ @Test
+ public void threadDoubleStart() {
final ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread() {
public void run() {
@@ -499,7 +533,8 @@
* Check that call Thread.start for already finished thread
* throws {@code IllegalThreadStateException}
*/
- public void testThreadRestart() {
+ @Test
+ public void threadRestart() {
Thread thread = new Thread();
thread.start();
try {
@@ -513,6 +548,18 @@
}
}
+ @Test
+ public void resume_shouldThrowUnsupportedOperationException() {
+ Thread thread = new Thread();
+
+ try {
+ thread.resume();
+ fail();
+ } catch (UnsupportedOperationException ignored) {
+ // expected
+ }
+ }
+
// This method returns {@code null} if all tests pass, or a non-null String containing
// failure details if an error occured.
private static native String nativeTestNativeThreadNames();
@@ -528,7 +575,7 @@
}
private class WakeupTestThread extends Thread {
- public boolean done;
+ public volatile boolean done;
public void run() {
done = false;
diff --git a/luni/src/test/java/libcore/java/lang/UnicodeScriptTest.java b/luni/src/test/java/libcore/java/lang/UnicodeScriptTest.java
new file mode 100644
index 0000000..1ea57ab
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/UnicodeScriptTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.Character.UnicodeScript;
+
+@RunWith(JUnit4.class)
+public class UnicodeScriptTest {
+
+ @Test
+ public void forName_shouldThrowIllegalArgumentException_whenNameIsUnknown() {
+ try {
+ UnicodeScript.forName("NON EXISTING SCRIPT NAME");
+ fail();
+ } catch (IllegalArgumentException ignored) {
+ // expected
+ }
+ }
+
+ @Test
+ public void forName_shouldThrowNPE_whenNullIsPassed() {
+ try {
+ UnicodeScript.forName(null);
+ fail();
+ } catch (NullPointerException ignored) {
+ // expected
+ }
+ }
+
+ @Test
+ public void forName_shouldAcceptAllEnumValues() {
+ for (UnicodeScript unicodeScript : UnicodeScript.values()) {
+ assertEquals(unicodeScript, UnicodeScript.forName(unicodeScript.name()));
+ }
+ }
+
+ @Test
+ public void of_shouldThrowIllegalArgumentException_whenInvalidUnicodePointPassed() {
+ try {
+ UnicodeScript.of(-1);
+ fail();
+ } catch (IllegalArgumentException ignored) {
+ // expected
+ }
+
+ try {
+ UnicodeScript.of(Character.MAX_CODE_POINT + 1);
+ fail();
+ } catch (IllegalArgumentException ignored) {
+ // expected
+ }
+ }
+
+ @Test
+ public void of_onWellKnownScripts() {
+ int asciiZero = '\u0030';
+ assertEquals(UnicodeScript.COMMON, UnicodeScript.of(asciiZero));
+ int asciiA = '\u0041';
+ assertEquals(UnicodeScript.LATIN, UnicodeScript.of(asciiA));
+ int asciiTilda = '\u007E';
+ assertEquals(UnicodeScript.COMMON, UnicodeScript.of(asciiTilda));
+ int asciiGbp = '\u00A3';
+ assertEquals(UnicodeScript.COMMON, UnicodeScript.of(asciiGbp));
+ int greekCapitalAlpha = '\u0391';
+ assertEquals(UnicodeScript.GREEK, UnicodeScript.of(greekCapitalAlpha));
+ int cyrillicCapitalA = '\u0410';
+ assertEquals(UnicodeScript.CYRILLIC, UnicodeScript.of(cyrillicCapitalA));
+ assertEquals(UnicodeScript.HAN, UnicodeScript.of('\u4E00'));
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/VirtualMachineErrorTest.java b/luni/src/test/java/libcore/java/lang/VirtualMachineErrorTest.java
new file mode 100644
index 0000000..268584f
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/VirtualMachineErrorTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class VirtualMachineErrorTest {
+ @Test
+ public void constructorLThrowable() {
+ Throwable cause = new Exception("cause");
+ VirtualMachineError error = new TestVirtualMachineError(cause);
+
+ assertEquals(cause, error.getCause());
+ assertEquals("java.lang.Exception: cause", error.getMessage());
+ }
+
+ @Test
+ public void constructorLThrowable_withNull() {
+ VirtualMachineError error = new TestVirtualMachineError(null /* cause */);
+
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+
+ private static final class TestVirtualMachineError extends VirtualMachineError {
+ public TestVirtualMachineError(Throwable cause) {
+ super(cause);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java b/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java
index b059b6c..399b360 100644
--- a/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java
+++ b/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java
@@ -91,7 +91,8 @@
final long enqueueDelayMsec = 500L;
final long startNanos = System.nanoTime();
enqueueLater(referenceQueue, enqueueDelayMsec);
- referenceQueue.remove();
+ Object result = referenceQueue.remove();
+ assertNotNull(result);
final long durationNanos = System.nanoTime() - startNanos;
final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
checkDuration(enqueueDelayMsec, durationMillis);
@@ -102,7 +103,12 @@
final long enqueueDelayMsec = 500L;
final long startNanos = System.nanoTime();
enqueueLater(referenceQueue, enqueueDelayMsec);
- referenceQueue.remove(1000);
+ Object result = referenceQueue.remove(1000);
+ if (result == null) {
+ // Also report the actual queue status.
+ assertNotNull(referenceQueue.poll());
+ assertNotNull(result);
+ }
final long durationNanos = System.nanoTime() - startNanos;
final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
checkDuration(enqueueDelayMsec, durationMillis);
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index dda8499..aecc1ad 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -900,9 +900,9 @@
@Test public void getFileNameMap_compositeExtension_customMimeMap() {
MimeMap testMimeMap = MimeMap.builder()
- .put("text/html", "html")
- .put("application/gzip", "gz")
- .put("application/tar+gzip", "tar.gz")
+ .addMimeMapping("text/html", "html")
+ .addMimeMapping("application/gzip", "gz")
+ .addMimeMapping("application/tar+gzip", "tar.gz")
.build();
MimeMap defaultMimeMap = MimeMap.getDefault();
MimeMap.setDefaultSupplier(() -> testMimeMap);
diff --git a/luni/src/test/java/libcore/java/util/ConcurrentHashMapTest.java b/luni/src/test/java/libcore/java/util/ConcurrentHashMapTest.java
deleted file mode 100644
index 397108c..0000000
--- a/luni/src/test/java/libcore/java/util/ConcurrentHashMapTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package libcore.java.util;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-public class ConcurrentHashMapTest extends junit.framework.TestCase {
-
- public void test_getOrDefault() {
- MapDefaultMethodTester.test_getOrDefault(new ConcurrentHashMap<>(),
- false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/,
- true /*getAcceptsAnyObject*/);
- }
-
- public void test_forEach() {
- MapDefaultMethodTester.test_forEach(new ConcurrentHashMap<>());
- }
-
- public void test_putIfAbsent() {
- MapDefaultMethodTester
- .test_putIfAbsent(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
- false /*doesNotAcceptNullValue*/);
- }
-
- public void test_remove() {
- MapDefaultMethodTester
- .test_remove(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
- false /*doesNotAcceptNullValue*/);
- }
-
- public void test_replace$K$V$V() {
- MapDefaultMethodTester
- .test_replace$K$V$V(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
- false /*doesNotAcceptNullValue*/);
- }
-
- public void test_replace$K$V() {
- MapDefaultMethodTester.test_replace$K$V(new ConcurrentHashMap<>(),
- false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
- }
-
- public void test_computeIfAbsent() {
- MapDefaultMethodTester.test_computeIfAbsent(new ConcurrentHashMap<>(),
- false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
- }
-
- public void test_computeIfPresent() {
- MapDefaultMethodTester.test_computeIfPresent(new ConcurrentHashMap<>(),
- false /*doesNotAcceptNullKey*/);
- }
-
- public void test_compute() {
- MapDefaultMethodTester
- .test_compute(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/);
- }
-
- public void test_merge() {
- MapDefaultMethodTester.test_merge(new ConcurrentHashMap<>(),
- false /*doesNotAcceptNullKey*/);
- }
-}
diff --git a/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java b/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java
index 1c9b399..3ae0acc 100644
--- a/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java
+++ b/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java
@@ -16,6 +16,7 @@
package libcore.java.util.beans;
+import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeListenerProxy;
@@ -246,6 +247,68 @@
}.test();
}
+ public void testFireIndexedPropertyChange_intUpdate() {
+ Object bean = "bean";
+ PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+ EventLog listenerToIntProperty = new EventLog();
+ support.addPropertyChangeListener("intProperty", listenerToIntProperty);
+
+ support.fireIndexedPropertyChange("intProperty", 10, 1, 2);
+
+ List<PropertyChangeEvent> events = listenerToIntProperty.log;
+ assertEquals(1, events.size());
+ assertEquals(1, events.get(0).getOldValue());
+ assertEquals(2, events.get(0).getNewValue());
+ assertEquals("intProperty", events.get(0).getPropertyName());
+ assertTrue(events.get(0) instanceof IndexedPropertyChangeEvent);
+ assertEquals(10, ((IndexedPropertyChangeEvent) events.get(0)).getIndex());
+ }
+
+ public void testFireIndexedPropertyChange_intUpdate_noEventWhenOldIsEqualToNew() {
+ Object bean = "bean";
+ PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+ EventLog listenerToIntProperty = new EventLog();
+ support.addPropertyChangeListener("intProperty", listenerToIntProperty);
+
+ support.fireIndexedPropertyChange("intProperty", 0, 1, 1);
+
+ List<PropertyChangeEvent> events = listenerToIntProperty.log;
+ assertTrue(events.isEmpty());
+ }
+
+ public void testFireIndexedPropertyChange_booleanUpdate() {
+ Object bean = "bean";
+ PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+ EventLog listenerToBooleanProperty = new EventLog();
+ support.addPropertyChangeListener("booleanProperty", listenerToBooleanProperty);
+
+ support.fireIndexedPropertyChange("booleanProperty", 11, true, false);
+
+ List<PropertyChangeEvent> events = listenerToBooleanProperty.log;
+ assertEquals(1, events.size());
+ assertEquals(true, events.get(0).getOldValue());
+ assertEquals(false, events.get(0).getNewValue());
+ assertEquals("booleanProperty", events.get(0).getPropertyName());
+ assertTrue(events.get(0) instanceof IndexedPropertyChangeEvent);
+ assertEquals(11, ((IndexedPropertyChangeEvent) events.get(0)).getIndex());
+ }
+
+ public void testFireIndexedPropertyChange_booleanUpdate_noEventWhenOldIsEqualToNew() {
+ Object bean = "bean";
+ PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+ EventLog listenerToBooleanProperty = new EventLog();
+ support.addPropertyChangeListener("booleanProperty", listenerToBooleanProperty);
+
+ support.fireIndexedPropertyChange("booleanProperty", 0, true, true);
+
+ List<PropertyChangeEvent> events = listenerToBooleanProperty.log;
+ assertTrue(events.isEmpty());
+ }
+
private String describe(PropertyChangeListener[] listeners) {
List<String> result = new ArrayList<String>();
for (PropertyChangeListener listener : listeners) {
diff --git a/luni/src/test/java/libcore/java/util/concurrent/AbstractExecutorServiceTest.java b/luni/src/test/java/libcore/java/util/concurrent/AbstractExecutorServiceTest.java
new file mode 100644
index 0000000..c4ed1e6
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/AbstractExecutorServiceTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AbstractExecutorServiceTest {
+
+ static class TestExecutorService extends AbstractExecutorService {
+
+ public volatile boolean isRunning = true;
+
+ public boolean awaitTermination(long timeout, TimeUnit unit) {
+ return isShutdown();
+ }
+
+ public boolean isShutdown() {
+ return !isRunning;
+ }
+
+ public boolean isTerminated() {
+ return isShutdown();
+ }
+
+ public void shutdown() {
+ isRunning = false;
+ }
+
+ public List<Runnable> shutdownNow() {
+ shutdown();
+ return Collections.emptyList();
+ }
+
+ public void execute(Runnable command) {
+ command.run();
+ }
+
+ public <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
+ return super.newTaskFor(runnable, value);
+ }
+ }
+
+ @Test
+ public void testSubmitRunnableWithValue() throws Exception {
+ Integer value = Integer.valueOf(42);
+ ExecutorService service = new TestExecutorService();
+ AtomicBoolean didRun = new AtomicBoolean(false);
+ Future<Integer> future = service.submit(() -> didRun.set(true), value);
+ Integer result = future.get();
+ assertSame(value, result);
+ assertTrue(didRun.get());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java
new file mode 100644
index 0000000..2735eab
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AbstractQueuedLongSynchronizerTest {
+
+ class DefaultMutex extends AbstractQueuedLongSynchronizer {
+
+ @Override
+ public boolean isHeldExclusively() {
+ return super.isHeldExclusively();
+ }
+
+ @Override
+ public boolean tryAcquire(long acquires) {
+ return super.tryAcquire(acquires);
+ }
+
+ @Override
+ public long tryAcquireShared(long acquires) {
+ return super.tryAcquireShared(acquires);
+ }
+
+ @Override
+ public boolean tryRelease(long releases) {
+ return super.tryRelease(releases);
+ }
+
+ @Override
+ public boolean tryReleaseShared(long releases) {
+ return super.tryReleaseShared(releases);
+ }
+
+ public AbstractQueuedLongSynchronizer.ConditionObject newCondition() {
+ return new AbstractQueuedLongSynchronizer.ConditionObject();
+ }
+
+ }
+
+ @Test
+ public void testDefaultIsHeldExclusivelyFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.isHeldExclusively();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryAcquireFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryAcquire(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryAcquireSharedFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryAcquireShared(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryReleaseFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryRelease(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryReleaseSharedFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryReleaseShared(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testConditionObjectCreation() {
+ DefaultMutex mutex = new DefaultMutex();
+ AbstractQueuedLongSynchronizer.ConditionObject condition = mutex.newCondition();
+ assertTrue(mutex.owns(condition));
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedSynchronizerTest.java b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedSynchronizerTest.java
new file mode 100644
index 0000000..0c0b98a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedSynchronizerTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AbstractQueuedSynchronizerTest {
+
+ class DefaultMutex extends AbstractQueuedSynchronizer {
+
+ @Override
+ public boolean isHeldExclusively() {
+ return super.isHeldExclusively();
+ }
+
+ @Override
+ public boolean tryAcquire(int acquires) {
+ return super.tryAcquire(acquires);
+ }
+
+ @Override
+ public int tryAcquireShared(int acquires) {
+ return super.tryAcquireShared(acquires);
+ }
+
+ @Override
+ public boolean tryRelease(int releases) {
+ return super.tryRelease(releases);
+ }
+
+ @Override
+ public boolean tryReleaseShared(int releases) {
+ return super.tryReleaseShared(releases);
+ }
+
+ public AbstractQueuedSynchronizer.ConditionObject newCondition() {
+ return new AbstractQueuedSynchronizer.ConditionObject();
+ }
+
+ }
+
+ @Test
+ public void testDefaultIsHeldExclusivelyFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.isHeldExclusively();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryAcquireFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryAcquire(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryAcquireSharedFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryAcquireShared(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryReleaseFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryRelease(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testDefaultTryReleaseSharedFails() {
+ DefaultMutex mutex = new DefaultMutex();
+ try {
+ mutex.tryReleaseShared(1);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testConditionObjectCreation() {
+ DefaultMutex mutex = new DefaultMutex();
+ AbstractQueuedSynchronizer.ConditionObject condition = mutex.newCondition();
+ assertTrue(mutex.owns(condition));
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/BrokenBarrierExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/BrokenBarrierExceptionTest.java
new file mode 100644
index 0000000..3632c09
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/BrokenBarrierExceptionTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.BrokenBarrierException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class BrokenBarrierExceptionTest {
+
+ /**
+ * constructor creates exception with detail message
+ */
+ @Test
+ public void testConstructWithMessage() {
+ BrokenBarrierException exception = new BrokenBarrierException("test");
+ assertEquals("test", exception.getMessage());
+ assertNull(exception.getCause());
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/CompletionExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/CompletionExceptionTest.java
new file mode 100644
index 0000000..956026c
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/CompletionExceptionTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.CompletionException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class CompletionExceptionTest {
+
+ // Adding derived class to be able to test the protected constructors
+ private class TestCompletionException extends CompletionException {
+ public TestCompletionException() {
+ super();
+ }
+ public TestCompletionException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * constructor creates exception without any details
+ */
+ @Test
+ public void testConstructNoMessage() {
+ CompletionException exception = new TestCompletionException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getCause());
+ }
+
+ /**
+ * constructor creates exception with detail message
+ */
+ @Test
+ public void testConstructWithMessage() {
+ CompletionException exception = new TestCompletionException("test");
+ assertEquals("test", exception.getMessage());
+ assertNull(exception.getCause());
+ }
+
+ /**
+ * constructor creates exception with detail message and cause
+ */
+ @Test
+ public void testConstructWithMessageAndCause() {
+ Throwable cause = new Exception();
+ CompletionException exception = new CompletionException("test", cause);
+ assertEquals("test", exception.getMessage());
+ assertEquals(cause, exception.getCause());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentHashMapTest.java b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentHashMapTest.java
new file mode 100644
index 0000000..233e6d3
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentHashMapTest.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package libcore.java.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.ToDoubleBiFunction;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntBiFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongBiFunction;
+import java.util.function.ToLongFunction;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import libcore.java.util.MapDefaultMethodTester;
+
+@RunWith(JUnit4.class)
+public class ConcurrentHashMapTest {
+
+ // Constants that dictate parallelism for 'reduce' calls. The value represents the number of
+ // elements needed for the operation to be executed in parallel.
+ static final long IN_PARALLEL = 1L;
+ static final long SEQUENTIALLY = Long.MAX_VALUE;
+
+ static final int MAP_SIZE = 100;
+
+ static class SumKeys implements BiFunction<Map.Entry<Long,Long>,
+ Map.Entry<Long,Long>, Map.Entry<Long,Long>> {
+ public Map.Entry<Long,Long> apply(Map.Entry<Long,Long> x, Map.Entry<Long,Long> y) {
+ return new AbstractMap.SimpleEntry<Long,Long>
+ (Long.valueOf(x.getKey().longValue() + y.getKey().longValue()),
+ Long.valueOf(1L));
+ }
+ }
+
+ static class IncrementKey implements Function<Map.Entry<Long, Long>, Map.Entry<Long, Long>> {
+ public Map.Entry<Long, Long> apply(Map.Entry<Long, Long> in) {
+ return new AbstractMap.SimpleEntry<Long, Long>
+ (Long.valueOf(in.getKey().longValue() + 1),
+ Long.valueOf(1L));
+ }
+ }
+
+ static class KeyAsDouble implements ToDoubleFunction<Map.Entry<Long, Long>> {
+ public double applyAsDouble(Map.Entry<Long, Long> in) {
+ return in.getKey().doubleValue();
+ }
+ }
+
+ static class KeyAsInt implements ToIntFunction<Map.Entry<Long, Long>> {
+ public int applyAsInt(Map.Entry<Long, Long> in) {
+ return in.getKey().intValue();
+ }
+ }
+
+ static class KeyAsLong implements ToLongFunction<Map.Entry<Long, Long>> {
+ public long applyAsLong(Map.Entry<Long, Long> in) {
+ return in.getKey().longValue();
+ }
+ }
+
+ static class IncrementKeyToDouble implements ToDoubleBiFunction<Long, Long> {
+ public double applyAsDouble(Long key, Long value) {
+ return (key.doubleValue() + 1);
+ }
+ }
+
+ static class IncrementKeyToInt implements ToIntBiFunction<Long, Long> {
+ public int applyAsInt(Long key, Long value) {
+ return (key.intValue() + 1);
+ }
+ }
+
+ static class IncrementKeyToLong implements ToLongBiFunction<Long, Long> {
+ public long applyAsLong(Long key, Long value) {
+ return (key.longValue() + 1);
+ }
+ }
+
+ static ConcurrentHashMap<Long, Long> createMap() {
+ ConcurrentHashMap<Long, Long> map = new ConcurrentHashMap<Long, Long>(MAP_SIZE);
+ for (int i = 0; i < MAP_SIZE; ++i) {
+ map.put(Long.valueOf(i), Long.valueOf(-i));
+ }
+ return map;
+ }
+
+ @Test
+ public void testReduceEntriesToDoubleSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ double result = map.reduceEntriesToDouble(SEQUENTIALLY,
+ new KeyAsDouble(), 0.0, Double::sum);
+ assertEquals((double)MAP_SIZE * (MAP_SIZE - 1) / 2, result, 0.5);
+ }
+
+ @Test
+ public void testReduceEntriesToDoubleInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ double result = map.reduceEntriesToDouble(IN_PARALLEL,
+ new KeyAsDouble(), 0.0, Double::sum);
+ assertEquals((double)MAP_SIZE * (MAP_SIZE - 1) / 2, result, 0.5);
+ }
+
+ @Test
+ public void testReduceEntriesToIntSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ int result = map.reduceEntriesToInt(SEQUENTIALLY, new KeyAsInt(), 0, Integer::sum);
+ assertEquals((int)MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+ }
+
+ @Test
+ public void testReduceEntriesToIntInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ int result = map.reduceEntriesToInt(IN_PARALLEL, new KeyAsInt(), 0, Integer::sum);
+ assertEquals(MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+ }
+
+ @Test
+ public void testReduceEntriesToLongSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ long result = map.reduceEntriesToLong(SEQUENTIALLY, new KeyAsLong(), 0L, Long::sum);
+ assertEquals((long)MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+ }
+
+ @Test
+ public void testReduceEntriesToLongInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ long result = map.reduceEntriesToLong(IN_PARALLEL, new KeyAsLong(), 0L, Long::sum);
+ assertEquals((long)MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+ }
+
+ @Test
+ public void testTransformReduceEntriesSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ Map.Entry<Long, Long> result;
+ result = map.reduceEntries(SEQUENTIALLY, new IncrementKey(), new SumKeys());
+ assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result.getKey().longValue());
+ }
+
+ @Test
+ public void testTransformReduceEntriesInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ Map.Entry<Long, Long> result;
+ result = map.reduceEntries(IN_PARALLEL, new IncrementKey(), new SumKeys());
+ assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result.getKey().longValue());
+ }
+
+ @Test
+ public void testTransformReduceEntriesToDoubleSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ double result = map.reduceToDouble(SEQUENTIALLY,
+ new IncrementKeyToDouble(), 0.0, Double::sum);
+ assertEquals((double)MAP_SIZE * (MAP_SIZE + 1) / 2, result, 0.5);
+ }
+
+ @Test
+ public void testTransformReduceEntriesToDoubleInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ double result = map.reduceToDouble(IN_PARALLEL,
+ new IncrementKeyToDouble(), 0.0, Double::sum);
+ assertEquals((double)MAP_SIZE * (MAP_SIZE + 1) / 2, result, 0.5);
+ }
+
+ @Test
+ public void testTransformReduceEntriesToIntSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ int result = map.reduceToInt(SEQUENTIALLY, new IncrementKeyToInt(), 0, Integer::sum);
+ assertEquals(MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+ }
+
+ @Test
+ public void testTransformReduceEntriesToIntInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ int result = map.reduceToInt(IN_PARALLEL, new IncrementKeyToInt(), 0, Integer::sum);
+ assertEquals(MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+ }
+
+ @Test
+ public void testTransformReduceEntriesToLongSequentially() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ long result = map.reduceToLong(SEQUENTIALLY, new IncrementKeyToLong(), 0L, Long::sum);
+ assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+ }
+
+ @Test
+ public void testTransformReduceEntriesToLongInParallel() {
+ ConcurrentHashMap<Long, Long> map = createMap();
+ long result = map.reduceToLong(IN_PARALLEL, new IncrementKeyToLong(), 0L, Long::sum);
+ assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+ }
+
+ @Test
+ public void testNewKeySetWithCapacity() {
+ final int capacity = 10;
+ Set<Long> set = ConcurrentHashMap.<Long>newKeySet(capacity);
+ assertTrue(set.isEmpty());
+ for (long i = 0; i < capacity; ++i) {
+ assertTrue(set.add(i));
+ }
+ assertFalse(set.isEmpty());
+ assertEquals(capacity, set.size());
+ }
+
+ @Test
+ public void testNewKeySetWithZeroCapacity() {
+ final int capacity = 0;
+ final int elements = 10;
+ Set<Long> set = ConcurrentHashMap.<Long>newKeySet(capacity);
+ assertTrue(set.isEmpty());
+ for (long i = 0; i < elements; ++i) {
+ assertTrue(set.add(i));
+ }
+ assertFalse(set.isEmpty());
+ assertEquals(elements, set.size());
+ }
+
+ @Test
+ public void testNewKeySetWithInvalidCapacity() {
+ try {
+ final int capacity = -10;
+ Set<Long> set = ConcurrentHashMap.<Long>newKeySet(capacity);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetOrDefault() {
+ MapDefaultMethodTester.test_getOrDefault(new ConcurrentHashMap<>(),
+ false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/,
+ true /*getAcceptsAnyObject*/);
+ }
+
+ @Test
+ public void testForEach() {
+ MapDefaultMethodTester.test_forEach(new ConcurrentHashMap<>());
+ }
+
+ @Test
+ public void testPutIfAbsent() {
+ MapDefaultMethodTester
+ .test_putIfAbsent(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
+ false /*doesNotAcceptNullValue*/);
+ }
+
+ @Test
+ public void testRemove() {
+ MapDefaultMethodTester
+ .test_remove(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
+ false /*doesNotAcceptNullValue*/);
+ }
+
+ @Test
+ public void testReplace$K$V$V() {
+ MapDefaultMethodTester
+ .test_replace$K$V$V(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
+ false /*doesNotAcceptNullValue*/);
+ }
+
+ @Test
+ public void testReplace$K$V() {
+ MapDefaultMethodTester.test_replace$K$V(new ConcurrentHashMap<>(),
+ false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
+ }
+
+ @Test
+ public void testComputeIfAbsent() {
+ MapDefaultMethodTester.test_computeIfAbsent(new ConcurrentHashMap<>(),
+ false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
+ }
+
+ @Test
+ public void testComputeIfPresent() {
+ MapDefaultMethodTester.test_computeIfPresent(new ConcurrentHashMap<>(),
+ false /*doesNotAcceptNullKey*/);
+ }
+
+ @Test
+ public void testCompute() {
+ MapDefaultMethodTester
+ .test_compute(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/);
+ }
+
+ @Test
+ public void testMerge() {
+ MapDefaultMethodTester.test_merge(new ConcurrentHashMap<>(),
+ false /*doesNotAcceptNullKey*/);
+ }
+
+ private ConcurrentHashMap.KeySetView<String, Boolean> createKeySet() {
+ final int count = 5;
+ ConcurrentHashMap.KeySetView<String, Boolean> set =
+ ConcurrentHashMap.<String>newKeySet(count);
+ assertTrue(set.isEmpty());
+ set.add("A");
+ set.add("B");
+ set.add("C");
+ set.add("D");
+ set.add("E");
+ assertFalse(set.isEmpty());
+ assertEquals(count, set.size());
+ return set;
+ }
+
+ @Test
+ public void testKeySetViewClear() {
+ ConcurrentHashMap.KeySetView set = createKeySet();
+ assertFalse(set.isEmpty());
+ set.clear();
+ assertEquals(0, set.size());
+ assertTrue(set.isEmpty());
+ }
+
+ @Test
+ public void testKeySetViewContainsAll() {
+ ConcurrentHashMap.KeySetView set = createKeySet();
+ assertTrue(set.containsAll(Arrays.asList()));
+ assertTrue(set.containsAll(Arrays.asList("A")));
+ assertTrue(set.containsAll(Arrays.asList("A", "E")));
+ assertTrue(set.containsAll(Arrays.asList("A", "B", "C", "D", "E")));
+ assertFalse(set.containsAll(Arrays.asList("A", "B", "F")));
+ assertFalse(set.containsAll(Arrays.asList("F")));
+ }
+
+ @Test
+ public void testKeySetViewForEach() {
+ final int count = 8;
+ ConcurrentHashMap.KeySetView<Integer, Boolean> set =
+ ConcurrentHashMap.<Integer>newKeySet(count);
+ for(int i = 0; i < count; ++i) {
+ set.add(i+1);
+ }
+ LongAdder adder = new LongAdder();
+ set.forEach((Integer x) -> adder.add(x.longValue()));
+ // The size is small enough for the sum not to overflow
+ assertEquals(set.size() * (set.size() + 1) / 2, adder.sum());
+ }
+
+ @Test
+ public void testKeySetViewRemoveAll() {
+ ConcurrentHashMap.KeySetView set = createKeySet();
+ assertTrue(set.removeAll(Arrays.asList("A", "C")));
+ assertEquals(set.size(), 3);
+ assertTrue(set.containsAll(Arrays.asList("B", "D", "E")));
+ assertFalse(set.removeAll(Arrays.asList("A", "C")));
+ assertEquals(set.size(), 3);
+ assertTrue(set.containsAll(Arrays.asList("B", "D", "E")));
+ }
+
+ @Test
+ public void testKeySetViewRetainAll() {
+ ConcurrentHashMap.KeySetView set = createKeySet();
+ assertTrue(set.retainAll(Arrays.asList("A", "C")));
+ assertEquals(set.size(), 2);
+ assertTrue(set.containsAll(Arrays.asList("A", "C")));
+ assertFalse(set.retainAll(Arrays.asList("A", "C")));
+ assertEquals(set.size(), 2);
+ assertTrue(set.containsAll(Arrays.asList("A", "C")));
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java
index 54b354e..c175d0b 100644
--- a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java
+++ b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java
@@ -16,62 +16,212 @@
package libcore.java.util.concurrent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentNavigableMap;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
import libcore.java.util.MapDefaultMethodTester;
-public class ConcurrentSkipListMapTest extends junit.framework.TestCase {
+@RunWith(JUnit4.class)
+public class ConcurrentSkipListMapTest {
- public void test_getOrDefault() {
+ @Test
+ public void testGetOrDefault() {
MapDefaultMethodTester.test_getOrDefault(new ConcurrentSkipListMap<>(),
false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/,
false /*getAcceptsAnyObject*/);
}
- public void test_forEach() {
+ @Test
+ public void testForEach() {
MapDefaultMethodTester.test_forEach(new ConcurrentSkipListMap<>());
}
- public void test_putIfAbsent() {
+ @Test
+ public void testPutIfAbsent() {
MapDefaultMethodTester
.test_putIfAbsent(new ConcurrentSkipListMap<>(), false /*doesNotAcceptNullKey*/,
false /*doesNotAcceptNullValue*/);
}
- public void test_remove() {
+ @Test
+ public void testRemove() {
MapDefaultMethodTester
.test_remove(new ConcurrentSkipListMap<>(), false /*doesNotAcceptNullKey*/,
false /*doesNotAcceptNullValue*/);
}
- public void test_replace$K$V$V() {
+ @Test
+ public void testReplace$K$V$V() {
MapDefaultMethodTester
.test_replace$K$V$V(new ConcurrentSkipListMap<>(), false /*doesNotAcceptNullKey*/,
false /*doesNotAcceptNullValue*/);
}
- public void test_replace$K$V() {
+ @Test
+ public void testReplace$K$V() {
MapDefaultMethodTester.test_replace$K$V(new ConcurrentSkipListMap<>(),
false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
}
- public void test_computeIfAbsent() {
+ @Test
+ public void testComputeIfAbsent() {
MapDefaultMethodTester.test_computeIfAbsent(new ConcurrentSkipListMap<>(),
false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
}
- public void test_computeIfPresent() {
+ @Test
+ public void testComputeIfPresent() {
MapDefaultMethodTester.test_computeIfPresent(new ConcurrentSkipListMap<>(),
false /*doesNotAcceptNullKey*/);
}
- public void test_compute() {
+ @Test
+ public void testCompute() {
MapDefaultMethodTester.test_compute(new ConcurrentSkipListMap<>(),
false /*doesNotAcceptNullKey*/);
}
- public void test_merge() {
+ @Test
+ public void testMerge() {
MapDefaultMethodTester.test_merge(new ConcurrentSkipListMap<>(),
false /*doesNotAcceptNullKey*/);
}
+
+ private ConcurrentSkipListMap createPopulatedMap() {
+ ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+ map.put("A", "a");
+ map.put("B", "b");
+ map.put("C", "c");
+ map.put("D", "d");
+ map.put("E", "e");
+ map.put("F", "f");
+ assertFalse(map.isEmpty());
+ return map;
+ }
+
+ @Test
+ public void testCloneFromSorted() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentSkipListMap mapClone = map.clone();
+ assertNotSame(map, mapClone);
+ Set set = map.entrySet();
+ Set setOfClone = mapClone.entrySet();
+ Iterator it = set.iterator();
+ Iterator itOfClone = setOfClone.iterator();
+ while ( it.hasNext() && itOfClone.hasNext() ) {
+ Map.Entry entry = (Map.Entry) it.next();
+ Map.Entry entryOfClone = (Map.Entry) itOfClone.next();
+ assertSame(entry.getKey(), entryOfClone.getKey());
+ assertSame(entry.getValue(), entryOfClone.getValue());
+ }
+ assertFalse(it.hasNext());
+ assertFalse(itOfClone.hasNext());
+ }
+
+ @Test
+ public void testFirstEntry() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ assertEquals("A", map.firstEntry().getKey());
+ assertEquals("a", map.firstEntry().getValue());
+ }
+
+ @Test
+ public void testLastEntry() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ assertEquals("F", map.lastEntry().getKey());
+ assertEquals("f", map.lastEntry().getValue());
+ }
+
+ @Test
+ public void testSubMap() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentNavigableMap subMap = map.subMap("B", "D");
+ assertEquals(2, subMap.size());
+ assertFalse(subMap.containsKey("A"));
+ assertTrue(subMap.containsKey("B"));
+ assertTrue(subMap.containsKey("C"));
+ assertFalse(subMap.containsKey("D"));
+ assertFalse(subMap.containsKey("E"));
+ assertFalse(subMap.containsKey("F"));
+ }
+
+ @Test
+ public void testSubMapEmpty() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentNavigableMap subMap = map.subMap("A", "A");
+ assertTrue(subMap.isEmpty());
+ assertFalse(subMap.containsKey("A"));
+ assertFalse(subMap.containsKey("B"));
+ assertFalse(subMap.containsKey("C"));
+ assertFalse(subMap.containsKey("D"));
+ assertFalse(subMap.containsKey("E"));
+ assertFalse(subMap.containsKey("F"));
+ }
+
+ @Test
+ public void testHeadMap() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentNavigableMap subMap = map.headMap("D");
+ assertEquals(3, subMap.size());
+ assertTrue(subMap.containsKey("A"));
+ assertTrue(subMap.containsKey("B"));
+ assertTrue(subMap.containsKey("C"));
+ assertFalse(subMap.containsKey("D"));
+ assertFalse(subMap.containsKey("E"));
+ assertFalse(subMap.containsKey("F"));
+ }
+
+ @Test
+ public void testHeadMapEmpty() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentNavigableMap subMap = map.headMap("A");
+ assertTrue(subMap.isEmpty());
+ assertFalse(subMap.containsKey("A"));
+ assertFalse(subMap.containsKey("B"));
+ assertFalse(subMap.containsKey("C"));
+ assertFalse(subMap.containsKey("D"));
+ assertFalse(subMap.containsKey("E"));
+ assertFalse(subMap.containsKey("F"));
+ }
+
+ @Test
+ public void testTailMap() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentNavigableMap subMap = map.tailMap("C");
+ assertEquals(4, subMap.size());
+ assertFalse(subMap.containsKey("A"));
+ assertFalse(subMap.containsKey("B"));
+ assertTrue(subMap.containsKey("C"));
+ assertTrue(subMap.containsKey("D"));
+ assertTrue(subMap.containsKey("E"));
+ assertTrue(subMap.containsKey("F"));
+ }
+
+ @Test
+ public void testTailMapSingleElement() {
+ ConcurrentSkipListMap map = createPopulatedMap();
+ ConcurrentNavigableMap subMap = map.tailMap("F");
+ assertEquals(1, subMap.size());
+ assertFalse(subMap.containsKey("A"));
+ assertFalse(subMap.containsKey("B"));
+ assertFalse(subMap.containsKey("C"));
+ assertFalse(subMap.containsKey("D"));
+ assertFalse(subMap.containsKey("E"));
+ assertTrue(subMap.containsKey("F"));
+ }
+
}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListSetTest.java b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListSetTest.java
new file mode 100644
index 0000000..bd858b0
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListSetTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ConcurrentSkipListSetTest {
+
+ private ConcurrentSkipListSet createPopulatedSet() {
+ ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+ set.add("A");
+ set.add("B");
+ set.add("C");
+ set.add("D");
+ set.add("E");
+ set.add("F");
+ assertFalse(set.isEmpty());
+ return set;
+ }
+
+ @Test
+ public void testConstructorFromSortedSet() {
+ TreeSet treeSet = new TreeSet();
+ treeSet.add("A");
+ treeSet.add("B");
+ treeSet.add("C");
+ treeSet.add("D");
+ treeSet.add("E");
+ treeSet.add("F");
+ ConcurrentSkipListSet skipListSet = new ConcurrentSkipListSet(treeSet);
+ assertEquals(treeSet.size(), skipListSet.size());
+ while (!treeSet.isEmpty()) {
+ assertFalse(skipListSet.isEmpty());
+ assertEquals(treeSet.pollFirst(), skipListSet.pollFirst());
+ }
+ }
+
+ @Test
+ public void testClone() {
+ ConcurrentSkipListSet set = createPopulatedSet();
+ ConcurrentSkipListSet setClone = set.clone();
+ assertNotSame(set, setClone);
+ Iterator it = set.iterator();
+ Iterator itOfClone = setClone.iterator();
+ while (it.hasNext() && itOfClone.hasNext()) {
+ String entry = (String) it.next();
+ String entryOfClone = (String) itOfClone.next();
+ assertSame(entry, entryOfClone);
+ }
+ assertFalse(it.hasNext());
+ assertFalse(itOfClone.hasNext());
+ }
+
+ @Test
+ public void testDescendingIterator() {
+ ConcurrentSkipListSet set = createPopulatedSet();
+ int size = set.size();
+ int i;
+ Iterator it = set.descendingIterator();
+ String lastVal = null;
+ for (i = 0; it.hasNext(); i++) {
+ String val = (String) it.next();
+ assertTrue(set.contains(val));
+ if(lastVal != null) {
+ assertTrue(0 <= lastVal.compareTo(val));
+ }
+ lastVal = val;
+ }
+ assertEquals(i, size);
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java b/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java
index fc783c0..80005df 100644
--- a/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java
+++ b/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java
@@ -101,6 +101,15 @@
assertEquals(Arrays.asList("a", "d"), list);
}
+ public void testRetainAll() {
+ CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
+ list.addAll(Arrays.asList("a", "b", "c", "d", "e"));
+ assertTrue(list.retainAll(Arrays.asList("b", "d")));
+ assertEquals(2, list.size());
+ assertFalse(list.retainAll(Arrays.asList("b", "d")));
+ assertEquals(2, list.size());
+ }
+
public void testSubListClear() {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
list.addAll(Arrays.asList("a", "b", "c", "d", "e"));
diff --git a/luni/src/test/java/libcore/java/util/concurrent/CountedCompleterTest.java b/luni/src/test/java/libcore/java/util/concurrent/CountedCompleterTest.java
new file mode 100644
index 0000000..3f14d14
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/CountedCompleterTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class CountedCompleterTest {
+
+ /**
+ * Exercises the completion of all tasks once one of them has a result.
+ *
+ * Instead of needing all tasks to be performed to get a result, this will only expect one of
+ * them to provide it. That task, given by choiceIndex, will just complete the root completer.
+ * All other tasks will remain "unfinished".
+ *
+ * The result is passed through setRawResult().
+ */
+ private static int chooseOne(Integer[] array, int choiceIndex) {
+ class Task extends CountedCompleter<Integer> {
+ final int lo;
+ final int hi;
+ AtomicInteger ai = new AtomicInteger(0);
+
+ Task(Task parent, int lo, int hi) {
+ super(parent);
+ this.lo = lo;
+ this.hi = hi;
+ }
+
+ @Override
+ public void compute() {
+ if (hi - lo >= 2) {
+ int mid = (lo + hi) >>> 1;
+ // must set pending count before fork
+ setPendingCount(2);
+ new Task(this, mid, hi).fork(); // right child
+ new Task(this, lo, mid).fork(); // left child
+ } else if (hi > lo) {
+ if (choiceIndex == lo) {
+ final CountedCompleter root = getRoot();
+ final Integer val = Integer.valueOf(array[lo]);
+ if (root != null) {
+ root.complete(val);
+ } else {
+ complete(val); // the current task is the root
+ }
+ }
+ }
+ }
+
+ public Integer getRawResult() {
+ return new Integer(ai.intValue());
+ }
+
+ protected void setRawResult(Integer val) {
+ ai.addAndGet(val.intValue());
+ }
+ }
+ return new Task(null, 0, array.length).invoke().intValue();
+ }
+
+ /**
+ * complete marks a task as complete regardless of the pending count.
+ *
+ * The test will only require one task to complete.
+ */
+ @Test
+ public void testRecursiveChoice() {
+ int n = 7;
+ Integer[] a = new Integer[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = i + 1;
+ }
+ for (int chosenOne = 0; chosenOne < n; ++chosenOne) {
+ final int result = chooseOne(a, chosenOne);
+ assertEquals(chosenOne + 1, result);
+ }
+ }
+
+ /**
+ * Forces a task to complete all its children by running them its own pool.
+ *
+ * After a parent task adds its children tasks to it's own pool queue, it uses helpComplete to
+ * ensure that those tasks are run before it returns. As all tasks are queued to the same pool
+ * and the parallelism is set to 1, this will make the pool execute the children tasks from
+ * within the execution of the parent.
+ */
+ private static void completeAllChildren(Integer[] array, Consumer<Integer> action) {
+
+ /**
+ * Leaf task that just runs the action and then completes.
+ */
+ class Task extends CountedCompleter<Integer> {
+ final int idx;
+
+ Task(CountedCompleter<Integer> parent, int idx) {
+ super(parent);
+ this.idx = idx;
+ }
+
+ @Override
+ public void compute() {
+ action.accept(array[idx]);
+ tryComplete();
+ }
+ }
+
+ /**
+ * The parent task that creates and queues its children, then executes them on its own pool
+ * before completing.
+ */
+ class MainTask extends CountedCompleter<Integer> {
+ final ForkJoinPool pool;
+ final int lo;
+ final int hi;
+
+ MainTask(ForkJoinPool pool, int lo, int hi) {
+ super(null);
+ this.pool = pool;
+ this.lo = lo;
+ this.hi = hi;
+ }
+
+ @Override
+ public void compute() {
+ final int count = hi - lo;
+ setPendingCount(count);
+
+ for (int idx = lo; idx < hi; ++idx) {
+ // Do not fork the task, rather add it to the parent's pool so that it is
+ // guaranteed not to be running before this compute() returns, unless
+ // helpComplete() is called.
+ pool.submit(new Task(this, idx));
+ }
+
+ // Make the pool run all the children tasks before moving one
+ helpComplete(count);
+
+ // If helpComplete() worked properly, by this point the pending count should be back
+ // to 0, so the tryComplete will terminate this task. Otherwise, the task will not
+ // get completed.
+ if (getPendingCount() == 0) {
+ tryComplete();
+ }
+ }
+ }
+
+ // Use a pool with parallelism set to 1 so the children tasks cannot run before the main
+ // task, unless helpComplete is used.
+ ForkJoinPool pool = new ForkJoinPool(1);
+ MainTask task = new MainTask(pool, 0, array.length);
+ pool.submit(task);
+ task.join();
+ }
+
+ /**
+ * helpComplete attempts to process at most a given number of unprocessed children tasks.
+ */
+ @Test
+ public void testHelpComplete() {
+ int n = 7;
+ Integer[] a = new Integer[n];
+ for (int i = 0; i < n; i++) {
+ a[i] = i + 1;
+ }
+ AtomicInteger ai = new AtomicInteger(0);
+ // Use an atomic add as the action for each task. This will add all the elements of the
+ // array into the ai variable. Since the elements are between 1 and 7, the number does not
+ // overflow.
+ completeAllChildren(a, ai::addAndGet);
+ assertEquals(n * (n + 1) / 2, ai.get());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ExecutionExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/ExecutionExceptionTest.java
new file mode 100644
index 0000000..d848403
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ExecutionExceptionTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.ExecutionException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class ExecutionExceptionTest {
+
+ // Adding derived class to be able to test the protected constructors
+ private class TestExecutionException extends ExecutionException {
+ public TestExecutionException() {
+ super();
+ }
+ public TestExecutionException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * constructor creates exception without any details
+ */
+ @Test
+ public void testConstructNoMessage() {
+ ExecutionException exception = new TestExecutionException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getCause());
+ }
+
+ /**
+ * constructor creates exception with detail message
+ */
+ @Test
+ public void testConstructWithMessage() {
+ ExecutionException exception = new TestExecutionException("test");
+ assertEquals("test", exception.getMessage());
+ assertNull(exception.getCause());
+ }
+
+ /**
+ * constructor creates exception with detail message and cause
+ */
+ @Test
+ public void testConstructWithMessageAndCause() {
+ Throwable cause = new Exception();
+ ExecutionException exception = new ExecutionException("test", cause);
+ assertEquals("test", exception.getMessage());
+ assertEquals(cause, exception.getCause());
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ExecutorServiceAutoCloseable.java b/luni/src/test/java/libcore/java/util/concurrent/ExecutorServiceAutoCloseable.java
new file mode 100644
index 0000000..2df0b29
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ExecutorServiceAutoCloseable.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+final class ExecutorServiceAutoCloseable implements AutoCloseable {
+ private final ExecutorService service;
+
+ public ExecutorServiceAutoCloseable(ExecutorService service) {
+ this.service = service;
+ }
+
+ @Override
+ public void close() {
+ try {
+ service.shutdown();
+
+ if(!service.awaitTermination(5000, TimeUnit.MILLISECONDS)) {
+ service.shutdownNow();
+ service.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ fail();
+ }
+ } catch(InterruptedException e) {
+ fail("Unexpected InterruptedException: " + e.getMessage());
+ }
+ };
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ExecutorsTest.java b/luni/src/test/java/libcore/java/util/concurrent/ExecutorsTest.java
new file mode 100644
index 0000000..dc44a81
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ExecutorsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ExecutorsTest {
+
+ class TestRunnable implements Runnable {
+ public void run() { }
+ }
+
+ @Test
+ public void testNewWorkStealingPoolDefault() {
+ final ExecutorService e = Executors.newWorkStealingPool();
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(e)) {
+ e.execute(new TestRunnable());
+ e.execute(new TestRunnable());
+ e.execute(new TestRunnable());
+ }
+ }
+
+ @Test
+ public void testNewWorkStealingPoolWithParallelism() {
+ final ExecutorService e = Executors.newWorkStealingPool(2);
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(e)) {
+ e.execute(new TestRunnable());
+ e.execute(new TestRunnable());
+ e.execute(new TestRunnable());
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/FlowTest.java b/luni/src/test/java/libcore/java/util/concurrent/FlowTest.java
new file mode 100644
index 0000000..b6e564b
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/FlowTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.Flow;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class FlowTest {
+
+ @Test
+ /**
+ * defaultBufferSize returns default value for Publisher or Subscriber buffering.
+ */
+ public void testDefaultBufferSize() {
+ // Currently the implementation always returns 256, as documented in the API. If this
+ // changes, the test would need to be adjusted as well. This, at least, can serve as a
+ // reminder to update the documentation.
+ assertEquals(256, Flow.defaultBufferSize());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ForkJoinPoolTest.java b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinPoolTest.java
new file mode 100644
index 0000000..578970e
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinPoolTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ForkJoinPoolTest {
+
+ @Test
+ public void testSubmit() {
+ final ForkJoinPool pool = new ForkJoinPool();
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+ final AtomicInteger result = new AtomicInteger(0);
+ ForkJoinTask task = pool.submit(() -> result.addAndGet(42), result);
+ assertSame(result, task.get());
+ assertEquals(42, result.get());
+ } catch(Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetRunningThreadCount() {
+ final ForkJoinPool pool = new ForkJoinPool();
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+ assertEquals(0, pool.getRunningThreadCount());
+
+ final AtomicInteger value = new AtomicInteger(0);
+ final AtomicBoolean stop = new AtomicBoolean(false);
+ ForkJoinTask task = pool.submit(new Runnable() {
+ public void run() {
+ while(!stop.get()) {
+ value.incrementAndGet();
+ }
+ stop.set(false);
+ }
+ });
+ assertEquals(1, pool.getRunningThreadCount());
+ stop.set(true);
+ task.join();
+ pool.awaitTermination(2000, TimeUnit.MILLISECONDS);
+ assertEquals(0, pool.getRunningThreadCount());
+ } catch(Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ForkJoinTaskTest.java b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinTaskTest.java
new file mode 100644
index 0000000..264aa6a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinTaskTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ForkJoinTaskTest {
+
+ /**
+ * adapt uses a Runnable to perform a task, returning as the result the provided object
+ */
+ @Test
+ public void testAdaptToRunnableWithResult() {
+
+ final AtomicInteger result = new AtomicInteger(0);
+ final ForkJoinTask task = ForkJoinTask.adapt(() -> result.addAndGet(42), result);
+ final ForkJoinPool pool = new ForkJoinPool(1);
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+ pool.execute(task);
+ assertSame(result, task.join());
+ assertEquals(42, result.get());
+ } catch(Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ /**
+ * adapt uses a Callable to perform a task, returning as the result the value returned from the
+ * call() function
+ */
+ @Test
+ public void testAdaptToCallable() {
+
+ Callable callable = () -> { return Integer.valueOf(42); };
+ final ForkJoinTask task = ForkJoinTask.adapt(callable);
+ final ForkJoinPool pool = new ForkJoinPool(1);
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+ pool.execute(task);
+ Integer result = (Integer)task.join();
+ assertEquals(42, result.intValue());
+ } catch(Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ /**
+ * adapt uses a Callable to perform a task, converting any checked exception into
+ * RuntimeException
+ */
+ @Test
+ public void testAdaptToCallableThrowsException() {
+
+ Callable callable = () -> { throw new Exception("Test passed"); };
+ final ForkJoinTask task = ForkJoinTask.adapt(callable);
+ final ForkJoinPool pool = new ForkJoinPool(1);
+ try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+ pool.execute(task);
+ Integer result = (Integer)task.join();
+ fail("Expected RuntimeException");
+ } catch(RuntimeException e) {
+ assertTrue(e.getMessage().contains("Test passed"));
+ } catch(Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/PhaserTest.java b/luni/src/test/java/libcore/java/util/concurrent/PhaserTest.java
new file mode 100644
index 0000000..c489a2f
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/PhaserTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertSame;
+
+import java.util.concurrent.Phaser;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PhaserTest {
+
+ /**
+ * The root ancestor of a phaser should be returned from getRoot
+ */
+ @Test
+ public void testGetRoot() {
+ Phaser root = new Phaser();
+ Phaser parent = new Phaser(root);
+ Phaser child = new Phaser(parent);
+ assertSame(root, root.getRoot());
+ assertSame(root, parent.getRoot());
+ assertSame(root, child.getRoot());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/RecursiveTaskTest.java b/luni/src/test/java/libcore/java/util/concurrent/RecursiveTaskTest.java
new file mode 100644
index 0000000..38d5b45
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/RecursiveTaskTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.time.Duration;
+import java.util.concurrent.RecursiveTask;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RecursiveTaskTest {
+
+ static final long MILLIS_TO_NANO = (1000 * 1000);
+
+ final class SumTask extends RecursiveTask<Integer> {
+ final int value;
+
+ SumTask(int value) {
+ this.value = value;
+ }
+
+ @Override
+ protected Integer compute() {
+ if (value <= 1)
+ return value;
+ SumTask subTask = new SumTask(value - 1);
+ subTask.fork();
+ return subTask.join() + value;
+ }
+
+ public void waitForCompletion(Integer forceResult) {
+ if(!TestUtils.waitWhileTrueOrTimeout(Duration.ofSeconds(2),
+ () -> { return !isDone(); })) {
+ fail("timed out waiting for task completion");
+ }
+ if (forceResult != null) {
+ super.setRawResult(forceResult);
+ }
+ }
+ }
+
+ @Test
+ public void testSetRawResult() {
+ SumTask task = new SumTask(10);
+ final Integer expected = Integer.valueOf(-1);
+ task.fork();
+ task.waitForCompletion(expected);
+ Integer result = task.join();
+ assertSame(expected, result);
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ReentrantReadWriteLockTest.java b/luni/src/test/java/libcore/java/util/concurrent/ReentrantReadWriteLockTest.java
new file mode 100644
index 0000000..4497157
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ReentrantReadWriteLockTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ReentrantReadWriteLockTest {
+
+ class ReadLockRunnable implements Runnable {
+ final ReentrantReadWriteLock lock;
+
+ ReadLockRunnable(ReentrantReadWriteLock lock) {
+ this.lock = lock;
+ }
+
+ @Override
+ public void run() {
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }
+ }
+
+ class WriteLockRunnable implements Runnable {
+ final ReentrantReadWriteLock lock;
+
+ WriteLockRunnable(ReentrantReadWriteLock lock) {
+ this.lock = lock;
+ }
+
+ @Override
+ public void run() {
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ }
+ }
+
+ static class DefaultReentrantReadWriteLock extends ReentrantReadWriteLock {
+
+ DefaultReentrantReadWriteLock() {
+ super();
+ }
+
+ @Override
+ public Collection<Thread> getQueuedReaderThreads() {
+ return super.getQueuedReaderThreads();
+ }
+
+ @Override
+ public Collection<Thread> getQueuedWriterThreads() {
+ return super.getQueuedWriterThreads();
+ }
+ }
+
+ private void waitForQueuedThread(DefaultReentrantReadWriteLock lock, Thread thread) {
+ if(!TestUtils.waitWhileTrueOrTimeout(Duration.ofSeconds(2),
+ () -> { return !lock.hasQueuedThread(thread); })) {
+ fail("timed out waiting for queued thread");
+ }
+ }
+
+ @Test
+ public void testReadLockCondition() {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+ try {
+ final Condition condition = lock.readLock().newCondition();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException success) {
+ } catch (Throwable t) {
+ fail("Unexpected exception: " + t.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetQueuedReaderThreads() {
+ final DefaultReentrantReadWriteLock lock = new DefaultReentrantReadWriteLock();
+ Thread thread1 = new Thread(new ReadLockRunnable(lock));
+ Thread thread2 = new Thread(new ReadLockRunnable(lock));
+ lock.writeLock().lock();
+ assertTrue(lock.getQueuedReaderThreads().isEmpty());
+ thread1.start();
+ waitForQueuedThread(lock, thread1);
+ assertTrue(lock.getQueuedReaderThreads().contains(thread1));
+ thread2.start();
+ waitForQueuedThread(lock, thread2);
+ assertTrue(lock.getQueuedReaderThreads().contains(thread2));
+ lock.writeLock().unlock();
+ TestUtils.joinThreadOrFail(2000, thread1);
+ TestUtils.joinThreadOrFail(2000, thread2);
+ assertTrue(lock.getQueuedReaderThreads().isEmpty());
+ }
+
+ @Test
+ public void testGetQueuedWriterThreads() {
+ final DefaultReentrantReadWriteLock lock = new DefaultReentrantReadWriteLock();
+ Thread thread1 = new Thread(new WriteLockRunnable(lock));
+ Thread thread2 = new Thread(new WriteLockRunnable(lock));
+ lock.writeLock().lock();
+ assertTrue(lock.getQueuedWriterThreads().isEmpty());
+ thread1.start();
+ waitForQueuedThread(lock, thread1);
+ assertTrue(lock.getQueuedWriterThreads().contains(thread1));
+ thread2.start();
+ waitForQueuedThread(lock, thread2);
+ assertTrue(lock.getQueuedWriterThreads().contains(thread2));
+ lock.writeLock().unlock();
+ TestUtils.joinThreadOrFail(2000, thread1);
+ TestUtils.joinThreadOrFail(2000, thread2);
+ assertTrue(lock.getQueuedWriterThreads().isEmpty());
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/RejectedExecutionExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/RejectedExecutionExceptionTest.java
new file mode 100644
index 0000000..14c1408
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/RejectedExecutionExceptionTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.RejectedExecutionException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class RejectedExecutionExceptionTest {
+
+ // Adding derived class to be able to test the protected constructors
+ private class TestExecutionException extends RejectedExecutionException {
+ public TestExecutionException() {
+ super();
+ }
+ public TestExecutionException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * constructor creates exception without any details
+ */
+ @Test
+ public void testConstructDefault() {
+ RejectedExecutionException exception = new TestExecutionException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getCause());
+ }
+
+ /**
+ * constructor creates exception with detail message and cause
+ */
+ @Test
+ public void testConstructWithMessageAndCause() {
+ Throwable cause = new Exception();
+ RejectedExecutionException exception = new RejectedExecutionException("test", cause);
+ assertEquals("test", exception.getMessage());
+ assertEquals(cause, exception.getCause());
+ }
+
+ /**
+ * constructor creates exception with cause
+ */
+ @Test
+ public void testConstructWithCause() {
+ Throwable cause = new Exception("root");
+ RejectedExecutionException exception = new RejectedExecutionException(cause);
+ assertEquals(cause.toString(), exception.getMessage());
+ assertEquals(cause, exception.getCause());
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/TestUtils.java b/luni/src/test/java/libcore/java/util/concurrent/TestUtils.java
new file mode 100644
index 0000000..eaa4330
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/TestUtils.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.concurrent;
+
+import static org.junit.Assert.fail;
+
+import java.time.Duration;
+import java.util.function.BooleanSupplier;
+
+class TestUtils {
+
+ public static final long MILLIS_TO_NANO = (1000 * 1000);
+
+ public static void joinThreadOrFail(long timeoutMillis, Thread thread) {
+ try {
+ thread.join(timeoutMillis);
+ } catch (InterruptedException fail) {
+ fail("InterruptedException when joining thread");
+ } finally {
+ if (thread.getState() != Thread.State.TERMINATED) {
+ thread.interrupt();
+ fail("timed out waiting to join thread");
+ }
+ }
+ }
+
+ public static boolean waitWhileTrueOrTimeout(Duration timeout, BooleanSupplier conditionFn) {
+ Duration startTime = Duration.ofNanos(System.nanoTime());
+ while (conditionFn.getAsBoolean()) {
+ Duration now = Duration.ofNanos(System.nanoTime());
+ if (now.minus(startTime).compareTo(timeout) >= 0) {
+ return false;
+ }
+ Thread.yield();
+ }
+ return true;
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/stream/CollectorsTest.java b/luni/src/test/java/libcore/java/util/stream/CollectorsTest.java
new file mode 100644
index 0000000..afe097c
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/stream/CollectorsTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 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.stream;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import static java.util.stream.Collectors.counting;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.stream.Collector;
+import java.util.stream.Stream;
+
+@RunWith(JUnit4.class)
+public class CollectorsTest {
+
+ @Test
+ public void counting_countsNulls() {
+ long count = Stream.of(null, null, null).collect(counting());
+
+ assertEquals(3, count);
+ }
+
+ @Test
+ public void counting_emptyStream() {
+ assertEquals(0L, (long) Stream.empty().collect(counting()));
+ }
+
+ @Test
+ public void counting_nonEmptyStream() {
+ long count = Stream.of(null, 1, 2, "").collect(counting());
+
+ assertEquals(4, count);
+ }
+
+ @Test
+ public void counting_largeStream() {
+ int size = 10_000_000;
+
+ long actual = Stream.generate(() -> 1)
+ .limit(size)
+ .collect(counting());
+
+ assertEquals(size, actual);
+ }
+
+ @Test
+ public void collectorOf() {
+ Collector<Integer, int[], int[]> sqSumCollector =
+ Collector.of(
+ () -> new int[] {0},
+ (sum, next) -> sum[0] = sum[0] + next * next,
+ (a, b) -> new int[] {a[0] + b[0]},
+ Collector.Characteristics.UNORDERED);
+
+ int[] anArray = new int[] {10};
+ assertSame("Finisher is identity fn", anArray, sqSumCollector.finisher().apply(anArray));
+
+ assertArrayEquals(new int[]{0}, sqSumCollector.supplier().get());
+ assertArrayEquals(new int[] {20}, sqSumCollector.combiner().apply(anArray, anArray));
+
+ sqSumCollector.accumulator().accept(anArray, 10);
+ assertArrayEquals(new int[] {110}, anArray);
+ assertTrue(sqSumCollector.characteristics().contains(Collector.Characteristics.UNORDERED));
+
+ assertArrayEquals(new int[] {30}, Stream.of(1, 2, 3, 4).collect(sqSumCollector));
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/stream/LongStreamTest.java b/luni/src/test/java/libcore/java/util/stream/LongStreamTest.java
new file mode 100644
index 0000000..3c36aa7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/stream/LongStreamTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.stream;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.stream.LongStream;
+
+@RunWith(JUnit4.class)
+public class LongStreamTest {
+
+ private static final int[] TEST_SIZES = {0, 1, 2, 10, 20, 100, 1000};
+
+ @Test
+ public void ofArraysWithDifferentSizes() {
+ for (int size : TEST_SIZES) {
+ long[] sourceArray = generate(size);
+ LongStream stream = LongStream.of(sourceArray);
+
+ long[] destArray = stream.toArray();
+
+ assertFalse("By default stream should be sequential", stream.isParallel());
+ assertNotSame("New array should be generated", sourceArray, destArray);
+ assertArrayEquals(sourceArray, destArray);
+ }
+ }
+
+ @Test
+ public void ofNullArray_shouldThrowNPE() {
+ try {
+ LongStream.of((long[]) null);
+ fail();
+ } catch (NullPointerException ignored) {
+ // expected
+ }
+ }
+
+ private long[] generate(int size) {
+ long[] array = new long[size];
+
+ for (int index = 0; index < size; ++index) {
+ array[index] = index + 1;
+ }
+
+ return array;
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index 2175289..ae07e02 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -26,6 +26,7 @@
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -85,4 +86,40 @@
fail();
} catch(FileNotFoundException expected) {}
}
+
+ /**
+ * cp1251.zip archive has single empty file with cp1251 encoding name.
+ * Its name is 'имя файла'('file name' in Russian), but in cp1251.
+ * It was created using "convmv -f utf-8 -t cp1251 <file> --notest".
+ */
+ public void test_zipFileWith_cp1251_fileNames() throws Exception {
+ String resourceName = "/libcore/java/util/zip/cp1251.zip";
+
+ File tempFile = createTemporaryZipFile();
+ try (
+ InputStream is = ZipFileTest.class.getResourceAsStream(resourceName);
+ FileOutputStream fos = new FileOutputStream(tempFile)) {
+
+ int read;
+ byte[] arr = new byte[1024];
+
+ while ((read = is.read(arr)) > 0) {
+ fos.write(arr, 0, read);
+ }
+ fos.flush();
+
+ Charset cp1251 = Charset.forName("cp1251");
+ try (ZipFile zipFile = new ZipFile(tempFile, cp1251)) {
+ ZipEntry zipEntry = zipFile.entries().nextElement();
+
+ assertEquals("имя файла", zipEntry.getName());
+ }
+
+ try (ZipFile zipFile = new ZipFile(tempFile.getAbsolutePath(), cp1251)) {
+ ZipEntry zipEntry = zipFile.entries().nextElement();
+
+ assertEquals("имя файла", zipEntry.getName());
+ }
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLPermissionTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLPermissionTest.java
new file mode 100644
index 0000000..d0217b4
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLPermissionTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import junit.framework.TestCase;
+
+import javax.net.ssl.SSLPermission;
+
+public final class SSLPermissionTest extends TestCase {
+
+ public void testSslPermissions_constructor_LString() {
+ SSLPermission permission = new SSLPermission("name");
+
+ assertEquals("", permission.getName());
+ assertEquals("", permission.getActions());
+ }
+
+ public void testSslPermission_constructor_LString_LString() {
+ SSLPermission permission = new SSLPermission("name", "actions");
+
+ assertEquals("", permission.getName());
+ assertEquals("", permission.getActions());
+ }
+}
diff --git a/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java b/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java
index 764bad2..405aa84 100644
--- a/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java
+++ b/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java
@@ -70,7 +70,7 @@
@Test public void caseNormalization_key() {
mimeMap = MimeMap.builder()
- .put("application/msWord", Arrays.asList("Doc"))
+ .addMimeMapping("application/msWord", Arrays.asList("Doc"))
.build();
assertEquals("application/msword", mimeMap.guessMimeTypeFromExtension("dOc"));
assertEquals("doc", mimeMap.guessExtensionFromMimeType("appliCATion/mSWOrd"));
@@ -93,7 +93,7 @@
// Known keys for a custom map
mimeMap = MimeMap.builder()
- .put("application/msWord", Arrays.asList("Doc"))
+ .addMimeMapping("application/msWord", Arrays.asList("Doc"))
.build();
assertEquals("doc", mimeMap.guessExtensionFromMimeType("Application/mSWord"));
assertEquals("application/msword", mimeMap.guessMimeTypeFromExtension("DoC"));
@@ -105,7 +105,7 @@
@Test public void unmapped() {
mimeMap = MimeMap.builder()
- .put("mime/test", Arrays.asList("test", "tst"))
+ .addMimeMapping("mime/test", Arrays.asList("test", "tst"))
.build();
assertNull(mimeMap.guessExtensionFromMimeType("mime/unknown"));
assertFalse(mimeMap.hasMimeType("mime/unknown"));
@@ -122,7 +122,7 @@
MimeMap originalDefault = MimeMap.getDefault();
try {
// Constructs a new instance every time it is called
- MimeMap.setDefaultSupplier(() -> MimeMap.builder().put("mime/sup", "sup").build());
+ MimeMap.setDefaultSupplier(() -> MimeMap.builder().addMimeMapping("mime/sup", "sup").build());
// Same instance is returned both times
assertSame(MimeMap.getDefault(), MimeMap.getDefault());
// Check that the supplier is in effect
@@ -165,7 +165,7 @@
mimeMap);
mimeMap = mimeMap.buildUpon()
- .put("text/plain", "txt")
+ .addMimeMapping("text/plain", "txt")
.build();
assertMap(
makeMap("text/plain", "txt"),
@@ -173,7 +173,7 @@
mimeMap);
mimeMap = mimeMap.buildUpon()
- .put("audio/mpeg", Arrays.asList("mp2", "mp3"))
+ .addMimeMapping("audio/mpeg", Arrays.asList("mp2", "mp3"))
.build();
assertMap(
makeMap("audio/mpeg", "mp2",
@@ -184,7 +184,7 @@
mimeMap);
mimeMap = mimeMap.buildUpon()
- .put("text/plain", "text")
+ .addMimeMapping("text/plain", "text")
.build();
assertMap(
makeMap("audio/mpeg", "mp2",
@@ -198,12 +198,12 @@
@Test public void put() {
MimeMap a = MimeMap.builder()
- .put("text/plain", Arrays.asList("txt", "text"))
- .put("application/msword", "doc")
+ .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+ .addMimeMapping("application/msword", "doc")
.build();
MimeMap b = MimeMap.builder()
- .put("text/plain", Arrays.asList("txt", "text"))
- .put("application/msword", "doc")
+ .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+ .addMimeMapping("application/msword", "doc")
.build();
assertEqualsButNotSame(a, b);
assertEqualsButNotSame(a, a.buildUpon().build());
@@ -219,7 +219,7 @@
@Test public void put_noExtensions() {
checkPut_noExtensions(emptyMap);
- checkPut_noExtensions(MimeMap.builder().put("text/plain", "txt").build());
+ checkPut_noExtensions(MimeMap.builder().addMimeMapping("text/plain", "txt").build());
checkPut_noExtensions(mimeMap);
}
@@ -228,7 +228,7 @@
*/
private static void checkPut_noExtensions(MimeMap baseMap) {
MimeMap mimeMap = baseMap.buildUpon()
- .put("mime/type", Collections.emptyList())
+ .addMimeMapping("mime/type", Collections.emptyList())
.build();
assertEquals(baseMap, mimeMap);
}
@@ -249,11 +249,11 @@
}
@Test public void put_String_String_nullOrEmpty() {
- assertThrowsNpe(() -> MimeMap.builder().put(null, "ext"));
- assertThrowsIae(() -> MimeMap.builder().put("", "ext"));
+ assertThrowsNpe(() -> MimeMap.builder().addMimeMapping(null, "ext"));
+ assertThrowsIae(() -> MimeMap.builder().addMimeMapping("", "ext"));
- assertThrowsNpe(() -> MimeMap.builder().put("mime/type", (String) null));
- assertThrowsIae(() -> MimeMap.builder().put("mime/type", ""));
+ assertThrowsNpe(() -> MimeMap.builder().addMimeMapping("mime/type", (String) null));
+ assertThrowsIae(() -> MimeMap.builder().addMimeMapping("mime/type", ""));
}
/**
@@ -262,8 +262,8 @@
@Test public void putIfAbsent() {
// Starting from an empty mapping, add a bunch more, some with and some without '?'.
mimeMap = MimeMap.builder()
- .put("?text/plain", "?txt")
- .put("audio/mpeg", Arrays.asList("mpga", "mpega", "?mp2", "mp3"))
+ .addMimeMapping("?text/plain", "?txt")
+ .addMimeMapping("audio/mpeg", Arrays.asList("mpga", "mpega", "?mp2", "mp3"))
.build();
assertEquals("txt", mimeMap.guessExtensionFromMimeType("text/plain"));
assertEquals("text/plain", mimeMap.guessMimeTypeFromExtension("txt"));
@@ -273,14 +273,14 @@
// Override a ext -> MIME mapping without overriding the MIME -> ext mapping.
mimeMap = mimeMap.buildUpon()
- .put("?audio/mpeg", "m4a")
+ .addMimeMapping("?audio/mpeg", "m4a")
.build();
assertEquals("mpga", mimeMap.guessExtensionFromMimeType("audio/mpeg"));
assertEquals("audio/mpeg", mimeMap.guessMimeTypeFromExtension("m4a"));
// Override a MIME -> ext mapping without overriding the ext -> MIME mapping.
mimeMap = mimeMap.buildUpon()
- .put("audio/mpeg", "?txt")
+ .addMimeMapping("audio/mpeg", "?txt")
.build();
assertEquals("txt", mimeMap.guessExtensionFromMimeType("audio/mpeg"));
assertEquals("text/plain", mimeMap.guessMimeTypeFromExtension("txt"));
@@ -307,10 +307,10 @@
@Test public void extensions() {
assertEquals(Collections.emptySet(), emptyMap.extensions());
mimeMap = MimeMap.builder()
- .put("text/plain", Arrays.asList("txt", "text"))
- .put("audi/mpeg", "m4a")
- .put("application/msword", "doc")
- .put("text/plain", "tx")
+ .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+ .addMimeMapping("audi/mpeg", "m4a")
+ .addMimeMapping("application/msword", "doc")
+ .addMimeMapping("text/plain", "tx")
.build();
Set<String> extensions = new HashSet<>(Arrays.asList(
"txt", "text", "m4a", "doc", "tx"));
@@ -326,10 +326,10 @@
@Test public void mimeTypes() {
assertEquals(Collections.emptySet(), emptyMap.mimeTypes());
mimeMap = MimeMap.builder()
- .put("text/plain", Arrays.asList("txt", "text"))
- .put("audio/mpeg", "m4a")
- .put("application/msword", "doc")
- .put("text/plain", "tx")
+ .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+ .addMimeMapping("audio/mpeg", "m4a")
+ .addMimeMapping("application/msword", "doc")
+ .addMimeMapping("text/plain", "tx")
.build();
Set<String> mimeTypes = new HashSet<>(Arrays.asList(
"text/plain",
@@ -362,17 +362,17 @@
assertPutThrowsIae("invalidmime", "ext");
// During lookups, wrong arguments return null rather than throwing.
- mimeMap = MimeMap.builder().put("mime/type", "ext").build();
+ mimeMap = MimeMap.builder().addMimeMapping("mime/type", "ext").build();
assertNull(mimeMap.guessExtensionFromMimeType("ext")); // ext is no mime type
assertNull(mimeMap.guessMimeTypeFromExtension("mime/type")); // mime/type is no extension
}
private static void assertPutThrowsNpe(String mime, String... exts) {
- assertThrowsNpe(() -> MimeMap.builder().put(mime, Arrays.asList(exts)));
+ assertThrowsNpe(() -> MimeMap.builder().addMimeMapping(mime, Arrays.asList(exts)));
}
private static void assertPutThrowsIae(final String mime, final String... exts) {
- assertThrowsIae(() -> MimeMap.builder().put(mime, Arrays.asList(exts)));
+ assertThrowsIae(() -> MimeMap.builder().addMimeMapping(mime, Arrays.asList(exts)));
}
private static void assertThrowsNpe(Runnable runnable) {
@@ -393,8 +393,8 @@
@Test public void hashCodeValue() {
assertEquals(0, emptyMap.hashCode());
- MimeMap a = MimeMap.builder().put("mime/test", "test").build();
- MimeMap b = a.buildUpon().put("foo/bar", "baz").build();
+ MimeMap a = MimeMap.builder().addMimeMapping("mime/test", "test").build();
+ MimeMap b = a.buildUpon().addMimeMapping("foo/bar", "baz").build();
assertTrue(0 != a.hashCode());
assertTrue((a.hashCode() != b.hashCode()));
}
@@ -434,13 +434,13 @@
String ext = entry.getKey();
String mime = entry.getValue();
assertEquals(ext + ": " + mimeMap, mime, mimeMap.guessMimeTypeFromExtension(ext));
- expectedBuilder.put("?" + mime, ext);
+ expectedBuilder.addMimeMapping("?" + mime, ext);
}
for (Map.Entry<String, String> entry : expectedMimeToExt.entrySet()) {
String mime = entry.getKey();
String ext = entry.getValue();
assertEquals(mime + ": " + mimeMap, ext, mimeMap.guessExtensionFromMimeType(mime));
- expectedBuilder.put(mime, "?" + ext);
+ expectedBuilder.addMimeMapping(mime, "?" + ext);
}
// Check that there are no unexpected additional mappings.
assertEqualsButNotSame(expectedBuilder.build(), mimeMap);
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index adbf399..02da02b 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -233,8 +233,8 @@
"android_fdsan_get_tag_value(long)",
"bind(java.io.FileDescriptor,java.net.InetAddress,int)",
"bind(java.io.FileDescriptor,java.net.SocketAddress)",
- "capget(android.system.StructCapUserHeader)",
- "capset(android.system.StructCapUserHeader,android.system.StructCapUserData[])",
+ "capget(android.system.StructUserCapHeader)",
+ "capset(android.system.StructUserCapHeader,android.system.StructUserCapData[])",
"dup(java.io.FileDescriptor)",
"dup2(java.io.FileDescriptor,int)",
"environ()",
diff --git a/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java b/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
index e5ef07c..9190452 100644
--- a/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
+++ b/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
@@ -61,11 +61,11 @@
assertEquals("Native bytes already allocated", 0, nativeBytes);
long max = Runtime.getRuntime().maxMemory();
long total = Runtime.getRuntime().totalMemory();
- int size = 1024*1024;
- final int nativeSize = size/2;
- int javaSize = size/2;
- int expectedMaxNumAllocations = (int)(max-total)/javaSize;
- int numSavedAllocations = expectedMaxNumAllocations/2;
+ int size = 1024 * 1024;
+ final int nativeSize = size / 2;
+ int javaSize = size / 2;
+ int expectedMaxNumAllocations = (int)(max-total) / javaSize;
+ int numSavedAllocations = expectedMaxNumAllocations / 2;
Allocation[] saved = new Allocation[numSavedAllocations];
NativeAllocationRegistry registry = null;
@@ -90,21 +90,31 @@
alloc.nativeAllocation = doNativeAllocation(nativeSize);
registry.registerNativeAllocation(alloc, alloc.nativeAllocation);
- saved[i%numSavedAllocations] = alloc;
+ saved[i % numSavedAllocations] = alloc;
}
- // Verify most of the allocations have been freed.
- // Since we use fairly large Java objects, this doesn't test the GC triggering
- // effect; we do that elsewhere.
- // Since native and java objects have the same size, and we can only have max
- // Java bytes in use, there should be no more than max native bytes in use,
- // once all enqueued deallocations have been processed. First make sure
- // that the ReferenceQueueDaemon has processed all pending requests, and then
- // check.
+ // Verify most of the allocations have been freed. Since we use fairly large Java
+ // objects, this doesn't test the GC triggering effect; we do that elsewhere.
+ //
+ // Since native and java objects have the same size, and we can only have max Java bytes
+ // in use, there should ideally be no more than max native bytes in use, once all enqueued
+ // deallocations have been processed. We call runFinalization() to make sure that the
+ // ReferenceQueueDaemon has processed all pending requests, and then check.
+ // (runFinalization() isn't documented to guarantee this, but it waits for a sentinel
+ // object to make it all the way through the pending reference queue, and hence has that
+ // effect.)
+ //
+ // However the garbage collector enqueues references asynchronously, by enqueuing
+ // another heap task. If the GC runs before we finish our allocation, but reference
+ // enqueueing is delayed, and runFinalization() runs between the time the GC reclaims
+ // memory and the references are enqueued, then runFinalization() may complete
+ // immediately, and further allocation may have occurred between the GC and the invocation
+ // of runFinalization(). Thus, under unlikely conditions, we may see up to twice as much
+ // native memory as the Java heap, and that's the actual condition we test.
System.runFinalization();
nativeBytes = getNumNativeBytesAllocated();
assertTrue("Excessive native bytes still allocated (" + nativeBytes + ")"
- + " given max memory of (" + max + ")", nativeBytes <= max);
+ + " given max memory of (" + max + ")", nativeBytes <= 2 * max);
// Check that the array is fully populated, and sufficiently many native bytes
// are live.
long nativeReachableBytes = numSavedAllocations * nativeSize;
diff --git a/luni/src/test/resources/libcore/java/util/zip/cp1251.zip b/luni/src/test/resources/libcore/java/util/zip/cp1251.zip
new file mode 100644
index 0000000..30426f9
--- /dev/null
+++ b/luni/src/test/resources/libcore/java/util/zip/cp1251.zip
Binary files differ
diff --git a/mmodules/core_platform_api/api/legacy_platform/current.txt b/mmodules/core_platform_api/api/legacy_platform/current.txt
index 368bfa6..a915845 100644
--- a/mmodules/core_platform_api/api/legacy_platform/current.txt
+++ b/mmodules/core_platform_api/api/legacy_platform/current.txt
@@ -2,25 +2,25 @@
package android.compat {
public final class Compatibility {
+ method public static void clearBehaviorChangeDelegate();
method public static void clearOverrides();
method public static boolean isChangeEnabled(long);
- method public static void reportChange(long);
- method public static void setCallbacks(android.compat.Compatibility.Callbacks);
+ method public static void reportUnconditionalChange(long);
+ method public static void setBehaviorChangeDelegate(android.compat.Compatibility.BehaviorChangeDelegate);
method public static void setOverrides(android.compat.Compatibility.ChangeConfig);
}
- public static class Compatibility.Callbacks {
- ctor protected Compatibility.Callbacks();
- method protected boolean isChangeEnabled(long);
- method protected void reportChange(long);
+ public static interface Compatibility.BehaviorChangeDelegate {
+ method public default boolean isChangeEnabled(long);
+ method public default void onChangeReported(long);
}
public static final class Compatibility.ChangeConfig {
- ctor public Compatibility.ChangeConfig(java.util.Set<java.lang.Long>, java.util.Set<java.lang.Long>);
- method public long[] forceDisabledChangesArray();
- method public java.util.Set<java.lang.Long> forceDisabledSet();
- method public long[] forceEnabledChangesArray();
- method public java.util.Set<java.lang.Long> forceEnabledSet();
+ ctor public Compatibility.ChangeConfig(@NonNull java.util.Set<java.lang.Long>, @NonNull java.util.Set<java.lang.Long>);
+ method @NonNull public long[] getDisabledChangesArray();
+ method @NonNull public java.util.Set<java.lang.Long> getDisabledSet();
+ method @NonNull public long[] getEnabledChangesArray();
+ method @NonNull public java.util.Set<java.lang.Long> getEnabledSet();
method public boolean isEmpty();
method public boolean isForceDisabled(long);
method public boolean isForceEnabled(long);
@@ -37,8 +37,8 @@
}
public final class Os {
- method @Nullable public static android.system.StructCapUserData[] capget(@NonNull android.system.StructCapUserHeader) throws android.system.ErrnoException;
- method public static void capset(@NonNull android.system.StructCapUserHeader, @NonNull android.system.StructCapUserData[]) throws android.system.ErrnoException;
+ method @Nullable public static android.system.StructUserCapData[] capget(@NonNull android.system.StructUserCapHeader) throws android.system.ErrnoException;
+ method public static void capset(@NonNull android.system.StructUserCapHeader, @NonNull android.system.StructUserCapData[]) throws android.system.ErrnoException;
method public static int getpgid(int) throws android.system.ErrnoException;
method @Nullable public static android.system.StructRlimit getrlimit(int) throws android.system.ErrnoException;
method public static int getsockoptInt(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
@@ -80,25 +80,19 @@
ctor public PacketSocketAddress(int, int, byte[]);
}
- public final class StructCapUserData {
- ctor public StructCapUserData(int, int, int);
+ public final class StructRlimit {
+ field public final long rlim_cur;
+ }
+
+ public final class StructUserCapData {
+ ctor public StructUserCapData(int, int, int);
field public final int effective;
field public final int inheritable;
field public final int permitted;
}
- public final class StructCapUserHeader {
- ctor public StructCapUserHeader(int, int);
- }
-
- public final class StructLinger {
- ctor public StructLinger(int, int);
- method public boolean isOn();
- field public final int l_linger;
- }
-
- public final class StructRlimit {
- field public final long rlim_cur;
+ public final class StructUserCapHeader {
+ ctor public StructUserCapHeader(int, int);
}
public final class UnixSocketAddress extends java.net.SocketAddress {
@@ -188,15 +182,15 @@
}
public class BaseDexClassLoader extends java.lang.ClassLoader {
- method public void addDexPath(String);
- method public void addNativePath(java.util.Collection<java.lang.String>);
- method public String getLdLibraryPath();
+ method public void addDexPath(@Nullable String);
+ method public void addNativePath(@NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public String getLdLibraryPath();
method public void reportClassLoaderChain();
- method public static void setReporter(dalvik.system.BaseDexClassLoader.Reporter);
+ method public static void setReporter(@Nullable dalvik.system.BaseDexClassLoader.Reporter);
}
public static interface BaseDexClassLoader.Reporter {
- method public void report(java.util.Map<java.lang.String,java.lang.String>);
+ method public void report(@NonNull java.util.Map<java.lang.String,java.lang.String>);
}
public final class BlockGuard {
@@ -216,7 +210,7 @@
}
public static interface BlockGuard.VmPolicy {
- method public void onPathAccess(String);
+ method public void onPathAccess(@NonNull String);
}
public final class CloseGuard {
@@ -548,8 +542,8 @@
package libcore.content.type {
public final class MimeMap {
- method public libcore.content.type.MimeMap.Builder buildUpon();
- method public static libcore.content.type.MimeMap.Builder builder();
+ method @NonNull public libcore.content.type.MimeMap.Builder buildUpon();
+ method @NonNull public static libcore.content.type.MimeMap.Builder builder();
method @NonNull public java.util.Set<java.lang.String> extensions();
method @NonNull public static libcore.content.type.MimeMap getDefault();
method @Nullable public String guessExtensionFromMimeType(@Nullable String);
@@ -561,17 +555,8 @@
}
public static final class MimeMap.Builder {
- method public libcore.content.type.MimeMap build();
- method public libcore.content.type.MimeMap.Builder put(@NonNull String, @NonNull java.util.List<java.lang.String>);
- }
-
-}
-
-package libcore.internal {
-
- public final class StringPool {
- ctor public StringPool();
- method public String get(char[], int, int);
+ method @NonNull public libcore.content.type.MimeMap.Builder addMimeMapping(@NonNull String, @NonNull java.util.List<java.lang.String>);
+ method @NonNull public libcore.content.type.MimeMap build();
}
}
@@ -671,10 +656,10 @@
}
public class HttpURLConnectionFactory {
- method public static libcore.net.http.HttpURLConnectionFactory createInstance();
- method public java.net.URLConnection openConnection(java.net.URL, javax.net.SocketFactory, java.net.Proxy) throws java.io.IOException;
- method public void setDns(libcore.net.http.Dns);
- method public void setNewConnectionPool(int, long, java.util.concurrent.TimeUnit);
+ method @NonNull public static libcore.net.http.HttpURLConnectionFactory createInstance();
+ method public java.net.URLConnection openConnection(@NonNull java.net.URL, @NonNull javax.net.SocketFactory, @NonNull java.net.Proxy) throws java.io.IOException;
+ method public void setDns(@NonNull libcore.net.http.Dns);
+ method public void setNewConnectionPool(int, long, @NonNull java.util.concurrent.TimeUnit);
}
}
@@ -691,7 +676,7 @@
field public static final String[] STRING;
}
- public class FP16 {
+ public final class FP16 {
method public static short ceil(short);
method public static int compare(short, short);
method public static boolean equals(short, short);
@@ -804,7 +789,7 @@
package org.json {
public class JSONObject {
- method public java.util.Set<java.lang.String> keySet();
+ method @NonNull public java.util.Set<java.lang.String> keySet();
}
}
diff --git a/mmodules/core_platform_api/api/stable_platform/current.txt b/mmodules/core_platform_api/api/stable_platform/current.txt
index dffea52..729e4e7 100644
--- a/mmodules/core_platform_api/api/stable_platform/current.txt
+++ b/mmodules/core_platform_api/api/stable_platform/current.txt
@@ -2,25 +2,25 @@
package android.compat {
public final class Compatibility {
+ method public static void clearBehaviorChangeDelegate();
method public static void clearOverrides();
method public static boolean isChangeEnabled(long);
- method public static void reportChange(long);
- method public static void setCallbacks(android.compat.Compatibility.Callbacks);
+ method public static void reportUnconditionalChange(long);
+ method public static void setBehaviorChangeDelegate(android.compat.Compatibility.BehaviorChangeDelegate);
method public static void setOverrides(android.compat.Compatibility.ChangeConfig);
}
- public static class Compatibility.Callbacks {
- ctor protected Compatibility.Callbacks();
- method protected boolean isChangeEnabled(long);
- method protected void reportChange(long);
+ public static interface Compatibility.BehaviorChangeDelegate {
+ method public default boolean isChangeEnabled(long);
+ method public default void onChangeReported(long);
}
public static final class Compatibility.ChangeConfig {
- ctor public Compatibility.ChangeConfig(java.util.Set<java.lang.Long>, java.util.Set<java.lang.Long>);
- method public long[] forceDisabledChangesArray();
- method public java.util.Set<java.lang.Long> forceDisabledSet();
- method public long[] forceEnabledChangesArray();
- method public java.util.Set<java.lang.Long> forceEnabledSet();
+ ctor public Compatibility.ChangeConfig(@NonNull java.util.Set<java.lang.Long>, @NonNull java.util.Set<java.lang.Long>);
+ method @NonNull public long[] getDisabledChangesArray();
+ method @NonNull public java.util.Set<java.lang.Long> getDisabledSet();
+ method @NonNull public long[] getEnabledChangesArray();
+ method @NonNull public java.util.Set<java.lang.Long> getEnabledSet();
method public boolean isEmpty();
method public boolean isForceDisabled(long);
method public boolean isForceEnabled(long);
@@ -37,8 +37,8 @@
}
public final class Os {
- method @Nullable public static android.system.StructCapUserData[] capget(@NonNull android.system.StructCapUserHeader) throws android.system.ErrnoException;
- method public static void capset(@NonNull android.system.StructCapUserHeader, @NonNull android.system.StructCapUserData[]) throws android.system.ErrnoException;
+ method @Nullable public static android.system.StructUserCapData[] capget(@NonNull android.system.StructUserCapHeader) throws android.system.ErrnoException;
+ method public static void capset(@NonNull android.system.StructUserCapHeader, @NonNull android.system.StructUserCapData[]) throws android.system.ErrnoException;
method public static int getpgid(int) throws android.system.ErrnoException;
method @Nullable public static android.system.StructRlimit getrlimit(int) throws android.system.ErrnoException;
method public static int getsockoptInt(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
@@ -80,25 +80,19 @@
ctor public PacketSocketAddress(int, int, byte[]);
}
- public final class StructCapUserData {
- ctor public StructCapUserData(int, int, int);
+ public final class StructRlimit {
+ field public final long rlim_cur;
+ }
+
+ public final class StructUserCapData {
+ ctor public StructUserCapData(int, int, int);
field public final int effective;
field public final int inheritable;
field public final int permitted;
}
- public final class StructCapUserHeader {
- ctor public StructCapUserHeader(int, int);
- }
-
- public final class StructLinger {
- ctor public StructLinger(int, int);
- method public boolean isOn();
- field public final int l_linger;
- }
-
- public final class StructRlimit {
- field public final long rlim_cur;
+ public final class StructUserCapHeader {
+ ctor public StructUserCapHeader(int, int);
}
public final class UnixSocketAddress extends java.net.SocketAddress {
@@ -126,15 +120,15 @@
}
public class BaseDexClassLoader extends java.lang.ClassLoader {
- method public void addDexPath(String);
- method public void addNativePath(java.util.Collection<java.lang.String>);
- method public String getLdLibraryPath();
+ method public void addDexPath(@Nullable String);
+ method public void addNativePath(@NonNull java.util.Collection<java.lang.String>);
+ method @NonNull public String getLdLibraryPath();
method public void reportClassLoaderChain();
- method public static void setReporter(dalvik.system.BaseDexClassLoader.Reporter);
+ method public static void setReporter(@Nullable dalvik.system.BaseDexClassLoader.Reporter);
}
public static interface BaseDexClassLoader.Reporter {
- method public void report(java.util.Map<java.lang.String,java.lang.String>);
+ method public void report(@NonNull java.util.Map<java.lang.String,java.lang.String>);
}
public final class BlockGuard {
@@ -154,7 +148,7 @@
}
public static interface BlockGuard.VmPolicy {
- method public void onPathAccess(String);
+ method public void onPathAccess(@NonNull String);
}
public final class CloseGuard {
@@ -454,8 +448,8 @@
package libcore.content.type {
public final class MimeMap {
- method public libcore.content.type.MimeMap.Builder buildUpon();
- method public static libcore.content.type.MimeMap.Builder builder();
+ method @NonNull public libcore.content.type.MimeMap.Builder buildUpon();
+ method @NonNull public static libcore.content.type.MimeMap.Builder builder();
method @NonNull public java.util.Set<java.lang.String> extensions();
method @NonNull public static libcore.content.type.MimeMap getDefault();
method @Nullable public String guessExtensionFromMimeType(@Nullable String);
@@ -467,8 +461,8 @@
}
public static final class MimeMap.Builder {
- method public libcore.content.type.MimeMap build();
- method public libcore.content.type.MimeMap.Builder put(@NonNull String, @NonNull java.util.List<java.lang.String>);
+ method @NonNull public libcore.content.type.MimeMap.Builder addMimeMapping(@NonNull String, @NonNull java.util.List<java.lang.String>);
+ method @NonNull public libcore.content.type.MimeMap build();
}
}
@@ -554,21 +548,21 @@
package libcore.net.http {
public interface Dns {
- method public java.util.List<java.net.InetAddress> lookup(String) throws java.net.UnknownHostException;
+ method @NonNull public java.util.List<java.net.InetAddress> lookup(@Nullable String) throws java.net.UnknownHostException;
}
public class HttpURLConnectionFactory {
- method public static libcore.net.http.HttpURLConnectionFactory createInstance();
- method public java.net.URLConnection openConnection(java.net.URL, javax.net.SocketFactory, java.net.Proxy) throws java.io.IOException;
- method public void setDns(libcore.net.http.Dns);
- method public void setNewConnectionPool(int, long, java.util.concurrent.TimeUnit);
+ method @NonNull public static libcore.net.http.HttpURLConnectionFactory createInstance();
+ method public java.net.URLConnection openConnection(@NonNull java.net.URL, @NonNull javax.net.SocketFactory, @NonNull java.net.Proxy) throws java.io.IOException;
+ method public void setDns(@NonNull libcore.net.http.Dns);
+ method public void setNewConnectionPool(int, long, @NonNull java.util.concurrent.TimeUnit);
}
}
package libcore.util {
- public class FP16 {
+ public final class FP16 {
method public static short ceil(short);
method public static int compare(short, short);
method public static boolean equals(short, short);
@@ -643,6 +637,14 @@
}
+package org.json {
+
+ public class JSONObject {
+ method @NonNull public java.util.Set<java.lang.String> keySet();
+ }
+
+}
+
package sun.misc {
public class Cleaner extends java.lang.ref.PhantomReference<java.lang.Object> {
@@ -725,6 +727,7 @@
package sun.security.x509 {
public class AlgorithmId implements java.io.Serializable {
+ ctor public AlgorithmId(sun.security.util.ObjectIdentifier);
method public String getName();
}
diff --git a/mmodules/intracoreapi/api/intra/current.txt b/mmodules/intracoreapi/api/intra/current.txt
index fab4f37..d6676bc 100644
--- a/mmodules/intracoreapi/api/intra/current.txt
+++ b/mmodules/intracoreapi/api/intra/current.txt
@@ -3,15 +3,15 @@
@libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public final class Compatibility {
method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static boolean isChangeEnabled(long);
- method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static void reportChange(long);
+ method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static void reportUnconditionalChange(long);
}
@libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static final class Compatibility.ChangeConfig {
- ctor public Compatibility.ChangeConfig(java.util.Set<java.lang.Long>, java.util.Set<java.lang.Long>);
- method public long[] forceDisabledChangesArray();
- method public java.util.Set<java.lang.Long> forceDisabledSet();
- method public long[] forceEnabledChangesArray();
- method public java.util.Set<java.lang.Long> forceEnabledSet();
+ ctor public Compatibility.ChangeConfig(@NonNull java.util.Set<java.lang.Long>, @NonNull java.util.Set<java.lang.Long>);
+ method @NonNull public long[] getDisabledChangesArray();
+ method @NonNull public java.util.Set<java.lang.Long> getDisabledSet();
+ method @NonNull public long[] getEnabledChangesArray();
+ method @NonNull public java.util.Set<java.lang.Long> getEnabledSet();
method public boolean isEmpty();
method public boolean isForceDisabled(long);
method public boolean isForceEnabled(long);
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 4e37283..8b67ef7 100755
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -138,8 +138,6 @@
"luni/src/main/java/android/system/OsConstants.java",
"luni/src/main/java/android/system/PacketSocketAddress.java",
"luni/src/main/java/android/system/StructAddrinfo.java",
- "luni/src/main/java/android/system/StructCapUserData.java",
- "luni/src/main/java/android/system/StructCapUserHeader.java",
"luni/src/main/java/android/system/StructCmsghdr.java",
"luni/src/main/java/android/system/StructGroupReq.java",
"luni/src/main/java/android/system/StructIfaddrs.java",
@@ -153,6 +151,8 @@
"luni/src/main/java/android/system/StructTimespec.java",
"luni/src/main/java/android/system/StructTimeval.java",
"luni/src/main/java/android/system/StructUcred.java",
+ "luni/src/main/java/android/system/StructUserCapData.java",
+ "luni/src/main/java/android/system/StructUserCapHeader.java",
"luni/src/main/java/android/system/StructUtsname.java",
"luni/src/main/java/android/system/UnixSocketAddress.java",
"luni/src/main/java/android/system/VmSocketAddress.java",
@@ -224,7 +224,6 @@
"luni/src/main/java/libcore/icu/ICU.java",
"luni/src/main/java/libcore/icu/LocaleData.java",
"luni/src/main/java/libcore/icu/TimeZoneNames.java",
- "luni/src/main/java/libcore/internal/StringPool.java",
"luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java",
"luni/src/main/java/libcore/io/ForwardingOs.java",
"luni/src/main/java/libcore/io/IoBridge.java",
@@ -353,6 +352,7 @@
"luni/src/main/java/libcore/icu/CollationKeyICU.java",
"luni/src/main/java/libcore/icu/DateUtilsBridge.java",
"luni/src/main/java/libcore/internal/Java9LanguageFeatures.java",
+ "luni/src/main/java/libcore/internal/StringPool.java",
"luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java",
"luni/src/main/java/libcore/io/BlockGuardOs.java",
"luni/src/main/java/libcore/io/BufferIterator.java",
diff --git a/ojluni/Android.bp b/ojluni/Android.bp
index 12ae7d7..4c9e703 100644
--- a/ojluni/Android.bp
+++ b/ojluni/Android.bp
@@ -12,10 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Phony target that causes the build to check the license file in this
-// directory, detect that it is a GPL license and then copy all the files
-// from this directory and its subdirectories in to the
-// ${OUT}/obj/PACKAGING/gpl_source_intermediates/gpl_source.tgz file.
package {
default_applicable_licenses: ["libcore_ojluni_license"],
}
@@ -48,11 +44,15 @@
],
}
+// Phony target that causes the build to check the license file in this
+// directory, detect that it is a GPL license and then copy all the files
+// from this directory and its subdirectories in to the
+// ${OUT}/obj/PACKAGING/gpl_source_intermediates/gpl_source.tgz file.
phony {
name: "ojluni-phony",
// A phony module must have at least one dependency.
required: [
- "art-notices-for-framework-stubs-jar",
+ "core-all",
],
}
diff --git a/ojluni/annotations/hiddenapi/java/net/InetAddress.java b/ojluni/annotations/hiddenapi/java/net/InetAddress.java
index 2e1376f..4951374 100644
--- a/ojluni/annotations/hiddenapi/java/net/InetAddress.java
+++ b/ojluni/annotations/hiddenapi/java/net/InetAddress.java
@@ -182,7 +182,7 @@
}
@UnsupportedAppUsage(maxTargetSdk = VersionCodes.P, trackingBug = 78686891,
- publicAlternatives = "Use {@link android.net.InetAddresses#isNumericAddress} "
+ publicAlternatives = "Use {@code android.net.InetAddresses#isNumericAddress} "
+ "instead. There is a behavioural difference between the original method and its "
+ "replacement.")
public static boolean isNumeric(java.lang.String address) {
@@ -202,7 +202,7 @@
* @deprecated Use {@code android.net.InetAddresses.parseNumericAddress(String)} instead.
*/
@UnsupportedAppUsage(maxTargetSdk = VersionCodes.P, trackingBug = 78686891,
- publicAlternatives = "Use {@link android.net.InetAddresses#parseNumericAddress} "
+ publicAlternatives = "Use {@code android.net.InetAddresses#parseNumericAddress} "
+ "instead. There is a behavioural difference between the original method and its "
+ "replacement.")
public static java.net.InetAddress parseNumericAddress(java.lang.String numericAddress) {
diff --git a/ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java b/ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java
index dc2baf6..1fc8d82 100644
--- a/ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java
@@ -31,17 +31,17 @@
import sun.security.util.DerEncoder;
import sun.security.util.ObjectIdentifier;
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
@libcore.api.IntraCoreApi
@libcore.api.Hide
public class AlgorithmId implements Serializable, DerEncoder {
- @libcore.api.CorePlatformApi
+ @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
public AlgorithmId(ObjectIdentifier oid) {
throw new RuntimeException("Stub!");
}
- @libcore.api.CorePlatformApi
+ @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
@libcore.api.IntraCoreApi
public String getName() {
throw new RuntimeException("Stub!");
diff --git a/ojluni/src/main/java/java/lang/Deprecated.java b/ojluni/src/main/java/java/lang/Deprecated.java
index 17f9dd9..3735f59 100644
--- a/ojluni/src/main/java/java/lang/Deprecated.java
+++ b/ojluni/src/main/java/java/lang/Deprecated.java
@@ -79,9 +79,7 @@
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
-// Androrid-changed: Modules not supported yet
-// @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
-@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
+@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
/**
* Returns the version in which the annotated element became deprecated.
diff --git a/ojluni/src/main/java/java/net/NetworkInterface.java b/ojluni/src/main/java/java/net/NetworkInterface.java
index e56e0cb..587d19b 100644
--- a/ojluni/src/main/java/java/net/NetworkInterface.java
+++ b/ojluni/src/main/java/java/net/NetworkInterface.java
@@ -37,7 +37,11 @@
import java.util.Map;
import java.util.NoSuchElementException;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.system.StructIfaddrs;
+import dalvik.annotation.compat.VersionCodes;
import libcore.io.IoUtils;
import libcore.io.Libcore;
import sun.security.action.*;
@@ -47,7 +51,7 @@
// Android-note: NetworkInterface has been rewritten to avoid native code.
// Fix upstream bug not returning link-down interfaces. http://b/26238832
-// Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+// Android-added: Document restrictions for non-system apps. http://b/170188668
/**
* This class represents a Network Interface made up of a name,
* and a list of IP addresses assigned to this interface.
@@ -58,13 +62,28 @@
* <p>
* <a name="access-restrictions"></a>Note that information about
* {@link NetworkInterface}s may be restricted. For example, non-system apps
- * with {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R} will only
- * have access to information about {@link NetworkInterface}s that are
+ * will only have access to information about {@link NetworkInterface}s that are
* associated with an {@link InetAddress}.
*
* @since 1.4
*/
public final class NetworkInterface {
+ // Android-added: Anonymized address for apps targeting old API versions. http://b/170188668
+ /**
+ * If this change is enabled, {@link #getHardwareAddress()} returns null when the hardware
+ * address is <a href="#access-restrictions">inaccessible</a>. If the change is disabled, the
+ * default MAC address (02:00:00:00:00:00) is returned instead.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion=VersionCodes.R)
+ static final long RETURN_NULL_HARDWARE_ADDRESS = 170188668L;
+ // The default hardware address is a zeroed-out MAC address with only its
+ // locally-administered bit set, returned to apps targeting older API versions if they would
+ // otherwise see a null MAC address.
+ // Matches android.net.wifi.WifiInfo.DEFAULT_MAC_ADDRESS
+ private static final byte[] DEFAULT_MAC_ADDRESS = {
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
private String name;
private String displayName;
private int index;
@@ -272,7 +291,7 @@
return "".equals(displayName) ? null : displayName;
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Document restrictions for non-system apps. http://b/170188668
/**
* Searches for the network interface with the specified name.
*
@@ -304,7 +323,7 @@
return null;
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Document restrictions for non-system apps. http://b/170188668
/**
* Get a network interface given its index.
*
@@ -373,7 +392,7 @@
return null;
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Document restrictions for non-system apps. http://b/170188668
/**
* Returns all the interfaces on this machine. The {@code Enumeration}
* contains at least one element, possibly representing a loopback
@@ -383,10 +402,8 @@
* NOTE: can use getNetworkInterfaces()+getInetAddresses()
* to obtain all IP addresses for this node
* <p>
- * For non-system apps with
- * {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R}, this
- * method will only return information for {@link NetworkInterface}s that
- * are associated with an {@link InetAddress}.
+ * For non-system apps, this method will only return information for
+ * {@link NetworkInterface}s associated with an {@link InetAddress}.
*
* @return an Enumeration of NetworkInterfaces found on this machine
* that <a href="#access-restrictions">are accessible</a>.
@@ -562,7 +579,7 @@
return (getFlags() & IFF_MULTICAST) != 0;
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Restrictions for non-system apps. http://b/170188668
/**
* Returns the hardware address (usually MAC) of the interface if it
* has one and if it can be accessed given the current privileges.
@@ -574,8 +591,8 @@
* manager is set and the caller does not have the permission
* NetPermission("getNetworkInformation"). For example, this
* method will generally return {@code null} when called by
- * non-system apps having
- * {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R}.
+ * non-system apps (or 02:00:00:00:00:00 for apps having
+ * {@code targetSdkVersion < android.os.Build.VERSION_CODES.R}).
*
* @exception SocketException if an I/O error occurs.
* @since 1.6
@@ -594,6 +611,12 @@
if (ni == null) {
throw new SocketException("NetworkInterface doesn't exist anymore");
}
+ // Return 02:00:00:00:00:00 for apps having a target SDK version < R if they would have
+ // otherwise gotten a null MAC address.
+ if (ni.hardwareAddr == null &&
+ !Compatibility.isChangeEnabled(RETURN_NULL_HARDWARE_ADDRESS)) {
+ return DEFAULT_MAC_ADDRESS.clone();
+ }
return ni.hardwareAddr;
// END Android-changed: Fix upstream not returning link-down interfaces. http://b/26238832
}
diff --git a/ojluni/src/main/java/java/text/SimpleDateFormat.java b/ojluni/src/main/java/java/text/SimpleDateFormat.java
index 718c95f..36a4601 100644
--- a/ojluni/src/main/java/java/text/SimpleDateFormat.java
+++ b/ojluni/src/main/java/java/text/SimpleDateFormat.java
@@ -43,7 +43,7 @@
import android.icu.util.ULocale;
import com.android.icu.text.ExtendedTimeZoneNames;
-import com.android.icu.text.ExtendedTimeZoneNames.MatchedTimeZone;
+import com.android.icu.text.ExtendedTimeZoneNames.Match;
import java.io.IOException;
import java.io.InvalidObjectException;
@@ -2011,27 +2011,26 @@
private int subParseZoneStringFromICU(String text, int start, CalendarBuilder calb) {
String currentTimeZoneID = android.icu.util.TimeZone.getCanonicalID(getTimeZone().getID());
- MatchedTimeZone matchedTimeZone = getExtendedTimeZoneNames().matchName(text, start,
- currentTimeZoneID);
- if (matchedTimeZone == null) {
+ Match matchedName = getExtendedTimeZoneNames().matchName(text, start, currentTimeZoneID);
+ if (matchedName == null) {
// No match found, return error.
return -start;
}
- String tzId = matchedTimeZone.getTzId();
+ String tzId = matchedName.getTzId();
TimeZone newTimeZone = TimeZone.getTimeZone(tzId);
if (!currentTimeZoneID.equals(tzId)) {
setTimeZone(newTimeZone);
}
// Same logic as in subParseZoneStringFromSymbols, see below for details.
- boolean isDst = matchedTimeZone.isDst();
+ boolean isDst = matchedName.isDst();
int dstAmount = isDst ? newTimeZone.getDSTSavings() : 0;
if (!isDst || dstAmount != 0) {
calb.clear(Calendar.ZONE_OFFSET).set(Calendar.DST_OFFSET, dstAmount);
}
- return matchedTimeZone.getMatchLength() + start;
+ return matchedName.getMatchLength() + start;
}
/**
diff --git a/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java
index 5c76697..438ea56 100644
--- a/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java
+++ b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java
@@ -180,6 +180,11 @@
assertEquals(expected.length == 0, actual.isEmpty());
assertEquals(new HashSet<Thread>(actual),
new HashSet<Thread>(Arrays.asList(expected)));
+ // Android-added: Since we check queued threads, also check queued predecessors
+ final boolean expectedQueuedPredecessors =
+ sync.getFirstQueuedThread() != Thread.currentThread() &&
+ sync.hasQueuedThreads();
+ assertEquals(expectedQueuedPredecessors, sync.hasQueuedPredecessors());
}
/**
diff --git a/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java
index 1f79e2c..a1f36ba 100644
--- a/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java
+++ b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java
@@ -183,6 +183,11 @@
assertEquals(expected.length == 0, actual.isEmpty());
assertEquals(new HashSet<Thread>(actual),
new HashSet<Thread>(Arrays.asList(expected)));
+ // Android-added: Since we check queued threads, also check queued predecessors
+ final boolean expectedQueuedPredecessors =
+ sync.getFirstQueuedThread() != Thread.currentThread() &&
+ sync.hasQueuedThreads();
+ assertEquals(expectedQueuedPredecessors, sync.hasQueuedPredecessors());
}
/**
diff --git a/ojluni/src/test/java/util/concurrent/tck/BrokenBarrierExceptionTest.java b/ojluni/src/test/java/util/concurrent/tck/BrokenBarrierExceptionTest.java
deleted file mode 100644
index 88dc86a..0000000
--- a/ojluni/src/test/java/util/concurrent/tck/BrokenBarrierExceptionTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- * Other contributors include Andrew Wright, Jeffrey Hayes,
- * Pat Fisher, Mike Judd.
- */
-
-package test.java.util.concurrent.tck;
-
-import java.util.concurrent.BrokenBarrierException;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class BrokenBarrierExceptionTest extends JSR166TestCase {
- public static void main(String[] args) {
- main(suite(), args);
- }
- public static Test suite() {
- return new TestSuite(BrokenBarrierExceptionTest.class);
- }
-
- /**
- * constructor creates exception with detail message
- */
- public void testConstructWithMessage() {
- BrokenBarrierException exception = new BrokenBarrierException("test");
- assertEquals("test", exception.getMessage());
- assertNull(exception.getCause());
- }
-
-}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CompletionExceptionTest.java b/ojluni/src/test/java/util/concurrent/tck/CompletionExceptionTest.java
deleted file mode 100644
index 0a25ac2..0000000
--- a/ojluni/src/test/java/util/concurrent/tck/CompletionExceptionTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- * Other contributors include Andrew Wright, Jeffrey Hayes,
- * Pat Fisher, Mike Judd.
- */
-
-package test.java.util.concurrent.tck;
-
-import java.util.concurrent.CompletionException;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class CompletionExceptionTest extends JSR166TestCase {
- public static void main(String[] args) {
- main(suite(), args);
- }
- public static Test suite() {
- return new TestSuite(CompletionExceptionTest.class);
- }
-
- // Adding derived class to be able to test the protected constructors
- private class TestCompletionException extends CompletionException {
- public TestCompletionException() {
- super();
- }
- public TestCompletionException(String message) {
- super(message);
- }
- }
-
- /**
- * constructor creates exception without any details
- */
- public void testConstructNoMessage() {
- CompletionException exception = new TestCompletionException();
- assertNull(exception.getMessage());
- assertNull(exception.getCause());
- }
-
- /**
- * constructor creates exception with detail message
- */
- public void testConstructWithMessage() {
- CompletionException exception = new TestCompletionException("test");
- assertEquals("test", exception.getMessage());
- assertNull(exception.getCause());
- }
-
- /**
- * constructor creates exception with detail message and cause
- */
- public void testConstructWithMessageAndCause() {
- Throwable cause = new Exception();
- CompletionException exception = new CompletionException("test", cause);
- assertEquals("test", exception.getMessage());
- assertEquals(cause, exception.getCause());
- }
-}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java
index 25ba7a1..324a5ef 100644
--- a/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java
@@ -49,13 +49,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.ToDoubleBiFunction;
-import java.util.function.ToDoubleFunction;
-import java.util.function.ToIntBiFunction;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongBiFunction;
-import java.util.function.ToLongFunction;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -196,8 +189,7 @@
}
static Set<Integer> populatedSet(int n) {
- // Android-changed: Use the overload of newKeySet with specified initial capacity.
- Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet(n);
+ Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
assertTrue(a.isEmpty());
for (int i = 0; i < n; i++)
assertTrue(a.add(i));
@@ -614,52 +606,6 @@
}
}
- // BEGIN Android-added: More explicit function classes to avoid type inference problems.
- static class IncrementKey implements Function<Map.Entry<Long,Long>, Map.Entry<Long,Long>> {
- public Map.Entry<Long,Long> apply(Map.Entry<Long,Long> in) {
- return new AbstractMap.SimpleEntry<Long,Long>
- (Long.valueOf(in.getKey().longValue() + 1),
- Long.valueOf(1L));
- }
- }
-
- static class KeyAsDouble implements ToDoubleFunction<Map.Entry<Long,Long>> {
- public double applyAsDouble(Map.Entry<Long,Long> in) {
- return in.getKey().doubleValue();
- }
- }
-
- static class KeyAsInt implements ToIntFunction<Map.Entry<Long,Long>> {
- public int applyAsInt(Map.Entry<Long,Long> in) {
- return in.getKey().intValue();
- }
- }
-
- static class KeyAsLong implements ToLongFunction<Map.Entry<Long,Long>> {
- public long applyAsLong(Map.Entry<Long,Long> in) {
- return in.getKey().longValue();
- }
- }
-
- static class IncrementKeyToDouble implements ToDoubleBiFunction<Long, Long> {
- public double applyAsDouble(Long key, Long value) {
- return (key.doubleValue() + 1);
- }
- }
-
- static class IncrementKeyToInt implements ToIntBiFunction<Long, Long> {
- public int applyAsInt(Long key, Long value) {
- return (key.intValue() + 1);
- }
- }
-
- static class IncrementKeyToLong implements ToLongBiFunction<Long, Long> {
- public long applyAsLong(Long key, Long value) {
- return (key.longValue() + 1);
- }
- }
- // END Android-added: More explicit function classes to avoid type inference problems.
-
/**
* forEachKeySequentially traverses all keys
*/
@@ -866,136 +812,6 @@
assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
}
- // BEGIN Android-added: Extra unit tests to cover missing APIs.
- /**
- * transformReduceEntriesSequentially accumulates across all entries
- */
- public void testTransformReduceEntriesSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- Map.Entry<Long,Long> r;
- r = m.reduceEntries(Long.MAX_VALUE, new IncrementKey(), new AddKeys());
- assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * reduceEntriesToDoubleSequentially accumulates across all entries
- */
- public void testReduceEntriesToDoubleSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- double dr = m.reduceEntriesToDouble(Long.MAX_VALUE, new KeyAsDouble(), 0.0, Double::sum);
- assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
- }
-
- /**
- * reduceEntriesToIntSequentially accumulates across all entries
- */
- public void testReduceEntriesToIntSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- int ir = m.reduceEntriesToInt(Long.MAX_VALUE, new KeyAsInt(), 0, Integer::sum);
- assertEquals(ir, (int)SIZE * (SIZE - 1) / 2);
- }
-
- /**
- * reduceEntriesToLongSequentially accumulates across all entries
- */
- public void testReduceEntriesToLongSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- long lr = m.reduceEntriesToLong(Long.MAX_VALUE, new KeyAsLong(), 0L, Long::sum);
- assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
- }
-
- /**
- * transformReduceEntriesToDoubleSequentially accumulates across all entries
- */
- public void testTransformReduceEntriesToDoubleSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- double dr = m.reduceToDouble(Long.MAX_VALUE, new IncrementKeyToDouble(), 0.0, Double::sum);
- assertEquals(dr, (double)SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * transformReduceEntriesToIntSequentially accumulates across all entries
- */
- public void testTransformReduceEntriesToIntSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- int ir = m.reduceToInt(Long.MAX_VALUE, new IncrementKeyToInt(), 0, Integer::sum);
- assertEquals(ir, SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * transformReduceEntriesToLongSequentially accumulates across all entries
- */
- public void testTransformReduceEntriesToLongSequentially() {
- ConcurrentHashMap<Long, Long> m = longMap();
- long lr = m.reduceToLong(Long.MAX_VALUE, new IncrementKeyToLong(), 0L, Long::sum);
- assertEquals(lr, (long)SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * transformReduceEntriesInParallel accumulates across all entries
- */
- public void testTransformReduceEntriesInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- Map.Entry<Long,Long> r;
- r = m.reduceEntries(1L, new IncrementKey(), new AddKeys());
- assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * reduceEntriesToDoubleInParallel accumulates across all entries
- */
- public void testReduceEntriesToDoubleInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- double dr = m.reduceEntriesToDouble(1L, new KeyAsDouble(), 0.0, Double::sum);
- assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
- }
-
- /**
- * reduceEntriesToIntInParallel accumulates across all entries
- */
- public void testReduceEntriesToIntInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- int ir = m.reduceEntriesToInt(1L, new KeyAsInt(), 0, Integer::sum);
- assertEquals(ir, SIZE * (SIZE - 1) / 2);
- }
-
- /**
- * reduceEntriesToLongInParallel accumulates across all entries
- */
- public void testReduceEntriesToLongInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- long lr = m.reduceEntriesToLong(1L, new KeyAsLong(), 0L, Long::sum);
- assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
- }
-
- /**
- * transformReduceEntriesToDoubleInParallel accumulates across all entries
- */
- public void testTransformReduceEntriesToDoubleInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- double dr = m.reduceToDouble(1L, new IncrementKeyToDouble(), 0.0, Double::sum);
- assertEquals(dr, (double)SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * transformReduceEntriesToIntInParallel accumulates across all entries
- */
- public void testTransformReduceEntriesToIntInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- int ir = m.reduceToInt(1L, new IncrementKeyToInt(), 0, Integer::sum);
- assertEquals(ir, SIZE * (SIZE + 1) / 2);
- }
-
- /**
- * transformReduceEntriesToLongInParallel accumulates across all entries
- */
- public void testTransformReduceEntriesToLongInParallel() {
- ConcurrentHashMap<Long, Long> m = longMap();
- long lr = m.reduceToLong(1L, new IncrementKeyToLong(), 0L, Long::sum);
- assertEquals(lr, (long)SIZE * (SIZE + 1) / 2);
- }
- // END Android-added: Extra unit tests to cover missing APIs.
-
/**
* reduceKeysInParallel accumulates across all keys
*/
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java
index 5218e1a..7e8594d 100644
--- a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java
@@ -171,47 +171,6 @@
assertFalse(s.containsAll(Arrays.asList(ar)));
}
- // BEGIN Android-added: Extra unit tests for missing APIs.
- /**
- * clone creates map with a shallow copy of the source map
- */
- public void testCloneFromSorted() {
- ConcurrentSkipListMap map = map5();
- ConcurrentSkipListMap map2 = map.clone();
- assertNotSame(map, map2);
- Set s = map.entrySet();
- Set s2 = map2.entrySet();
- Iterator it = s.iterator();
- Iterator it2 = s2.iterator();
- while(it.hasNext() && it2.hasNext()) {
- Map.Entry e = (Map.Entry) it.next();
- Map.Entry e2 = (Map.Entry) it2.next();
- assertSame(e.getKey(), e2.getKey());
- assertSame(e.getValue(), e2.getValue());
- }
- assertFalse(it.hasNext());
- assertFalse(it2.hasNext());
- }
-
- /**
- * firstEntry returns first key-value entry
- */
- public void testFirstEntry() {
- ConcurrentSkipListMap map = map5();
- assertEquals(one, map.firstEntry().getKey());
- assertEquals("A", map.firstEntry().getValue());
- }
-
- /**
- * lastEntry returns last key-value entry
- */
- public void testLastEntry() {
- ConcurrentSkipListMap map = map5();
- assertEquals(five, map.lastEntry().getKey());
- assertEquals("E", map.lastEntry().getValue());
- }
- // END Android-added: Extra unit tests for missing APIs.
-
/**
* descendingkeySet.toArray returns contains all keys
*/
@@ -888,8 +847,7 @@
*/
public void testSubMapContents() {
ConcurrentSkipListMap map = map5();
- // Android-changed: Use the "default" subMap overload.
- NavigableMap sm = map.subMap(two, four);
+ NavigableMap sm = map.subMap(two, true, four, false);
assertEquals(two, sm.firstKey());
assertEquals(three, sm.lastKey());
assertEquals(2, sm.size());
@@ -927,8 +885,7 @@
public void testSubMapContents2() {
ConcurrentSkipListMap map = map5();
- // Android-changed: Use the "default" subMap overload.
- NavigableMap sm = map.subMap(two, three);
+ NavigableMap sm = map.subMap(two, true, three, false);
assertEquals(1, sm.size());
assertEquals(two, sm.firstKey());
assertEquals(two, sm.lastKey());
@@ -963,8 +920,7 @@
*/
public void testHeadMapContents() {
ConcurrentSkipListMap map = map5();
- // Android-changed: Use the "default" headMap overload.
- NavigableMap sm = map.headMap(four);
+ NavigableMap sm = map.headMap(four, false);
assertTrue(sm.containsKey(one));
assertTrue(sm.containsKey(two));
assertTrue(sm.containsKey(three));
@@ -990,8 +946,7 @@
*/
public void testTailMapContents() {
ConcurrentSkipListMap map = map5();
- // Android-changed: Use the "default" tailMap overload.
- NavigableMap sm = map.tailMap(two);
+ NavigableMap sm = map.tailMap(two, true);
assertFalse(sm.containsKey(one));
assertTrue(sm.containsKey(two));
assertTrue(sm.containsKey(three));
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java
index 4c16ace..d27c10f 100644
--- a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java
@@ -42,7 +42,6 @@
import java.util.Random;
import java.util.Set;
import java.util.SortedSet;
-import java.util.TreeSet;
import java.util.concurrent.ConcurrentSkipListSet;
import junit.framework.Test;
@@ -161,45 +160,6 @@
assertEquals(ints[i], q.pollFirst());
}
- // BEGIN Android-added: Extra unit tests for covering constructor and clone APIs.
- /**
- * A sorted set is used in constructor - the new set will contain the same elements and using the
- * same ordering as the source
- */
- public void testConstructorFromSortedSet() {
- TreeSet ts = new TreeSet();
- ts.add(one);
- ts.add(two);
- ts.add(three);
- ts.add(four);
- ts.add(five);
- ConcurrentSkipListSet q = new ConcurrentSkipListSet(ts);
- assertEquals(ts.size(), q.size());
- while(!ts.isEmpty()) {
- assertFalse(q.isEmpty());
- assertEquals(ts.pollFirst(), q.pollFirst());
- }
- }
-
- /**
- * clone creates set with a shallow copy of the source set
- */
- public void testClone() {
- ConcurrentSkipListSet x = set5();
- ConcurrentSkipListSet y = x.clone();
- assertNotSame(x, y);
- Iterator itX = x.iterator();
- Iterator itY = y.iterator();
- while(itX.hasNext() && itY.hasNext()) {
- Integer iX = (Integer) itX.next();
- Integer iY = (Integer) itY.next();
- assertSame(iX, iY);
- }
- assertFalse(itX.hasNext());
- assertFalse(itY.hasNext());
- }
- // END Android-added: Extra unit tests for covering constructor and clone APIs.
-
/**
* isEmpty is true before add, false after
*/
@@ -548,41 +508,12 @@
ConcurrentSkipListSet q = populatedSet(SIZE);
Iterator it = q.iterator();
int i;
- Integer lastVal = null;
- for (i = 0; it.hasNext(); i++) {
- Integer val = (Integer) it.next();
- assertTrue(q.contains(val));
- if(lastVal != null) {
- assertTrue(0 >= lastVal.compareTo(val));
- }
- lastVal = val;
- }
+ for (i = 0; it.hasNext(); i++)
+ assertTrue(q.contains(it.next()));
assertEquals(i, SIZE);
assertIteratorExhausted(it);
}
- // BEGIN Android-added: Unit test for descending iterator API.
- /**
- * descendingIterator iterates through all elements
- */
- public void testDescendingIterator() {
- ConcurrentSkipListSet q = populatedSet(SIZE);
- Iterator it = q.descendingIterator();
- int i;
- Integer lastVal = null;
- for (i = 0; it.hasNext(); i++) {
- Integer val = (Integer) it.next();
- assertTrue(q.contains(val));
- if(lastVal != null) {
- assertTrue(0 <= lastVal.compareTo(val));
- }
- lastVal = val;
- }
- assertEquals(i, SIZE);
- assertIteratorExhausted(it);
- }
- // END Android-added: Unit test for descending iterator API.
-
/**
* iterator of empty set has no elements
*/
diff --git a/ojluni/src/test/java/util/concurrent/tck/ExecutionExceptionTest.java b/ojluni/src/test/java/util/concurrent/tck/ExecutionExceptionTest.java
deleted file mode 100644
index 7cf1fa1..0000000
--- a/ojluni/src/test/java/util/concurrent/tck/ExecutionExceptionTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- * Other contributors include Andrew Wright, Jeffrey Hayes,
- * Pat Fisher, Mike Judd.
- */
-
-package test.java.util.concurrent.tck;
-
-import java.util.concurrent.ExecutionException;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class ExecutionExceptionTest extends JSR166TestCase {
- public static void main(String[] args) {
- main(suite(), args);
- }
- public static Test suite() {
- return new TestSuite(ExecutionExceptionTest.class);
- }
-
- // Adding derived class to be able to test the protected constructors
- private class TestExecutionException extends ExecutionException {
- public TestExecutionException() {
- super();
- }
- public TestExecutionException(String message) {
- super(message);
- }
- }
-
- /**
- * constructor creates exception without any details
- */
- public void testConstructNoMessage() {
- ExecutionException exception = new TestExecutionException();
- assertNull(exception.getMessage());
- assertNull(exception.getCause());
- }
-
- /**
- * constructor creates exception with detail message
- */
- public void testConstructWithMessage() {
- ExecutionException exception = new TestExecutionException("test");
- assertEquals("test", exception.getMessage());
- assertNull(exception.getCause());
- }
-
- /**
- * constructor creates exception with detail message and cause
- */
- public void testConstructWithMessageAndCause() {
- Throwable cause = new Exception();
- ExecutionException exception = new ExecutionException("test", cause);
- assertEquals("test", exception.getMessage());
- assertEquals(cause, exception.getCause());
- }
-
-}
diff --git a/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java b/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
index 73625db..575a8f3 100644
--- a/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
+++ b/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
@@ -511,8 +511,6 @@
AtomicReferenceFieldUpdaterTest.suite(),
AtomicReferenceTest.suite(),
AtomicStampedReferenceTest.suite(),
- BrokenBarrierExceptionTest.suite(),
- CompletionExceptionTest.suite(),
ConcurrentHashMapTest.suite(),
ConcurrentLinkedDequeTest.suite(),
ConcurrentLinkedQueueTest.suite(),
@@ -528,9 +526,8 @@
DelayQueueTest.suite(),
EntryTest.suite(),
ExchangerTest.suite(),
- ExecutionExceptionTest.suite(),
- ExecutorCompletionServiceTest.suite(),
ExecutorsTest.suite(),
+ ExecutorCompletionServiceTest.suite(),
FutureTaskTest.suite(),
LinkedBlockingDequeTest.suite(),
LinkedBlockingQueueTest.suite(),
@@ -540,9 +537,8 @@
PriorityQueueTest.suite(),
ReentrantLockTest.suite(),
ReentrantReadWriteLockTest.suite(),
- RejectedExecutionExceptionTest.suite(),
- ScheduledExecutorSubclassTest.suite(),
ScheduledExecutorTest.suite(),
+ ScheduledExecutorSubclassTest.suite(),
SemaphoreTest.suite(),
SynchronousQueueTest.suite(),
SystemTest.suite(),
diff --git a/ojluni/src/test/java/util/concurrent/tck/RejectedExecutionExceptionTest.java b/ojluni/src/test/java/util/concurrent/tck/RejectedExecutionExceptionTest.java
deleted file mode 100644
index 4c6e239..0000000
--- a/ojluni/src/test/java/util/concurrent/tck/RejectedExecutionExceptionTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- * Other contributors include Andrew Wright, Jeffrey Hayes,
- * Pat Fisher, Mike Judd.
- */
-
-package test.java.util.concurrent.tck;
-
-import java.util.concurrent.RejectedExecutionException;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class RejectedExecutionExceptionTest extends JSR166TestCase {
- public static void main(String[] args) {
- main(suite(), args);
- }
- public static Test suite() {
- return new TestSuite(RejectedExecutionExceptionTest.class);
- }
-
- // Adding derived class to be able to test the protected constructors
- private class TestExecutionException extends RejectedExecutionException {
- public TestExecutionException() {
- super();
- }
- public TestExecutionException(String message) {
- super(message);
- }
- }
-
- /**
- * constructor creates exception without any details
- */
- public void testConstructDefault() {
- RejectedExecutionException exception = new TestExecutionException();
- assertNull(exception.getMessage());
- assertNull(exception.getCause());
- }
-
- /**
- * constructor creates exception with detail message and cause
- */
- public void testConstructWithMessageAndCause() {
- Throwable cause = new Exception();
- RejectedExecutionException exception = new RejectedExecutionException("test", cause);
- assertEquals("test", exception.getMessage());
- assertEquals(cause, exception.getCause());
- }
-
- /**
- * constructor creates exception with cause
- */
- public void testConstructWithCause() {
- Throwable cause = new Exception("root");
- RejectedExecutionException exception = new RejectedExecutionException(cause);
- assertEquals(cause.toString(), exception.getMessage());
- assertEquals(cause, exception.getCause());
- }
-
-}
diff --git a/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java b/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java
index b526707..4fd3208 100644
--- a/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java
+++ b/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java
@@ -17,7 +17,6 @@
package libcore.junit.util.compat;
import android.compat.Compatibility;
-import android.compat.Compatibility.Callbacks;
import android.compat.Compatibility.ChangeConfig;
import org.junit.rules.TestRule;