Merge "Remove hidden System.arraycopy(byte[]...."
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index 2a81be1..486ee90 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -110,8 +110,9 @@
//System.out.println("DEX FILE cookie is " + mCookie + " fileName=" + fileName);
}
- DexFile(ByteBuffer[] bufs) throws IOException {
- mCookie = openInMemoryDexFiles(bufs);
+ DexFile(ByteBuffer[] bufs, ClassLoader loader, DexPathList.Element[] elements)
+ throws IOException {
+ mCookie = openInMemoryDexFiles(bufs, loader, elements);
mInternalCookie = mCookie;
mFileName = null;
}
@@ -370,7 +371,8 @@
elements);
}
- private static Object openInMemoryDexFiles(ByteBuffer[] bufs) throws IOException {
+ private static Object openInMemoryDexFiles(ByteBuffer[] bufs, ClassLoader loader,
+ DexPathList.Element[] elements) throws IOException {
// Preprocess the ByteBuffers for openInMemoryDexFilesNative. We extract
// the backing array (non-direct buffers only) and start/end positions
// so that the native method does not have to call Java methods anymore.
@@ -382,11 +384,11 @@
starts[i] = bufs[i].position();
ends[i] = bufs[i].limit();
}
- return openInMemoryDexFilesNative(bufs, arrays, starts, ends);
+ return openInMemoryDexFilesNative(bufs, arrays, starts, ends, loader, elements);
}
private static native Object openInMemoryDexFilesNative(ByteBuffer[] bufs, byte[][] arrays,
- int[] starts, int[] ends);
+ int[] starts, int[] ends, ClassLoader loader, DexPathList.Element[] elements);
/*
* Initiates background verification of this DexFile. This is a sepearate down-call
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index 227231a..c63bb13 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -266,10 +266,10 @@
try {
Element[] null_elements = null;
- DexFile dex = new DexFile(dexFiles);
+ DexFile dex = new DexFile(dexFiles, definingContext, null_elements);
// Capture class loader context from *before* `dexElements` is set (see comment below).
- String classLoaderContext = DexFile.getClassLoaderContext(definingContext,
- null_elements);
+ String classLoaderContext = dex.isBackedByOatFile()
+ ? null : DexFile.getClassLoaderContext(definingContext, null_elements);
dexElements = new Element[] { new Element(dex) };
// Spawn background thread to verify all classes and cache verification results.
// Must be called *after* `dexElements` has been initialized for ART to find
@@ -277,7 +277,13 @@
// the order of the array), but with class loader context from *before*
// `dexElements` was set because that is what it will be compared against next
// time the same bytecode is loaded.
- dex.verifyInBackground(definingContext, classLoaderContext);
+ // We only spawn the background thread if the bytecode is not backed by an oat
+ // file, i.e. this is the first time this bytecode is being loaded and/or
+ // verification results have not been cached yet. Skip spawning the thread on
+ // all subsequent loads of the same bytecode in the same class loader context.
+ if (classLoaderContext != null) {
+ dex.verifyInBackground(definingContext, classLoaderContext);
+ }
} catch (IOException suppressed) {
System.logE("Unable to load dex files", suppressed);
suppressedExceptions.add(suppressed);
@@ -340,7 +346,8 @@
int elementPos = 0;
for (ByteBuffer buf : dexFiles) {
try {
- DexFile dex = new DexFile(new ByteBuffer[] { buf });
+ DexFile dex = new DexFile(new ByteBuffer[] { buf }, /* classLoader */ null,
+ /* dexElements */ null);
elements[elementPos++] = new Element(dex);
} catch (IOException suppressed) {
System.logE("Unable to load dex file: " + buf, suppressed);
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 0260e68..7d70680 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -696,4 +696,10 @@
*/
@libcore.api.CorePlatformApi
public static native void setProcessPackageName(String packageName);
+
+ /**
+ * Sets the full path to data directory of the app running in this process.
+ */
+ @libcore.api.CorePlatformApi
+ public static native void setProcessDataDirectory(String dataDir);
}
diff --git a/luni/src/main/java/libcore/net/android.mime.types b/luni/src/main/java/libcore/net/android.mime.types
index 8a090fc..dd3b21a 100644
--- a/luni/src/main/java/libcore/net/android.mime.types
+++ b/luni/src/main/java/libcore/net/android.mime.types
@@ -90,4 +90,5 @@
video/3gpp 3gpp!
video/mpeg mpeg!
video/quicktime mov!
+video/vnd.youtube.yt yt
video/x-matroska mkv!
diff --git a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
index cf1e233..26be32b 100644
--- a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
+++ b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
@@ -90,8 +90,13 @@
assertEquals("video/ogg", MimeUtils.guessMimeTypeFromExtension("ogv"));
}
- public void test_70851634() {
- assertEquals("application/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
+ public void test_70851634_mimeTypeFromExtension() {
+ assertEquals("video/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
+ }
+
+ public void test_70851634_extensionFromMimeType() {
+ assertEquals("yt", MimeUtils.guessExtensionFromMimeType("video/vnd.youtube.yt"));
+ assertEquals("yt", MimeUtils.guessExtensionFromMimeType("application/vnd.youtube.yt"));
}
public void test_112162449_audio() {
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
index 9e3515a..a304cf8 100644
--- a/mmodules/core_platform_api/api/platform/current-api.txt
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -748,6 +748,7 @@
method public void setHiddenApiExemptions(String[]);
method public static void setHiddenApiUsageLogger(dalvik.system.VMRuntime.HiddenApiUsageLogger);
method public static void setNonSdkApiUsageConsumer(java.util.function.Consumer<java.lang.String>);
+ method public static void setProcessDataDirectory(String);
method public static void setProcessPackageName(String);
method @dalvik.annotation.compat.UnsupportedAppUsage public float setTargetHeapUtilization(float);
method public void setTargetSdkVersion(int);
diff --git a/ojluni/src/main/java/java/net/Inet6AddressImpl.java b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
index 6b22f8c..bb722f3 100644
--- a/ojluni/src/main/java/java/net/Inet6AddressImpl.java
+++ b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
@@ -44,6 +44,7 @@
import static android.system.OsConstants.AI_ADDRCONFIG;
import static android.system.OsConstants.EACCES;
import static android.system.OsConstants.ECONNREFUSED;
+import static android.system.OsConstants.EPERM;
import static android.system.OsConstants.NI_NAMEREQD;
import static android.system.OsConstants.ICMP6_ECHO_REPLY;
import static android.system.OsConstants.ICMP_ECHOREPLY;
@@ -144,7 +145,8 @@
// SecurityException to aid in debugging this common mistake.
// http://code.google.com/p/android/issues/detail?id=15722
if (gaiException.getCause() instanceof ErrnoException) {
- if (((ErrnoException) gaiException.getCause()).errno == EACCES) {
+ int errno = ((ErrnoException) gaiException.getCause()).errno;
+ if (errno == EACCES || errno == EPERM) {
throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException);
}
}