Merge "Test that confirms a socket can be closed during connect()"
diff --git a/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java b/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java
index 02d8f97..e84c287 100644
--- a/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java
@@ -18,14 +18,14 @@
import com.google.caliper.SimpleBenchmark;
-import java.util.Locale;
-import java.util.TimeZone;
+import android.icu.util.ULocale;
+import android.icu.util.TimeZone;
import static libcore.icu.DateIntervalFormat.*;
public class DateIntervalFormatBenchmark extends SimpleBenchmark {
public void timeDateIntervalFormat_formatDateRange_DATE(int reps) throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY;
@@ -35,7 +35,7 @@
}
public void timeDateIntervalFormat_formatDateRange_TIME(int reps) throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR;
@@ -45,7 +45,7 @@
}
public void timeDateIntervalFormat_formatDateRange_DATE_TIME(int reps) throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_TIME | FORMAT_24HOUR;
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 4b606e6..59e28e2 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -18,6 +18,8 @@
import java.io.FileDescriptor;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
/**
* Provides access to some VM-specific debug features. Though this class and
@@ -389,4 +391,57 @@
* @param data the array into which the stats are written.
*/
public static native void getHeapSpaceStats(long[] data);
+
+ /* Map from the names of the runtime stats supported by getRuntimeStat() to their IDs */
+ private static final HashMap<String, Integer> runtimeStatsMap = new HashMap<>();
+
+ static {
+ runtimeStatsMap.put("art.gc.gc-count", 0);
+ runtimeStatsMap.put("art.gc.gc-time", 1);
+ runtimeStatsMap.put("art.gc.bytes-allocated", 2);
+ runtimeStatsMap.put("art.gc.bytes-freed", 3);
+ runtimeStatsMap.put("art.gc.blocking-gc-count", 4);
+ 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);
+ }
+
+ /**
+ * Returns the value of a particular runtime statistic or {@code null} if no
+ * such runtime statistic exists.
+ *
+ * @param statName
+ * the name of the runtime statistic to look up.
+ * @return the value of the runtime statistic.
+ */
+ public static String getRuntimeStat(String statName) {
+ if (statName == null) {
+ throw new NullPointerException("statName == null");
+ }
+ Integer statId = runtimeStatsMap.get(statName);
+ if (statId != null) {
+ return getRuntimeStatInternal(statId);
+ }
+ return null;
+ }
+
+ /**
+ * Returns a map of the names/values of the runtime statistics
+ * that {@link #getRuntimeStat()} supports.
+ *
+ * @return a map of the names/values of the supported runtime statistics.
+ */
+ public static Map<String, String> getRuntimeStats() {
+ HashMap<String, String> map = new HashMap<>();
+ String[] values = getRuntimeStatsInternal();
+ for (String name : runtimeStatsMap.keySet()) {
+ int id = runtimeStatsMap.get(name);
+ String value = values[id];
+ map.put(name, value);
+ }
+ return map;
+ }
+
+ private static native String getRuntimeStatInternal(int statId);
+ private static native String[] getRuntimeStatsInternal();
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
index 5cc88f4..77812ed 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
@@ -227,8 +227,8 @@
assertEquals("wrong result 4", ref1.getPath(), file4.getPath());
}
- File ref2 = new File("/lib/content-types.properties");
- File file5 = new File("/", "lib/content-types.properties");
+ File ref2 = new File("/lib/test_112270.properties");
+ File file5 = new File("/", "lib/test_112270.properties");
assertEquals("wrong result 5", ref2.getPath(), file5.getPath());
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java
index 64bfbb3..26403f5 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java
@@ -20,7 +20,7 @@
* @version $Revision$
*/
-package tests.api.javax.security.cert;
+package org.apache.harmony.tests.javax.security.cert;
import junit.framework.Test;
import junit.framework.TestCase;
diff --git a/libart/src/main/java/dalvik/system/VMStack.java b/libart/src/main/java/dalvik/system/VMStack.java
index ee0a0db..b69ab60 100644
--- a/libart/src/main/java/dalvik/system/VMStack.java
+++ b/libart/src/main/java/dalvik/system/VMStack.java
@@ -48,11 +48,10 @@
native public static Class<?> getStackClass2();
/**
- * Returns the first ClassLoader on the call stack that isn't either of
- * the passed-in ClassLoaders.
+ * Returns the first ClassLoader on the call stack that isn't the
+ * bootstrap class loader.
*/
- public native static ClassLoader getClosestUserClassLoader(ClassLoader bootstrap,
- ClassLoader system);
+ public native static ClassLoader getClosestUserClassLoader();
/**
* Retrieves the stack trace from the specified thread.
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index 4ea0bb5..1072ce8 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -124,16 +124,16 @@
private static final long serialVersionUID = 3206093459760846163L;
- /** defining class loader, or NULL for the "bootstrap" system loader. */
+ /** defining class loader, or null for the "bootstrap" system loader. */
private transient ClassLoader classLoader;
/**
* For array classes, the component class object for instanceof/checkcast (for String[][][],
- * this will be String[][]). NULL for non-array classes.
+ * this will be String[][]). null for non-array classes.
*/
private transient Class<?> componentType;
/**
- * DexCache of resolved constant pool entries. Will be null for certain VM-generated classes
+ * DexCache of resolved constant pool entries. Will be null for certain runtime-generated classes
* e.g. arrays and primitive classes.
*/
private transient DexCache dexCache;
@@ -163,7 +163,7 @@
/** Lazily computed name of this class; always prefer calling getName(). */
private transient String name;
- /** The superclass, or NULL if this is java.lang.Object, an interface or primitive type. */
+ /** The superclass, or null if this is java.lang.Object, an interface or primitive type. */
private transient Class<? super T> superClass;
/** If class verify fails, we must return same error on subsequent tries. */
@@ -253,7 +253,8 @@
private transient int status;
private Class() {
- // Prevent this class to be instantiated, instance should be created by JVM only
+ // Prevent this class from being instantiated,
+ // instances should be created by the runtime only.
}
/**
@@ -291,6 +292,9 @@
* If the class has not yet been initialized and {@code shouldInitialize} is true,
* the class will be initialized.
*
+ * <p>If the provided {@code classLoader} is {@code null}, the bootstrap
+ * class loader will be used to load the class.
+ *
* @throws ClassNotFoundException
* if the requested class cannot be found.
* @throws LinkageError
@@ -303,7 +307,7 @@
ClassLoader classLoader) throws ClassNotFoundException {
if (classLoader == null) {
- classLoader = ClassLoader.getSystemClassLoader();
+ classLoader = BootClassLoader.getInstance();
}
// Catch an Exception thrown by the underlying native code. It wraps
// up everything inside a ClassNotFoundException, even if e.g. an
@@ -414,24 +418,7 @@
return null;
}
- ClassLoader loader = getClassLoaderImpl();
- if (loader == null) {
- loader = BootClassLoader.getInstance();
- }
- return loader;
- }
-
- /**
- * This must be provided by the VM vendor, as it is used by other provided
- * class implementations in this package. Outside of this class, it is used
- * by SecurityManager.classLoaderDepth(),
- * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for
- * this Class without doing any security checks. The bootstrap ClassLoader
- * is returned, unlike getClassLoader() which returns null in place of the
- * bootstrap ClassLoader.
- */
- ClassLoader getClassLoaderImpl() {
- ClassLoader loader = classLoader;
+ final ClassLoader loader = classLoader;
return loader == null ? BootClassLoader.getInstance() : loader;
}
@@ -540,30 +527,12 @@
}
/**
- * Returns the constructor with the given parameters if it is defined by this class; null
- * otherwise. This may return a non-public member.
+ * Returns the constructor with the given parameters if it is defined by this class;
+ * {@code null} otherwise. This may return a non-public member.
*
* @param args the types of the parameters to the constructor.
*/
- private Constructor<T> getDeclaredConstructorInternal(Class<?>[] args) {
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (Modifier.isStatic(modifiers)) {
- // skip <clinit> which is a static constructor
- continue;
- }
- if (!Modifier.isConstructor(modifiers)) {
- continue;
- }
- if (!ArtMethod.equalConstructorParameters(m, args)) {
- continue;
- }
- return new Constructor<T>(m);
- }
- }
- return null;
- }
+ private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);
/**
* Returns an array containing {@code Constructor} objects for all public
@@ -574,9 +543,7 @@
* @see #getDeclaredConstructors()
*/
public Constructor<?>[] getConstructors() {
- ArrayList<Constructor<T>> constructors = new ArrayList();
- getDeclaredConstructors(true, constructors);
- return constructors.toArray(new Constructor[constructors.size()]);
+ return getDeclaredConstructorsInternal(true);
}
/**
@@ -588,27 +555,10 @@
* @see #getConstructors()
*/
public Constructor<?>[] getDeclaredConstructors() {
- ArrayList<Constructor<T>> constructors = new ArrayList();
- getDeclaredConstructors(false, constructors);
- return constructors.toArray(new Constructor[constructors.size()]);
+ return getDeclaredConstructorsInternal(false);
}
- private void getDeclaredConstructors(boolean publicOnly, List<Constructor<T>> constructors) {
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (!publicOnly || Modifier.isPublic(modifiers)) {
- if (Modifier.isStatic(modifiers)) {
- // skip <clinit> which is a static constructor
- continue;
- }
- if (Modifier.isConstructor(modifiers)) {
- constructors.add(new Constructor<T>(m));
- }
- }
- }
- }
- }
+ private native Constructor<?>[] getDeclaredConstructorsInternal(boolean publicOnly);
/**
* Returns a {@code Method} object which represents the method matching the
@@ -695,78 +645,13 @@
}
/**
- * Returns the method if it is defined by this class; null otherwise. This may return a
+ * Returns the method if it is defined by this class; {@code null} otherwise. This may return a
* non-public member.
*
* @param name the method name
* @param args the method's parameter types
*/
- private Method getDeclaredMethodInternal(String name, Class<?>[] args) {
- // Covariant return types permit the class to define multiple
- // methods with the same name and parameter types. Prefer to
- // return a non-synthetic method in such situations. We may
- // still return a synthetic method to handle situations like
- // escalated visibility. We never return miranda methods that
- // were synthesized by the VM.
- int skipModifiers = Modifier.MIRANDA | Modifier.SYNTHETIC;
- ArtMethod artMethodResult = null;
- if (virtualMethods != null) {
- for (ArtMethod m : virtualMethods) {
- ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(m);
- String methodName = ArtMethod.getMethodName(nonProxyMethod);
- if (!name.equals(methodName)) {
- continue;
- }
- if (!ArtMethod.equalMethodParameters(nonProxyMethod, args)) {
- continue;
- }
- int modifiers = m.getAccessFlags();
- if ((modifiers & skipModifiers) == 0) {
- return new Method(m);
- }
- if ((modifiers & Modifier.MIRANDA) == 0) {
- // Remember as potential result if it's not a miranda method.
- artMethodResult = m;
- }
- }
- }
- if (artMethodResult == null) {
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (Modifier.isConstructor(modifiers)) {
- continue;
- }
- ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(m);
- String methodName = ArtMethod.getMethodName(nonProxyMethod);
- if (!name.equals(methodName)) {
- continue;
- }
- if (!ArtMethod.equalMethodParameters(nonProxyMethod, args)) {
- continue;
- }
- if ((modifiers & skipModifiers) == 0) {
- return new Method(m);
- }
- // Direct methods cannot be miranda methods,
- // so this potential result must be synthetic.
- artMethodResult = m;
- }
- }
- }
- if (artMethodResult == null) {
- return null;
- }
- return new Method(artMethodResult);
- }
-
- /**
- * Returns the overridden method if the {@code method} is a proxy method,
- * otherwise returns the {@code method}.
- *
- * @hide
- */
- public static native ArtMethod findOverriddenMethodIfProxy(ArtMethod method);
+ private native Method getDeclaredMethodInternal(String name, Class<?>[] args);
/**
* Returns an array containing {@code Method} objects for all methods
@@ -777,11 +662,7 @@
* @see #getMethods()
*/
public Method[] getDeclaredMethods() {
- int initial_size = virtualMethods == null ? 0 : virtualMethods.length;
- initial_size += directMethods == null ? 0 : directMethods.length;
- ArrayList<Method> methods = new ArrayList<Method>(initial_size);
- getDeclaredMethodsUnchecked(false, methods);
- Method[] result = methods.toArray(new Method[methods.size()]);
+ Method[] result = getDeclaredMethodsUnchecked(false);
for (Method m : result) {
// Throw NoClassDefFoundError if types cannot be resolved.
m.getReturnType();
@@ -799,30 +680,7 @@
* @param methods A list to populate with declared methods.
* @hide
*/
- public void getDeclaredMethodsUnchecked(boolean publicOnly, List<Method> methods) {
- if (virtualMethods != null) {
- for (ArtMethod m : virtualMethods) {
- int modifiers = m.getAccessFlags();
- if (!publicOnly || Modifier.isPublic(modifiers)) {
- // Add non-miranda virtual methods.
- if ((modifiers & Modifier.MIRANDA) == 0) {
- methods.add(new Method(m));
- }
- }
- }
- }
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (!publicOnly || Modifier.isPublic(modifiers)) {
- // Add non-constructor direct/static methods.
- if (!Modifier.isConstructor(modifiers)) {
- methods.add(new Method(m));
- }
- }
- }
- }
- }
+ public native Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
/**
* Returns an array containing {@code Method} objects for all public methods
@@ -852,11 +710,11 @@
* superclasses, and all implemented interfaces, including overridden methods.
*/
private void getPublicMethodsInternal(List<Method> result) {
- getDeclaredMethodsUnchecked(true, result);
+ Collections.addAll(result, getDeclaredMethodsUnchecked(true));
if (!isInterface()) {
// Search superclasses, for interfaces don't search java.lang.Object.
for (Class<?> c = superClass; c != null; c = c.superClass) {
- c.getDeclaredMethodsUnchecked(true, result);
+ Collections.addAll(result, c.getDeclaredMethodsUnchecked(true));
}
}
// Search iftable which has a flattened and uniqued list of interfaces.
@@ -864,7 +722,7 @@
if (iftable != null) {
for (int i = 0; i < iftable.length; i += 2) {
Class<?> ifc = (Class<?>) iftable[i];
- ifc.getDeclaredMethodsUnchecked(true, result);
+ Collections.addAll(result, ifc.getDeclaredMethodsUnchecked(true));
}
}
}
@@ -920,7 +778,7 @@
public native Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
/**
- * Returns the field if it is defined by this class; null otherwise. This
+ * Returns the field if it is defined by this class; {@code null} otherwise. This
* may return a non-public member.
*/
private native Field getDeclaredFieldInternal(String name);
@@ -1234,21 +1092,21 @@
}
/**
- * Returns the simple name of a member or local class, or null otherwise.
+ * Returns the simple name of a member or local class, or {@code null} otherwise.
*/
private String getInnerClassName() {
return AnnotationAccess.getInnerClassName(this);
}
/**
- * Returns null.
+ * Returns {@code null}.
*/
public ProtectionDomain getProtectionDomain() {
return null;
}
/**
- * Returns the URL of the given resource, or null if the resource is not found.
+ * Returns the URL of the given resource, or {@code null} if the resource is not found.
* The mapping between the resource name and the URL is managed by the class' class loader.
*
* @see ClassLoader
@@ -1279,8 +1137,8 @@
}
/**
- * Returns a read-only stream for the contents of the given resource, or null if the resource
- * is not found.
+ * Returns a read-only stream for the contents of the given resource, or {@code null} if the
+ * resource is not found.
* The mapping between the resource name and the stream is managed by the class' class loader.
*
* @see ClassLoader
@@ -1311,8 +1169,8 @@
}
/**
- * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
- * All classes from any given dex file will have the same signers, but different dex
+ * Returns {@code null}. (On Android, a {@code ClassLoader} can load classes from multiple dex
+ * files. All classes from any given dex file will have the same signers, but different dex
* files may have different signers. This does not fit well with the original
* {@code ClassLoader}-based model of {@code getSigners}.)
*/
@@ -1542,7 +1400,7 @@
throw new IllegalAccessException(init + " is not accessible from " + caller);
}
try {
- return init.newInstance(null, init.isAccessible());
+ return init.newInstanceTwoFrames();
} catch (InvocationTargetException e) {
SneakyThrow.sneakyThrow(e.getCause());
return null; // Unreachable.
@@ -1603,7 +1461,7 @@
* object was created by the class loader of the class.
*/
public Package getPackage() {
- // TODO This might be a hack, but the VM doesn't have the necessary info.
+ // TODO This might be a hack, but the runtime doesn't have the necessary info.
ClassLoader loader = getClassLoader();
if (loader != null) {
String packageName = getPackageName$();
@@ -1613,7 +1471,7 @@
}
/**
- * Returns the package name of this class. This returns null for classes in
+ * Returns the package name of this class. This returns {@code null} for classes in
* the default package.
*
* @hide
diff --git a/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java
index 0107b6e..a5bf34c 100644
--- a/libart/src/main/java/java/lang/String.java
+++ b/libart/src/main/java/java/lang/String.java
@@ -22,12 +22,12 @@
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
-import java.nio.charset.Charsets;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Formatter;
import java.util.Locale;
import java.util.regex.Pattern;
+import libcore.util.CharsetUtils;
import libcore.util.EmptyArray;
/**
@@ -337,12 +337,12 @@
this.offset = 0;
this.value = new char[byteCount];
this.count = byteCount;
- Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
+ CharsetUtils.isoLatin1BytesToChars(data, offset, byteCount, value);
} else if (canonicalCharsetName.equals("US-ASCII")) {
this.offset = 0;
this.value = new char[byteCount];
this.count = byteCount;
- Charsets.asciiBytesToChars(data, offset, byteCount, value);
+ CharsetUtils.asciiBytesToChars(data, offset, byteCount, value);
} else {
CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
this.offset = 0;
@@ -772,13 +772,13 @@
public byte[] getBytes(Charset charset) {
String canonicalCharsetName = charset.name();
if (canonicalCharsetName.equals("UTF-8")) {
- return Charsets.toUtf8Bytes(value, offset, count);
+ return CharsetUtils.toUtf8Bytes(value, offset, count);
} else if (canonicalCharsetName.equals("ISO-8859-1")) {
- return Charsets.toIsoLatin1Bytes(value, offset, count);
+ return CharsetUtils.toIsoLatin1Bytes(value, offset, count);
} else if (canonicalCharsetName.equals("US-ASCII")) {
- return Charsets.toAsciiBytes(value, offset, count);
+ return CharsetUtils.toAsciiBytes(value, offset, count);
} else if (canonicalCharsetName.equals("UTF-16BE")) {
- return Charsets.toBigEndianUtf16Bytes(value, offset, count);
+ return CharsetUtils.toBigEndianUtf16Bytes(value, offset, count);
} else {
CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
diff --git a/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
index 7e6491d..0ac15f9 100644
--- a/libart/src/main/java/java/lang/reflect/AbstractMethod.java
+++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
@@ -39,28 +39,38 @@
import libcore.reflect.GenericSignatureParser;
import libcore.reflect.ListOfTypes;
import libcore.reflect.Types;
+import libcore.util.EmptyArray;
/**
* This class represents an abstract method. Abstract methods are either methods or constructors.
* @hide
*/
public abstract class AbstractMethod extends AccessibleObject {
+ /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
+ protected int accessFlags;
+
+ /**
+ * The ArtMethod associated with this Method, requried for dispatching due to entrypoints
+ * Hidden to workaround b/16828157.
+ * @hide
+ */
+ protected ArtMethod artMethod;
+
+ /** Method's declaring class */
+ protected Class<?> declaringClass;
+
+ /** Overriden method's declaring class (same as declaringClass unless declaringClass
+ * is a proxy class) */
+ protected Class<?> declaringClassOfOverriddenMethod;
+
+ /** The method index of this method within its defining dex file */
+ protected int dexMethodIndex;
/**
* Hidden to workaround b/16828157.
* @hide
*/
- protected final ArtMethod artMethod;
-
- /**
- * Hidden to workaround b/16828157.
- * @hide
- */
- protected AbstractMethod(ArtMethod artMethod) {
- if (artMethod == null) {
- throw new NullPointerException("artMethod == null");
- }
- this.artMethod = artMethod;
+ protected AbstractMethod() {
}
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
@@ -90,33 +100,33 @@
}
int getModifiers() {
- return fixMethodFlags(artMethod.getAccessFlags());
+ return fixMethodFlags(accessFlags);
}
boolean isVarArgs() {
- return (artMethod.getAccessFlags() & Modifier.VARARGS) != 0;
+ return (accessFlags & Modifier.VARARGS) != 0;
}
boolean isBridge() {
- return (artMethod.getAccessFlags() & Modifier.BRIDGE) != 0;
+ return (accessFlags & Modifier.BRIDGE) != 0;
}
boolean isSynthetic() {
- return (artMethod.getAccessFlags() & Modifier.SYNTHETIC) != 0;
+ return (accessFlags & Modifier.SYNTHETIC) != 0;
}
/**
* @hide
*/
public final int getAccessFlags() {
- return artMethod.getAccessFlags();
+ return accessFlags;
}
/**
* Returns the class that declares this constructor or method.
*/
Class<?> getDeclaringClass() {
- return artMethod.getDeclaringClass();
+ return declaringClass;
}
/**
@@ -125,7 +135,7 @@
* @hide
*/
public final int getDexMethodIndex() {
- return artMethod.getDexMethodIndex();
+ return dexMethodIndex;
}
/**
@@ -144,7 +154,17 @@
* @return the parameter types
*/
Class<?>[] getParameterTypes() {
- return artMethod.getParameterTypes();
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
+ if (types.length == 0) {
+ return EmptyArray.CLASS;
+ }
+ Class<?>[] parametersArray = new Class[types.length];
+ for (int i = 0; i < types.length; i++) {
+ // Note, in the case of a Proxy the dex cache types are equal.
+ parametersArray[i] = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
+ }
+ return parametersArray;
}
/**
@@ -155,8 +175,10 @@
if (!(other instanceof AbstractMethod)) {
return false;
}
- // exactly one instance of each member in this runtime
- return this.artMethod == ((AbstractMethod) other).artMethod;
+ // Exactly one instance of each member in this runtime, todo, does this work for proxies?
+ AbstractMethod otherMethod = (AbstractMethod) other;
+ return this.declaringClass == otherMethod.declaringClass &&
+ this.dexMethodIndex == otherMethod.dexMethodIndex;
}
String toGenericString() {
@@ -252,6 +274,37 @@
parser.returnType, parser.formalTypeParameters);
}
+ protected boolean equalMethodParameters(Class<?>[] params) {
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
+ if (types.length != params.length) {
+ return false;
+ }
+ for (int i = 0; i < types.length; i++) {
+ if (declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]) != params[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected int compareParameters(Class<?>[] params) {
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
+ int length = Math.min(types.length, params.length);
+ for (int i = 0; i < length; i++) {
+ Class<?> aType = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
+ Class<?> bType = params[i];
+ if (aType != bType) {
+ int comparison = aType.getName().compareTo(bType.getName());
+ if (comparison != 0) {
+ return comparison;
+ }
+ }
+ }
+ return types.length - params.length;
+ }
+
/**
* Helper for Method and Constructor for toGenericString
*/
diff --git a/libart/src/main/java/java/lang/reflect/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java
index 3abcb60..84e6b48 100644
--- a/libart/src/main/java/java/lang/reflect/ArtMethod.java
+++ b/libart/src/main/java/java/lang/reflect/ArtMethod.java
@@ -75,103 +75,4 @@
/** Only created by ART directly. */
private ArtMethod() {}
-
- public Class getDeclaringClass() {
- return declaringClass;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- int getDexMethodIndex() {
- return dexMethodIndex;
- }
-
- public static String getMethodName(ArtMethod artMethod) {
- Class<?> declClass = artMethod.getDeclaringClass();
- Dex dex = declClass.getDex();
- int nameIndex = dex.nameIndexFromMethodIndex(artMethod.getDexMethodIndex());
- // Note, in the case of a Proxy the dex cache strings are equal.
- return declClass.getDexCacheString(dex, nameIndex);
- }
-
- /**
- * Returns true if the given parameters match those of the method in the given order.
- *
- * @hide
- */
- public static boolean equalConstructorParameters(ArtMethod artMethod, Class<?>[] params) {
- Class<?> declClass = artMethod.getDeclaringClass();
- Dex dex = declClass.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(artMethod.getDexMethodIndex());
- if (types.length != params.length) {
- return false;
- }
- for (int i = 0; i < types.length; i++) {
- if (declClass.getDexCacheType(dex, types[i]) != params[i]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns true if the given parameters match those of this method in the given order.
- *
- * @hide
- */
- public static boolean equalMethodParameters(ArtMethod artMethod, Class<?>[] params) {
- return equalConstructorParameters(artMethod, params);
- }
-
- Class<?>[] getParameterTypes() {
- Class<?> declClass = getDeclaringClass();
- Dex dex = declClass.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- if (types.length == 0) {
- return EmptyArray.CLASS;
- }
- Class<?>[] parametersArray = new Class[types.length];
- for (int i = 0; i < types.length; i++) {
- // Note, in the case of a Proxy the dex cache types are equal.
- parametersArray[i] = declClass.getDexCacheType(dex, types[i]);
- }
- return parametersArray;
- }
-
- Class<?> getReturnType() {
- Class<?> declClass = getDeclaringClass();
- Dex dex = declClass.getDex();
- int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
- // Note, in the case of a Proxy the dex cache types are equal.
- return declClass.getDexCacheType(dex, returnTypeIndex);
- }
-
- /**
- * Performs a comparison of the parameters to this method with the given parameters.
- *
- * @hide
- */
- int compareParameters(Class<?>[] params) {
- Class<?> declClass = getDeclaringClass();
- Dex dex = declClass.getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- int length = Math.min(types.length, params.length);
- for (int i = 0; i < length; i++) {
- Class<?> aType = declClass.getDexCacheType(dex, types[i]);
- Class<?> bType = params[i];
- if (aType != bType) {
- int comparison = aType.getName().compareTo(bType.getName());
- if (comparison != 0) {
- return comparison;
- }
- }
- }
- return types.length - params.length;
- }
-
- Annotation[][] getParameterAnnotations() {
- return AnnotationAccess.getParameterAnnotations(declaringClass, dexMethodIndex);
- }
}
diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java
index 66ae143..9701147 100644
--- a/libart/src/main/java/java/lang/reflect/Constructor.java
+++ b/libart/src/main/java/java/lang/reflect/Constructor.java
@@ -49,11 +49,7 @@
private static final Comparator<Method> ORDER_BY_SIGNATURE = null; // Unused; must match Method.
- /**
- * @hide
- */
- public Constructor(ArtMethod artMethod) {
- super(artMethod);
+ private Constructor() {
}
public Annotation[] getAnnotations() {
@@ -213,7 +209,8 @@
* @return an array of arrays of {@code Annotation} instances
*/
public Annotation[][] getParameterAnnotations() {
- return artMethod.getParameterAnnotations();
+ return AnnotationAccess.getParameterAnnotations(
+ declaringClassOfOverriddenMethod, dexMethodIndex);
}
/**
@@ -283,13 +280,14 @@
*
* @see AccessibleObject
*/
- public T newInstance(Object... args) throws InstantiationException,
- IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- return newInstance(args, isAccessible());
- }
+ public native T newInstance(Object... args) throws InstantiationException,
+ IllegalAccessException, IllegalArgumentException, InvocationTargetException;
- /** @hide */
- public native T newInstance(Object[] args, boolean accessible) throws InstantiationException,
+ /**
+ * Special version that looks up two frames for access check. Used by Class.newInstance.
+ * @hide
+ */
+ public native T newInstanceTwoFrames(Object... args) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException;
/**
diff --git a/libart/src/main/java/java/lang/reflect/Method.java b/libart/src/main/java/java/lang/reflect/Method.java
index c70e34e..a07ec6f 100644
--- a/libart/src/main/java/java/lang/reflect/Method.java
+++ b/libart/src/main/java/java/lang/reflect/Method.java
@@ -57,8 +57,7 @@
}
int comparison = a.getName().compareTo(b.getName());
if (comparison == 0) {
- comparison = Class.findOverriddenMethodIfProxy(a.artMethod).compareParameters(
- Class.findOverriddenMethodIfProxy(b.artMethod).getParameterTypes());
+ comparison = a.compareParameters(b.getParameterTypes());
if (comparison == 0) {
// This is necessary for methods that have covariant return types.
Class<?> aReturnType = a.getReturnType();
@@ -77,12 +76,7 @@
/**
* @hide
*/
- public Method(ArtMethod artMethod) {
- super(artMethod);
- }
-
- ArtMethod getArtMethod() {
- return artMethod;
+ private Method() {
}
public Annotation[] getAnnotations() {
@@ -136,8 +130,9 @@
* @return the name of this method
*/
@Override public String getName() {
- ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(artMethod);
- return ArtMethod.getMethodName(nonProxyMethod);
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ int nameIndex = dex.nameIndexFromMethodIndex(dexMethodIndex);
+ return declaringClassOfOverriddenMethod.getDexCacheString(dex, nameIndex);
}
/**
@@ -172,7 +167,7 @@
* @return the parameter types
*/
@Override public Class<?>[] getParameterTypes() {
- return Class.findOverriddenMethodIfProxy(artMethod).getParameterTypes();
+ return super.getParameterTypes();
}
/**
@@ -182,9 +177,13 @@
* @return the return type
*/
public Class<?> getReturnType() {
- return Class.findOverriddenMethodIfProxy(artMethod).getReturnType();
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
+ // Note, in the case of a Proxy the dex cache types are equal.
+ return declaringClassOfOverriddenMethod.getDexCacheType(dex, returnTypeIndex);
}
+
/**
* {@inheritDoc}
*
@@ -210,10 +209,7 @@
* @hide needed by Proxy
*/
boolean equalNameAndParameters(Method m) {
- ArtMethod nonProxyThis = Class.findOverriddenMethodIfProxy(this.artMethod);
- ArtMethod nonProxyM = Class.findOverriddenMethodIfProxy(m.artMethod);
- return ArtMethod.getMethodName(nonProxyThis).equals(ArtMethod.getMethodName(nonProxyM)) &&
- ArtMethod.equalMethodParameters(nonProxyThis, nonProxyM.getParameterTypes());
+ return getName().equals(m.getName()) && equalMethodParameters(m.getParameterTypes());
}
/**
@@ -313,7 +309,8 @@
* @return an array of arrays of {@code Annotation} instances
*/
public Annotation[][] getParameterAnnotations() {
- return Class.findOverriddenMethodIfProxy(artMethod).getParameterAnnotations();
+ return AnnotationAccess.getParameterAnnotations(
+ declaringClassOfOverriddenMethod, dexMethodIndex);
}
/**
@@ -370,12 +367,7 @@
* @throws InvocationTargetException
* if an exception was thrown by the invoked method
*/
- public Object invoke(Object receiver, Object... args)
- throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- return invoke(receiver, args, isAccessible());
- }
-
- private native Object invoke(Object receiver, Object[] args, boolean accessible)
+ public native Object invoke(Object receiver, Object... args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
/**
diff --git a/libart/src/main/java/java/lang/reflect/Proxy.java b/libart/src/main/java/java/lang/reflect/Proxy.java
index e47b27b..18ad49c 100755
--- a/libart/src/main/java/java/lang/reflect/Proxy.java
+++ b/libart/src/main/java/java/lang/reflect/Proxy.java
@@ -166,11 +166,7 @@
Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
validateReturnTypes(methods);
List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
-
- ArtMethod[] methodsArray = new ArtMethod[methods.size()];
- for (int i = 0; i < methodsArray.length; i++) {
- methodsArray[i] = methods.get(i).getArtMethod();
- }
+ Method[] methodsArray = methods.toArray(new Method[methods.size()]);
Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
String baseName = commonPackageName != null && !commonPackageName.isEmpty()
@@ -383,7 +379,7 @@
}
private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
- ClassLoader loader, ArtMethod[] methods,
+ ClassLoader loader, Method[] methods,
Class<?>[][] exceptions);
/*
@@ -392,8 +388,8 @@
*/
private static native void constructorPrototype(InvocationHandler h);
- static Object invoke(Proxy proxy, ArtMethod method, Object[] args) throws Throwable {
+ private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
InvocationHandler h = proxy.h;
- return h.invoke(proxy, new Method(method), args);
+ return h.invoke(proxy, method, args);
}
}
diff --git a/luni/src/main/java/java/io/ObjectInputStream.java b/luni/src/main/java/java/io/ObjectInputStream.java
index 3a89b52..c588251 100644
--- a/luni/src/main/java/java/io/ObjectInputStream.java
+++ b/luni/src/main/java/java/io/ObjectInputStream.java
@@ -1977,7 +1977,7 @@
// original/outside caller
if (++nestedLevels == 1) {
// Remember the caller's class loader
- callerClassLoader = VMStack.getClosestUserClassLoader(bootstrapLoader, systemLoader);
+ callerClassLoader = VMStack.getClosestUserClassLoader();
}
result = readNonPrimitiveContent(unshared);
@@ -2014,9 +2014,6 @@
return result;
}
- private static final ClassLoader bootstrapLoader = Object.class.getClassLoader();
- private static final ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
-
/**
* Method to be overridden by subclasses to read the next object from the
* source stream.
diff --git a/luni/src/main/java/java/lang/Package.java b/luni/src/main/java/java/lang/Package.java
index 7e30883..cff01b9 100644
--- a/luni/src/main/java/java/lang/Package.java
+++ b/luni/src/main/java/java/lang/Package.java
@@ -96,7 +96,14 @@
*/
public Annotation[] getAnnotations() {
try {
- Class<?> c = Class.forName(getName() + ".package-info");
+ ClassLoader classLoader = VMStack.getCallingClassLoader();
+ if (classLoader == null) {
+ classLoader = ClassLoader.getSystemClassLoader();
+ }
+ Class<?> c = Class.forName(getName() + ".package-info",
+ // TODO: It is unclear if we need to initialize here.
+ true,
+ classLoader);
return c.getAnnotations();
} catch (Exception ex) {
return NO_ANNOTATIONS;
@@ -175,11 +182,11 @@
* @see ClassLoader#getPackage(java.lang.String)
*/
public static Package getPackage(String packageName) {
- ClassLoader classloader = VMStack.getCallingClassLoader();
- if (classloader == null) {
- classloader = ClassLoader.getSystemClassLoader();
+ ClassLoader classLoader = VMStack.getCallingClassLoader();
+ if (classLoader == null) {
+ classLoader = ClassLoader.getSystemClassLoader();
}
- return classloader.getPackage(packageName);
+ return classLoader.getPackage(packageName);
}
/**
@@ -189,11 +196,11 @@
* @see ClassLoader#getPackages
*/
public static Package[] getPackages() {
- ClassLoader classloader = VMStack.getCallingClassLoader();
- if (classloader == null) {
- classloader = ClassLoader.getSystemClassLoader();
+ ClassLoader classLoader = VMStack.getCallingClassLoader();
+ if (classLoader == null) {
+ classLoader = ClassLoader.getSystemClassLoader();
}
- return classloader.getPackages();
+ return classLoader.getPackages();
}
/**
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index bed9de6..e79f844 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -1176,7 +1176,12 @@
* named by the argument. On Android, this would turn {@code "MyLibrary"} into
* {@code "libMyLibrary.so"}.
*/
- public static native String mapLibraryName(String nickname);
+ public static String mapLibraryName(String nickname) {
+ if (nickname == null) {
+ throw new NullPointerException("nickname == null");
+ }
+ return "lib" + nickname + ".so";
+ }
/**
* Used to set System.err, System.in, and System.out.
diff --git a/luni/src/main/java/java/util/Collections.java b/luni/src/main/java/java/util/Collections.java
index c8a6a73..dc4161f 100644
--- a/luni/src/main/java/java/util/Collections.java
+++ b/luni/src/main/java/java/util/Collections.java
@@ -1426,21 +1426,21 @@
if (!(list instanceof RandomAccess)) {
ListIterator<? extends Comparable<? super T>> it = list.listIterator();
while (it.hasNext()) {
- int result;
- if ((result = -it.next().compareTo(object)) <= 0) {
- if (result == 0) {
- return it.previousIndex();
- }
+ final int result = it.next().compareTo(object);
+ if (result == 0) {
+ return it.previousIndex();
+ } else if (result > 0) {
return -it.previousIndex() - 1;
}
}
return -list.size() - 1;
}
- int low = 0, mid = list.size(), high = mid - 1, result = -1;
+ int low = 0, mid = list.size(), high = mid - 1, result = 1;
while (low <= high) {
mid = (low + high) >>> 1;
- if ((result = -list.get(mid).compareTo(object)) > 0) {
+ result = list.get(mid).compareTo(object);
+ if (result < 0) {
low = mid + 1;
} else if (result == 0) {
return mid;
@@ -1448,7 +1448,7 @@
high = mid - 1;
}
}
- return -mid - (result < 0 ? 1 : 2);
+ return -mid - (result > 0 ? 1 : 2);
}
/**
@@ -1481,21 +1481,21 @@
if (!(list instanceof RandomAccess)) {
ListIterator<? extends T> it = list.listIterator();
while (it.hasNext()) {
- int result;
- if ((result = -comparator.compare(it.next(), object)) <= 0) {
- if (result == 0) {
- return it.previousIndex();
- }
+ final int result = comparator.compare(it.next(), object);
+ if (result == 0) {
+ return it.previousIndex();
+ } else if (result > 0) {
return -it.previousIndex() - 1;
}
}
return -list.size() - 1;
}
- int low = 0, mid = list.size(), high = mid - 1, result = -1;
+ int low = 0, mid = list.size(), high = mid - 1, result = 1;
while (low <= high) {
mid = (low + high) >>> 1;
- if ((result = -comparator.compare(list.get(mid), object)) > 0) {
+ result = comparator.compare(list.get(mid), object);
+ if (result < 0) {
low = mid + 1;
} else if (result == 0) {
return mid;
@@ -1503,7 +1503,7 @@
high = mid - 1;
}
}
- return -mid - (result < 0 ? 1 : 2);
+ return -mid - (result > 0 ? 1 : 2);
}
/**
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index d7adbf2..d7beb91 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -109,7 +109,7 @@
raw = -raw;
}
- String cleanId = String.format("GMT%c%02d:%02d", sign, hour, minute);
+ String cleanId = String.format((Locale) null, "GMT%c%02d:%02d", sign, hour, minute);
return new SimpleTimeZone(raw, cleanId);
}
}
diff --git a/luni/src/main/java/java/util/jar/Manifest.java b/luni/src/main/java/java/util/jar/Manifest.java
index 6a3936d..5a6b42d 100644
--- a/luni/src/main/java/java/util/jar/Manifest.java
+++ b/luni/src/main/java/java/util/jar/Manifest.java
@@ -41,8 +41,10 @@
private static final byte[] VALUE_SEPARATOR = new byte[] { ':', ' ' };
- private final Attributes mainAttributes;
- private final HashMap<String, Attributes> entries;
+ /* non-final for {@code #clone()} */
+ private Attributes mainAttributes;
+ /* non-final for {@code #clone()} */
+ private HashMap<String, Attributes> entries;
static final class Chunk {
final int start;
@@ -93,9 +95,7 @@
*/
@SuppressWarnings("unchecked")
public Manifest(Manifest man) {
- mainAttributes = (Attributes) man.mainAttributes.clone();
- entries = (HashMap<String, Attributes>) ((HashMap<String, Attributes>) man
- .getEntries()).clone();
+ cloneAttributesAndEntriesFrom(man);
}
Manifest(byte[] manifestBytes, boolean readChunks) throws IOException {
@@ -156,7 +156,21 @@
*/
@Override
public Object clone() {
- return new Manifest(this);
+ Manifest result;
+ try {
+ result = (Manifest) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e);
+ }
+
+ result.cloneAttributesAndEntriesFrom(this);
+ return result;
+ }
+
+ private final void cloneAttributesAndEntriesFrom(Manifest other) {
+ mainAttributes = (Attributes) other.mainAttributes.clone();
+ entries = (HashMap<String, Attributes>) ((HashMap<String, Attributes>) other
+ .getEntries()).clone();
}
/**
diff --git a/luni/src/main/java/javax/security/cert/X509Certificate.java b/luni/src/main/java/javax/security/cert/X509Certificate.java
index e85a556..5084ae0 100644
--- a/luni/src/main/java/javax/security/cert/X509Certificate.java
+++ b/luni/src/main/java/javax/security/cert/X509Certificate.java
@@ -51,7 +51,7 @@
String classname = Security.getProperty("cert.provider.x509v1");
Class cl = Class.forName(classname);
constructor = cl.getConstructor(new Class[] {InputStream.class});
- } catch (Throwable e) {
+ } catch (Exception|LinkageError e) {
}
}
@@ -80,7 +80,7 @@
try {
return (X509Certificate)
constructor.newInstance(new Object[] {inStream});
- } catch (Throwable e) {
+ } catch (ReflectiveOperationException e) {
throw new CertificateException(e.getMessage());
}
}
diff --git a/luni/src/main/java/libcore/icu/DateIntervalFormat.java b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
index 96d2ca7..10e3e6a 100644
--- a/luni/src/main/java/libcore/icu/DateIntervalFormat.java
+++ b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
@@ -16,9 +16,12 @@
package libcore.icu;
+import com.ibm.icu.impl.JavaTimeZone;
+import com.ibm.icu.util.Calendar;
+import com.ibm.icu.util.GregorianCalendar;
+import com.ibm.icu.util.ULocale;
+
import java.text.FieldPosition;
-import java.util.Calendar;
-import java.util.Locale;
import java.util.TimeZone;
import libcore.util.BasicLruCache;
@@ -45,9 +48,6 @@
public static final int FORMAT_NUMERIC_DATE = 0x20000;
public static final int FORMAT_ABBREV_ALL = 0x80000;
- private static final int DAY_IN_MS = 24 * 60 * 60 * 1000;
- private static final int EPOCH_JULIAN_DAY = 2440588;
-
private static final FormatterCache CACHED_FORMATTERS = new FormatterCache();
static class FormatterCache extends BasicLruCache<String, com.ibm.icu.text.DateIntervalFormat> {
@@ -64,23 +64,24 @@
if ((flags & FORMAT_UTC) != 0) {
olsonId = "UTC";
}
+ // We create a java.util.TimeZone here to use libcore's data and libcore's olson ID / pseudo-tz
+ // logic.
TimeZone tz = (olsonId != null) ? TimeZone.getTimeZone(olsonId) : TimeZone.getDefault();
- return formatDateRange(Locale.getDefault(), tz, startMs, endMs, flags);
+ com.ibm.icu.util.TimeZone icuTimeZone = icuTimeZone(tz);
+ ULocale icuLocale = ULocale.getDefault();
+ return formatDateRange(icuLocale, icuTimeZone, startMs, endMs, flags);
}
// This is our slightly more sensible internal API. (A truly sane replacement would take a
// skeleton instead of int flags.)
- public static String formatDateRange(Locale locale, TimeZone tz, long startMs, long endMs,
- int flags) {
- Calendar startCalendar = Calendar.getInstance(tz);
- startCalendar.setTimeInMillis(startMs);
-
+ public static String formatDateRange(ULocale icuLocale, com.ibm.icu.util.TimeZone icuTimeZone,
+ long startMs, long endMs, int flags) {
+ Calendar startCalendar = createIcuCalendar(icuTimeZone, icuLocale, startMs);
Calendar endCalendar;
if (startMs == endMs) {
endCalendar = startCalendar;
} else {
- endCalendar = Calendar.getInstance(tz);
- endCalendar.setTimeInMillis(endMs);
+ endCalendar = createIcuCalendar(icuTimeZone, icuLocale, endMs);
}
boolean endsAtMidnight = isMidnight(endCalendar);
@@ -92,27 +93,26 @@
if (startMs != endMs && endsAtMidnight &&
((flags & FORMAT_SHOW_TIME) == 0 || dayDistance(startCalendar, endCalendar) <= 1)) {
endCalendar.roll(Calendar.DAY_OF_MONTH, false);
- endMs -= DAY_IN_MS;
}
String skeleton = toSkeleton(startCalendar, endCalendar, flags);
synchronized (CACHED_FORMATTERS) {
- com.ibm.icu.text.DateIntervalFormat formatter = getFormatter(skeleton, locale, tz);
- com.ibm.icu.util.Calendar scal = icuCalendar(startCalendar);
- com.ibm.icu.util.Calendar ecal = icuCalendar(endCalendar);
- return formatter.format(scal, ecal, new StringBuffer(), new FieldPosition(0)).toString();
+ com.ibm.icu.text.DateIntervalFormat formatter =
+ getFormatter(skeleton, icuLocale, icuTimeZone);
+ return formatter.format(startCalendar, endCalendar, new StringBuffer(),
+ new FieldPosition(0)).toString();
}
}
- private static com.ibm.icu.text.DateIntervalFormat getFormatter(String skeleton, Locale locale,
- TimeZone tz) {
- String key = skeleton + "\t" + locale + "\t" + tz;
+ private static com.ibm.icu.text.DateIntervalFormat getFormatter(String skeleton, ULocale locale,
+ com.ibm.icu.util.TimeZone icuTimeZone) {
+ String key = skeleton + "\t" + locale + "\t" + icuTimeZone;
com.ibm.icu.text.DateIntervalFormat formatter = CACHED_FORMATTERS.get(key);
if (formatter != null) {
return formatter;
}
formatter = com.ibm.icu.text.DateIntervalFormat.getInstance(skeleton, locale);
- formatter.setTimeZone(icuTimeZone(tz));
+ formatter.setTimeZone(icuTimeZone);
CACHED_FORMATTERS.put(key, formatter);
return formatter;
}
@@ -223,39 +223,30 @@
}
private static boolean isThisYear(Calendar c) {
- Calendar now = Calendar.getInstance(c.getTimeZone());
+ Calendar now = (Calendar) c.clone();
+ now.setTimeInMillis(System.currentTimeMillis());
return c.get(Calendar.YEAR) == now.get(Calendar.YEAR);
}
- // Return the date difference for the two times in a given timezone.
- public static int dayDistance(TimeZone tz, long startTime, long endTime) {
- return julianDay(tz, endTime) - julianDay(tz, startTime);
- }
-
public static int dayDistance(Calendar c1, Calendar c2) {
- return julianDay(c2) - julianDay(c1);
+ return c2.get(Calendar.JULIAN_DAY) - c1.get(Calendar.JULIAN_DAY);
}
- private static int julianDay(TimeZone tz, long time) {
- long utcMs = time + tz.getOffset(time);
- return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
+ /**
+ * Creates an immutable ICU timezone backed by the specified libcore timezone data. At the time of
+ * writing the libcore implementation is faster but restricted to 1902 - 2038.
+ * Callers must not modify the {@code tz} after calling this method.
+ */
+ static com.ibm.icu.util.TimeZone icuTimeZone(TimeZone tz) {
+ JavaTimeZone javaTimeZone = new JavaTimeZone(tz, null);
+ javaTimeZone.freeze(); // Optimization - allows the timezone to be copied cheaply.
+ return javaTimeZone;
}
- private static int julianDay(Calendar c) {
- long utcMs = c.getTimeInMillis() + c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
- return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
+ static Calendar createIcuCalendar(com.ibm.icu.util.TimeZone icuTimeZone, ULocale icuLocale,
+ long timeInMillis) {
+ Calendar calendar = new GregorianCalendar(icuTimeZone, icuLocale);
+ calendar.setTimeInMillis(timeInMillis);
+ return calendar;
}
-
- private static com.ibm.icu.util.TimeZone icuTimeZone(TimeZone tz) {
- final int timezoneType = com.ibm.icu.util.TimeZone.TIMEZONE_JDK;
- return com.ibm.icu.util.TimeZone.getTimeZone(tz.getID(), timezoneType);
- }
-
- private static com.ibm.icu.util.Calendar icuCalendar(Calendar cal) {
- com.ibm.icu.util.TimeZone timeZone = icuTimeZone(cal.getTimeZone());
- com.ibm.icu.util.Calendar result = com.ibm.icu.util.Calendar.getInstance(timeZone);
- result.setTime(cal.getTime());
- return result;
- }
-
}
diff --git a/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java b/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
index 750df00..8d62c78 100644
--- a/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
+++ b/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
@@ -16,13 +16,11 @@
package libcore.icu;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
import java.util.Locale;
-import java.util.TimeZone;
import libcore.util.BasicLruCache;
-import libcore.icu.DateIntervalFormat;
+
import com.ibm.icu.text.DisplayContext;
+import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
/**
@@ -50,6 +48,9 @@
// constant comes from public API in DateUtils, it cannot be fixed here.
public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;
+ private static final int DAY_IN_MS = 24 * 60 * 60 * 1000;
+ private static final int EPOCH_JULIAN_DAY = 2440588;
+
private static final FormatterCache CACHED_FORMATTERS = new FormatterCache();
static class FormatterCache
@@ -89,7 +90,7 @@
* always // returns a string like '0 seconds/minutes/... ago' according to
* minResolution.
*/
- public static String getRelativeTimeSpanString(Locale locale, TimeZone tz, long time,
+ public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time,
long now, long minResolution, int flags) {
if (locale == null) {
throw new NullPointerException("locale == null");
@@ -97,6 +98,9 @@
if (tz == null) {
throw new NullPointerException("tz == null");
}
+ ULocale icuLocale = ULocale.forLocale(locale);
+ com.ibm.icu.util.TimeZone icuTimeZone = DateIntervalFormat.icuTimeZone(tz);
+
long duration = Math.abs(now - time);
boolean past = (now >= time);
@@ -142,7 +146,7 @@
count = (int)(duration / HOUR_IN_MILLIS);
unit = com.ibm.icu.text.RelativeDateTimeFormatter.RelativeUnit.HOURS;
} else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {
- count = Math.abs(DateIntervalFormat.dayDistance(tz, time, now));
+ count = Math.abs(dayDistance(icuTimeZone, time, now));
unit = com.ibm.icu.text.RelativeDateTimeFormatter.RelativeUnit.DAYS;
if (count == 2) {
@@ -156,14 +160,14 @@
String str;
if (past) {
synchronized (CACHED_FORMATTERS) {
- str = getFormatter(locale.toString(), style, capitalizationContext)
+ str = getFormatter(icuLocale, style, capitalizationContext)
.format(
com.ibm.icu.text.RelativeDateTimeFormatter.Direction.LAST_2,
com.ibm.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY);
}
} else {
synchronized (CACHED_FORMATTERS) {
- str = getFormatter(locale.toString(), style, capitalizationContext)
+ str = getFormatter(icuLocale, style, capitalizationContext)
.format(
com.ibm.icu.text.RelativeDateTimeFormatter.Direction.NEXT_2,
com.ibm.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY);
@@ -198,32 +202,28 @@
// formatDateRange() would determine that based on the current system
// time and may give wrong results.
if ((flags & (FORMAT_NO_YEAR | FORMAT_SHOW_YEAR)) == 0) {
- Calendar timeCalendar = new GregorianCalendar(false);
- timeCalendar.setTimeZone(tz);
- timeCalendar.setTimeInMillis(time);
- Calendar nowCalendar = new GregorianCalendar(false);
- nowCalendar.setTimeZone(tz);
- nowCalendar.setTimeInMillis(now);
+ Calendar timeCalendar = DateIntervalFormat.createIcuCalendar(icuTimeZone, icuLocale, time);
+ Calendar nowCalendar = DateIntervalFormat.createIcuCalendar(icuTimeZone, icuLocale, now);
- if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) {
- flags |= FORMAT_SHOW_YEAR;
- } else {
- flags |= FORMAT_NO_YEAR;
- }
+ if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) {
+ flags |= FORMAT_SHOW_YEAR;
+ } else {
+ flags |= FORMAT_NO_YEAR;
+ }
}
- return DateIntervalFormat.formatDateRange(locale, tz, time, time, flags);
+ return DateIntervalFormat.formatDateRange(icuLocale, icuTimeZone, time, time, flags);
}
if (relative) {
synchronized (CACHED_FORMATTERS) {
- return getFormatter(locale.toString(), style, capitalizationContext)
+ return getFormatter(icuLocale, style, capitalizationContext)
.format(count, direction, unit);
}
} else {
capitalizationContext = DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE;
synchronized (CACHED_FORMATTERS) {
- return getFormatter(locale.toString(), style, capitalizationContext)
+ return getFormatter(icuLocale, style, capitalizationContext)
.format(direction, aunit);
}
}
@@ -258,7 +258,7 @@
* now - 2 hours, now, HOUR_IN_MILLIS, DAY_IN_MILLIS, 0), instead of '2
* hours ago, 11:30 PM' even with minResolution being HOUR_IN_MILLIS.
*/
- public static String getRelativeDateTimeString(Locale locale, TimeZone tz, long time,
+ public static String getRelativeDateTimeString(Locale locale, java.util.TimeZone tz, long time,
long now, long minResolution, long transitionResolution, int flags) {
if (locale == null) {
@@ -267,10 +267,12 @@
if (tz == null) {
throw new NullPointerException("tz == null");
}
+ ULocale icuLocale = ULocale.forLocale(locale);
+ com.ibm.icu.util.TimeZone icuTimeZone = DateIntervalFormat.icuTimeZone(tz);
// Get the time clause first.
- String timeClause = DateIntervalFormat.formatDateRange(locale, tz, time, time,
- FORMAT_SHOW_TIME);
+ String timeClause = DateIntervalFormat.formatDateRange(icuLocale, icuTimeZone, time, time,
+ FORMAT_SHOW_TIME);
long duration = Math.abs(now - time);
// It doesn't make much sense to have results like: "1 week ago, 10:50 AM".
@@ -288,12 +290,8 @@
// are currently using the _NONE option only.
DisplayContext capitalizationContext = DisplayContext.CAPITALIZATION_NONE;
- Calendar timeCalendar = new GregorianCalendar(false);
- timeCalendar.setTimeZone(tz);
- timeCalendar.setTimeInMillis(time);
- Calendar nowCalendar = new GregorianCalendar(false);
- nowCalendar.setTimeZone(tz);
- nowCalendar.setTimeInMillis(now);
+ Calendar timeCalendar = DateIntervalFormat.createIcuCalendar(icuTimeZone, icuLocale, time);
+ Calendar nowCalendar = DateIntervalFormat.createIcuCalendar(icuTimeZone, icuLocale, now);
int days = Math.abs(DateIntervalFormat.dayDistance(timeCalendar, nowCalendar));
@@ -318,12 +316,12 @@
flags = FORMAT_SHOW_DATE | FORMAT_NO_YEAR | FORMAT_ABBREV_MONTH;
}
- dateClause = DateIntervalFormat.formatDateRange(locale, tz, time, time, flags);
+ dateClause = DateIntervalFormat.formatDateRange(icuLocale, icuTimeZone, time, time, flags);
}
// Combine the two clauses, such as '5 days ago, 10:50 AM'.
synchronized (CACHED_FORMATTERS) {
- return getFormatter(locale.toString(), style, capitalizationContext)
+ return getFormatter(icuLocale, style, capitalizationContext)
.combineDateAndTime(dateClause, timeClause);
}
}
@@ -337,15 +335,26 @@
* formatter->action().
*/
private static com.ibm.icu.text.RelativeDateTimeFormatter getFormatter(
- String localeName, com.ibm.icu.text.RelativeDateTimeFormatter.Style style,
+ ULocale locale, com.ibm.icu.text.RelativeDateTimeFormatter.Style style,
DisplayContext capitalizationContext) {
- String key = localeName + "\t" + style + "\t" + capitalizationContext;
+ String key = locale + "\t" + style + "\t" + capitalizationContext;
com.ibm.icu.text.RelativeDateTimeFormatter formatter = CACHED_FORMATTERS.get(key);
if (formatter == null) {
formatter = com.ibm.icu.text.RelativeDateTimeFormatter.getInstance(
- new ULocale(localeName), null, style, capitalizationContext);
+ locale, null, style, capitalizationContext);
CACHED_FORMATTERS.put(key, formatter);
}
return formatter;
}
+
+ // Return the date difference for the two times in a given timezone.
+ private static int dayDistance(com.ibm.icu.util.TimeZone icuTimeZone, long startTime,
+ long endTime) {
+ return julianDay(icuTimeZone, endTime) - julianDay(icuTimeZone, startTime);
+ }
+
+ private static int julianDay(com.ibm.icu.util.TimeZone icuTimeZone, long time) {
+ long utcMs = time + icuTimeZone.getOffset(time);
+ return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
+ }
}
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index 2e72078..e36b3d1 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -16,13 +16,8 @@
package libcore.net;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
-import java.util.Properties;
/**
* Utilities for dealing with MIME types.
@@ -382,7 +377,6 @@
add("video/x-webex", "wrf");
add("x-conference/x-cooltalk", "ice");
add("x-epoc/x-sisx-app", "sisx");
- applyOverrides();
}
private static void add(String mimeType, String extension) {
@@ -399,61 +393,6 @@
}
}
- private static InputStream getContentTypesPropertiesStream() {
- // User override?
- String userTable = System.getProperty("content.types.user.table");
- if (userTable != null) {
- File f = new File(userTable);
- if (f.exists()) {
- try {
- return new FileInputStream(f);
- } catch (IOException ignored) {
- }
- }
- }
-
- // Standard location?
- File f = new File(System.getProperty("java.home"), "lib" + File.separator + "content-types.properties");
- if (f.exists()) {
- try {
- return new FileInputStream(f);
- } catch (IOException ignored) {
- }
- }
-
- return null;
- }
-
- /**
- * This isn't what the RI does. The RI doesn't have hard-coded defaults, so supplying your
- * own "content.types.user.table" means you don't get any of the built-ins, and the built-ins
- * come from "$JAVA_HOME/lib/content-types.properties".
- */
- private static void applyOverrides() {
- // Get the appropriate InputStream to read overrides from, if any.
- InputStream stream = getContentTypesPropertiesStream();
- if (stream == null) {
- return;
- }
-
- try {
- try {
- // Read the properties file...
- Properties overrides = new Properties();
- overrides.load(stream);
- // And translate its mapping to ours...
- for (Map.Entry<Object, Object> entry : overrides.entrySet()) {
- String extension = (String) entry.getKey();
- String mimeType = (String) entry.getValue();
- add(mimeType, extension);
- }
- } finally {
- stream.close();
- }
- } catch (IOException ignored) {
- }
- }
-
private MimeUtils() {
}
diff --git a/luni/src/main/java/java/nio/charset/Charsets.java b/luni/src/main/java/libcore/util/CharsetUtils.java
similarity index 96%
rename from luni/src/main/java/java/nio/charset/Charsets.java
rename to luni/src/main/java/libcore/util/CharsetUtils.java
index 3dede7a..2e426c4 100644
--- a/luni/src/main/java/java/nio/charset/Charsets.java
+++ b/luni/src/main/java/libcore/util/CharsetUtils.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package java.nio.charset;
+package libcore.util;
/**
* Various special-case charset conversions (for performance).
*
* @hide internal use only
*/
-public final class Charsets {
+public final class CharsetUtils {
/**
* Returns a new byte array containing the bytes corresponding to the given characters,
* encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'.
@@ -75,6 +75,6 @@
*/
public static native void isoLatin1BytesToChars(byte[] bytes, int offset, int length, char[] chars);
- private Charsets() {
+ private CharsetUtils() {
}
}
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 035b1d9..0f2d0ad 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -48,7 +48,6 @@
REGISTER(register_java_lang_System);
REGISTER(register_java_math_NativeBN);
REGISTER(register_java_nio_ByteOrder);
- REGISTER(register_java_nio_charset_Charsets);
REGISTER(register_java_text_Bidi);
REGISTER(register_java_util_jar_StrictJarFile);
REGISTER(register_java_util_regex_Matcher);
@@ -70,6 +69,7 @@
REGISTER(register_libcore_io_AsynchronousCloseMonitor);
REGISTER(register_libcore_io_Memory);
REGISTER(register_libcore_io_Posix);
+ REGISTER(register_libcore_util_CharsetUtils);
REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
REGISTER(register_org_apache_harmony_xml_ExpatParser);
REGISTER(register_sun_misc_Unsafe);
diff --git a/luni/src/main/native/java_lang_System.cpp b/luni/src/main/native/java_lang_System.cpp
index 3b995e7..306adab 100644
--- a/luni/src/main/native/java_lang_System.cpp
+++ b/luni/src/main/native/java_lang_System.cpp
@@ -124,22 +124,9 @@
#endif
}
-static jstring System_mapLibraryName(JNIEnv* env, jclass, jstring javaName) {
- ScopedUtfChars name(env, javaName);
- if (name.c_str() == NULL) {
- return NULL;
- }
- char* mappedName = NULL;
- asprintf(&mappedName, "lib%s.so", name.c_str());
- jstring result = env->NewStringUTF(mappedName);
- free(mappedName);
- return result;
-}
-
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(System, currentTimeMillis, "!()J"),
NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"),
- NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(System, nanoTime, "!()J"),
NATIVE_METHOD(System, setFieldImpl, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"),
NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"),
diff --git a/luni/src/main/native/java_nio_charset_Charsets.cpp b/luni/src/main/native/libcore_util_CharsetUtils.cpp
similarity index 98%
rename from luni/src/main/native/java_nio_charset_Charsets.cpp
rename to luni/src/main/native/libcore_util_CharsetUtils.cpp
index a49ba22..57c8172 100644
--- a/luni/src/main/native/java_nio_charset_Charsets.cpp
+++ b/luni/src/main/native/libcore_util_CharsetUtils.cpp
@@ -245,6 +245,6 @@
NATIVE_METHOD(Charsets, toIsoLatin1Bytes, "([CII)[B"),
NATIVE_METHOD(Charsets, toUtf8Bytes, "([CII)[B"),
};
-void register_java_nio_charset_Charsets(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/nio/charset/Charsets", gMethods, NELEM(gMethods));
+void register_libcore_util_CharsetUtils(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "libcore/util/CharsetUtils", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 2bc44ed..a90c683 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -28,7 +28,6 @@
java_lang_System.cpp \
java_math_NativeBN.cpp \
java_nio_ByteOrder.cpp \
- java_nio_charset_Charsets.cpp \
java_text_Bidi.cpp \
java_util_jar_StrictJarFile.cpp \
java_util_regex_Matcher.cpp \
@@ -50,6 +49,7 @@
libcore_io_AsynchronousCloseMonitor.cpp \
libcore_io_Memory.cpp \
libcore_io_Posix.cpp \
+ libcore_util_CharsetUtils.cpp \
org_apache_harmony_xml_ExpatParser.cpp \
readlink.cpp \
sun_misc_Unsafe.cpp \
diff --git a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
index d49579c..d14710c 100644
--- a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
+++ b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
@@ -16,9 +16,10 @@
package libcore.icu;
-import java.util.Calendar;
-import java.util.Locale;
-import java.util.TimeZone;
+import android.icu.util.Calendar;
+import android.icu.util.TimeZone;
+import android.icu.util.ULocale;
+
import static libcore.icu.DateIntervalFormat.*;
public class DateIntervalFormatTest extends junit.framework.TestCase {
@@ -32,7 +33,7 @@
public void test_formatDateInterval() throws Exception {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
- Calendar c = Calendar.getInstance(tz, Locale.US);
+ Calendar c = Calendar.getInstance(tz, ULocale.US);
c.set(Calendar.MONTH, Calendar.JANUARY);
c.set(Calendar.DAY_OF_MONTH, 19);
c.set(Calendar.HOUR_OF_DAY, 3);
@@ -51,10 +52,10 @@
long noonDuration = (8 * 60 + 30) * 60 * 1000 - 15 * 1000;
long midnightDuration = (3 * 60 + 30) * 60 * 1000 + 15 * 1000;
- Locale de_DE = new Locale("de", "DE");
- Locale en_US = new Locale("en", "US");
- Locale es_ES = new Locale("es", "ES");
- Locale es_US = new Locale("es", "US");
+ ULocale de_DE = new ULocale("de", "DE");
+ ULocale en_US = new ULocale("en", "US");
+ ULocale es_ES = new ULocale("es", "ES");
+ ULocale es_US = new ULocale("es", "US");
assertEquals("Monday", formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_WEEKDAY));
assertEquals("January 19", formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, FORMAT_SHOW_DATE));
@@ -168,7 +169,7 @@
// http://b/8862241 - we should be able to format dates past 2038.
// See also http://code.google.com/p/android/issues/detail?id=13050.
public void test8862241() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
Calendar c = Calendar.getInstance(tz, l);
c.clear();
@@ -182,7 +183,7 @@
// http://b/10089890 - we should take the given time zone into account.
public void test10089890() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles");
int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL | FORMAT_SHOW_TIME | FORMAT_24HOUR;
@@ -204,7 +205,7 @@
int abbr12 = time12 | FORMAT_ABBREV_ALL;
int abbr24 = time24 | FORMAT_ABBREV_ALL;
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
// Full length on-the-hour times.
@@ -231,7 +232,7 @@
// http://b/10560853 - when the time is not displayed, an end time 0 ms into the next day is
// considered to belong to the previous day.
public void test10560853_when_time_not_displayed() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
long midnight = 0;
@@ -255,7 +256,7 @@
// http://b/10560853 - when the start and end times are otherwise on the same day,
// an end time 0 ms into the next day is considered to belong to the previous day.
public void test10560853_for_single_day_events() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
@@ -267,7 +268,7 @@
// The fix for http://b/10560853 didn't work except for the day around the epoch, which was
// all the unit test checked!
public void test_single_day_events_later_than_epoch() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
@@ -285,7 +286,7 @@
// The fix for http://b/10560853 didn't work except for UTC, which was
// all the unit test checked!
public void test_single_day_events_not_in_UTC() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles");
int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
@@ -306,7 +307,7 @@
// http://b/10209343 - even if the caller didn't explicitly ask us to include the year,
// we should do so for years other than the current year.
public void test10209343_when_not_this_year() {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_TIME | FORMAT_24HOUR;
@@ -329,7 +330,7 @@
// http://b/10209343 - for the current year, we should honor the FORMAT_SHOW_YEAR flags.
public void test10209343_when_this_year() {
// Construct a date in the current year (whenever the test happens to be run).
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar c = Calendar.getInstance(utc, l);
c.set(Calendar.MONTH, Calendar.FEBRUARY);
@@ -364,7 +365,7 @@
// http://b/8467515 - yet another y2k38 bug report.
public void test8467515() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_YEAR | FORMAT_ABBREV_MONTH | FORMAT_ABBREV_WEEKDAY;
long t;
@@ -384,7 +385,7 @@
// http://b/12004664
public void test12004664() throws Exception {
TimeZone utc = TimeZone.getTimeZone("UTC");
- Calendar c = Calendar.getInstance(utc, Locale.US);
+ Calendar c = Calendar.getInstance(utc, ULocale.US);
c.clear();
c.set(Calendar.YEAR, 1980);
c.set(Calendar.MONTH, Calendar.FEBRUARY);
@@ -393,26 +394,26 @@
long thisYear = c.getTimeInMillis();
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_YEAR;
- assertEquals("Sunday, February 10, 1980", formatDateRange(new Locale("en", "US"), utc, thisYear, thisYear, flags));
+ assertEquals("Sunday, February 10, 1980", formatDateRange(new ULocale("en", "US"), utc, thisYear, thisYear, flags));
- // If we supported non-Gregorian calendars, this is what that we'd expect for these locales.
+ // If we supported non-Gregorian calendars, this is what that we'd expect for these ULocales.
// This is really the correct behavior, but since java.util.Calendar currently only supports
// the Gregorian calendar, we want to deliberately force icu4c to agree, otherwise we'd have
// a mix of calendars throughout an app's UI depending on whether Java or native code formatted
// the date.
- // assertEquals("یکشنبه ۲۱ بهمن ۱۳۵۸ ه.ش.", formatDateRange(new Locale("fa"), utc, thisYear, thisYear, flags));
- // assertEquals("AP ۱۳۵۸ سلواغه ۲۱, یکشنبه", formatDateRange(new Locale("ps"), utc, thisYear, thisYear, flags));
- // assertEquals("วันอาทิตย์ 10 กุมภาพันธ์ 2523", formatDateRange(new Locale("th"), utc, thisYear, thisYear, flags));
+ // assertEquals("یکشنبه ۲۱ بهمن ۱۳۵۸ ه.ش.", formatDateRange(new ULocale("fa"), utc, thisYear, thisYear, flags));
+ // assertEquals("AP ۱۳۵۸ سلواغه ۲۱, یکشنبه", formatDateRange(new ULocale("ps"), utc, thisYear, thisYear, flags));
+ // assertEquals("วันอาทิตย์ 10 กุมภาพันธ์ 2523", formatDateRange(new ULocale("th"), utc, thisYear, thisYear, flags));
// For now, here are the localized Gregorian strings instead...
- assertEquals("یکشنبه ۱۰ فوریهٔ ۱۹۸۰", formatDateRange(new Locale("fa"), utc, thisYear, thisYear, flags));
- assertEquals("یکشنبه د ۱۹۸۰ د فبروري ۱۰", formatDateRange(new Locale("ps"), utc, thisYear, thisYear, flags));
- assertEquals("วันอาทิตย์ที่ 10 กุมภาพันธ์ ค.ศ. 1980", formatDateRange(new Locale("th"), utc, thisYear, thisYear, flags));
+ assertEquals("یکشنبه ۱۰ فوریهٔ ۱۹۸۰", formatDateRange(new ULocale("fa"), utc, thisYear, thisYear, flags));
+ assertEquals("یکشنبه د ۱۹۸۰ د فبروري ۱۰", formatDateRange(new ULocale("ps"), utc, thisYear, thisYear, flags));
+ assertEquals("วันอาทิตย์ที่ 10 กุมภาพันธ์ ค.ศ. 1980", formatDateRange(new ULocale("th"), utc, thisYear, thisYear, flags));
}
// http://b/13234532
public void test13234532() throws Exception {
- Locale l = Locale.US;
+ ULocale l = ULocale.US;
TimeZone utc = TimeZone.getTimeZone("UTC");
int flags = FORMAT_SHOW_TIME | FORMAT_ABBREV_ALL | FORMAT_12HOUR;
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
index 42de50a..1611120 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
@@ -256,15 +256,7 @@
private void getSigAlgName(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
-
- String actual = crlRsa.getSigAlgName().toUpperCase(Locale.US);
-
- // Bouncycastle is broken
- if ("BC".equals(f.getProvider().getName())) {
- assertEquals("1.2.840.113549.1.1.5", actual);
- } else {
- assertEquals("SHA1WITHRSA", actual);
- }
+ assertEquals("SHA1WITHRSA", getCRL(f, CRL_RSA).getSigAlgName().toUpperCase(Locale.ROOT));
}
private void getSigAlgOID(CertificateFactory f) throws Exception {
diff --git a/luni/src/test/java/libcore/java/util/CollectionsTest.java b/luni/src/test/java/libcore/java/util/CollectionsTest.java
index cd89397..bc73817 100644
--- a/luni/src/test/java/libcore/java/util/CollectionsTest.java
+++ b/luni/src/test/java/libcore/java/util/CollectionsTest.java
@@ -19,6 +19,7 @@
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Enumeration;
import java.util.Iterator;
@@ -113,4 +114,75 @@
} catch (ConcurrentModificationException expected) {
}
}
+
+ /**
+ * A value type whose {@code compareTo} method returns one of {@code 0},
+ * {@code Integer.MIN_VALUE} and {@code Integer.MAX_VALUE}.
+ */
+ static final class IntegerWithExtremeComparator
+ implements Comparable<IntegerWithExtremeComparator> {
+ private final int value;
+
+ public IntegerWithExtremeComparator(int value) {
+ this.value = value;
+ }
+
+ @Override
+ public int compareTo(IntegerWithExtremeComparator another) {
+ if (another.value == this.value) {
+ return 0;
+ } else if (another.value > this.value) {
+ return Integer.MIN_VALUE;
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+ }
+
+ // http://b/19749094
+ public void testBinarySearch_comparatorThatReturnsMinAndMaxValue() {
+ ArrayList<Integer> list = new ArrayList<Integer>(16);
+ list.add(4);
+ list.add(9);
+ list.add(11);
+ list.add(14);
+ list.add(16);
+
+ int index = Collections.binarySearch(list, 9, new Comparator<Integer>() {
+ @Override
+ public int compare(Integer lhs, Integer rhs) {
+ final int compare = lhs.compareTo(rhs);
+ if (compare == 0) {
+ return 0;
+ } else if (compare < 0) {
+ return Integer.MIN_VALUE;
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+ });
+ assertEquals(1, index);
+
+ ArrayList<IntegerWithExtremeComparator> list2 =
+ new ArrayList<IntegerWithExtremeComparator>();
+ list2.add(new IntegerWithExtremeComparator(4));
+ list2.add(new IntegerWithExtremeComparator(9));
+ list2.add(new IntegerWithExtremeComparator(11));
+ list2.add(new IntegerWithExtremeComparator(14));
+ list2.add(new IntegerWithExtremeComparator(16));
+
+ assertEquals(1, Collections.binarySearch(list2, new IntegerWithExtremeComparator(9)));
+ }
+
+ public void testBinarySearch_emptyCollection() {
+ assertEquals(-1, Collections.binarySearch(new ArrayList<Integer>(), 9));
+
+ assertEquals(-1, Collections.binarySearch(new ArrayList<Integer>(), 9,
+ new Comparator<Integer>() {
+ @Override
+ public int compare(Integer lhs, Integer rhs) {
+ return lhs.compareTo(rhs);
+ }
+ }));
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 4f2e38c..68e9109 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -310,4 +310,18 @@
assertFalse(tz.inDaylightTime(new Date(2206292400000L)));
assertEquals(-18000000, tz.getOffset(2206292400000L));
}
+
+ public void testTimeZoneIDLocalization() {
+ Locale defaultLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(new Locale("en"));
+ TimeZone en_timezone = TimeZone.getTimeZone("GMT+09:00");
+ Locale.setDefault(new Locale("ar"));
+ TimeZone ar_timezone = TimeZone.getTimeZone("GMT+09:00");
+
+ assertEquals(en_timezone.getID(), ar_timezone.getID());
+ } finally {
+ Locale.setDefault(defaultLocale);
+ }
+ }
}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
index 9b7dc18..e90452d 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
@@ -100,6 +100,12 @@
macList.add(Mac.getInstance(defaultAlgorithm, defaultProvider));
macList.add(Mac.getInstance(defaultAlgorithm, defaultProviderName));
for (Provider p : Security.getProviders("Mac." + defaultAlgorithm)) {
+ // Do not test AndroidKeyStore's Mac. It cannot be initialized without providing an
+ // AndroidKeyStore-backed SecretKey instance. It's OKish not to test here because it's
+ // tested by cts/tests/test/keystore.
+ if ("AndroidKeyStore".equals(p.getName())) {
+ continue;
+ }
macList.add(Mac.getInstance(defaultAlgorithm, p));
}
return macList.toArray(new Mac[macList.size()]);
@@ -845,6 +851,13 @@
byte[] output = null;
byte[] output2 = null;
for (int i = 0; i < providers.length; i++) {
+ // Do not test AndroidKeyStore's Mac. It cannot be initialized without providing an
+ // AndroidKeyStore-backed SecretKey instance. It's OKish not to test here because it's
+ // tested by cts/tests/test/keystore.
+ if ("AndroidKeyStore".equals(providers[i].getName())) {
+ continue;
+ }
+
System.out.println("provider = " + providers[i].getName());
Mac mac = Mac.getInstance("HmacMD5", providers[i]);
mac.init(key);
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index a55b47a..9aab942 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -394,6 +394,12 @@
provide("Signature", "NONEwithRSA");
provide("Cipher", "RSA/ECB/NOPADDING");
provide("Cipher", "RSA/ECB/PKCS1PADDING");
+ provide("SecretKeyFactory", "AES");
+ provide("SecretKeyFactory", "HmacSHA1");
+ provide("SecretKeyFactory", "HmacSHA224");
+ provide("SecretKeyFactory", "HmacSHA256");
+ provide("SecretKeyFactory", "HmacSHA384");
+ provide("SecretKeyFactory", "HmacSHA512");
// different names: ARCFOUR vs ARC4
unprovide("Cipher", "ARCFOUR");