Merge "Move targetSDK-specific tests to SELinux CTS."
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 97d5838..407b30f 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -885,6 +885,7 @@
java_system_modules {
name: "art-module-public-api-stubs-system-modules",
visibility: [
+ "//art/build/sdk",
"//external/conscrypt",
"//external/icu/android_icu4j",
"//external/wycheproof",
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index f5136a4..d0a449b 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -159,6 +159,20 @@
}
/**
+ * Computes the classloader contexts for each classpath entry in {@code pathList.getDexPaths()}.
+ *
+ * Note that this method is not thread safe, i.e. it is the responsibility of the caller to
+ * ensure that {@code pathList.getDexPaths()} is not modified concurrently with this method
+ * being called.
+ *
+ * @return A non-null array of non-null strings of length
+ * {@code 2 * pathList.getDexPaths().size()}. Every even index (0 is even here) is a dex file
+ * path and every odd entry is the class loader context used to load the previously listed dex
+ * file. E.g. a result might be {@code { "foo.dex", "PCL[]", "bar.dex", "PCL[foo.dex]" } }.
+ */
+ private native String[] computeClassLoaderContextsNative();
+
+ /**
* Constructs an instance.
*
* dexFile must be an in-memory representation of a full dexFile.
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 6171cb6..863f85d 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -744,4 +744,15 @@
*/
@libcore.api.CorePlatformApi
public static native void setProcessDataDirectory(String dataDir);
+
+ /**
+ * Returns whether {@code encodedClassLoaderContext} is a valid encoded class loader context.
+ * A class loader context is an internal opaque format used by the runtime to encode the
+ * class loader hierarchy (including each ClassLoader's classpath) used to load a dex file.
+ *
+ * @return True if encodedClassLoaderContext is a non-null valid encoded class loader context.
+ * Throws NullPointerException if encodedClassLoaderContext is null.
+ */
+ @libcore.api.CorePlatformApi
+ public static native boolean isValidClassLoaderContext(String encodedClassLoaderContext);
}
diff --git a/luni/src/main/java/android/compat/TEST_MAPPING b/luni/src/main/java/android/compat/TEST_MAPPING
new file mode 100644
index 0000000..c8b07b4
--- /dev/null
+++ b/luni/src/main/java/android/compat/TEST_MAPPING
@@ -0,0 +1,17 @@
+{
+ "presubmit": [
+ // Unit tests for CoreCompatChangeRule
+ {
+ "name": "CtsLibcoreTestCases",
+ "options": [
+ {
+ "include-filter": "libcore.junit.util.compat"
+ }
+ ]
+ },
+ // CTS test for CompatChanges System
+ {
+ "name": "CtsAppCompatHostTestCases"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/javax/crypto/HardwareAesTest.java b/luni/src/test/java/libcore/javax/crypto/HardwareAesTest.java
new file mode 100644
index 0000000..f79bb81
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/HardwareAesTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package libcore.javax.crypto;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import libcore.java.security.CpuFeatures;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class HardwareAesTest {
+
+ @Test
+ public void hardwareAesAvailability() {
+ // Test is only applicable if we know for sure that the device should support
+ // hardware AES. That covers the important cases (non-emulated ARM and x86_64),
+ // For everything else we assume BoringSSL does the right thing.
+ assumeTrue(CpuFeatures.isKnownToSupportHardwareAes());
+ assertTrue(CpuFeatures.isAesHardwareAccelerated());
+ }
+}
diff --git a/mmodules/core_platform_api/Android.bp b/mmodules/core_platform_api/Android.bp
index 0a8c381..f2a042b 100644
--- a/mmodules/core_platform_api/Android.bp
+++ b/mmodules/core_platform_api/Android.bp
@@ -85,6 +85,7 @@
java_system_modules {
name: "art-module-platform-api-stubs-system-modules",
visibility: [
+ "//art/build/sdk",
"//external/conscrypt",
"//external/icu/android_icu4j",
"//external/wycheproof",
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
index c3a603c..707e3a3 100644
--- a/mmodules/core_platform_api/api/platform/current-api.txt
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -698,6 +698,7 @@
method public static boolean isBootClassPathOnDisk(String);
method @dalvik.annotation.optimization.FastNative public boolean isCheckJniEnabled();
method @dalvik.annotation.optimization.FastNative public boolean isNativeDebuggable();
+ method public static boolean isValidClassLoaderContext(String);
method @dalvik.annotation.optimization.FastNative public Object newNonMovableArray(Class<?>, int);
method @dalvik.annotation.optimization.FastNative public Object newUnpaddedArray(Class<?>, int);
method public void notifyStartupCompleted();
diff --git a/mmodules/intracoreapi/Android.bp b/mmodules/intracoreapi/Android.bp
index f8454bb..c2a3de3 100644
--- a/mmodules/intracoreapi/Android.bp
+++ b/mmodules/intracoreapi/Android.bp
@@ -71,6 +71,7 @@
java_system_modules {
name: "art-module-intra-core-api-stubs-system-modules",
visibility: [
+ "//art/build/sdk",
"//external/bouncycastle",
"//external/conscrypt",
"//external/icu/android_icu4j",
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java
index 7e9b0b4..c11a65b 100644
--- a/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java
@@ -165,10 +165,6 @@
public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
- public int getDexFieldIndex() {
- throw new RuntimeException("Stub!");
- }
-
@UnsupportedAppUsage
public int getOffset() {
throw new RuntimeException("Stub!");
@@ -181,7 +177,7 @@
private java.lang.Class<?> declaringClass;
- private int dexFieldIndex;
+ private int artFieldIndex;
private int offset;
diff --git a/ojluni/src/main/java/java/lang/reflect/Field.java b/ojluni/src/main/java/java/lang/reflect/Field.java
index 2bcf9e9..ca5857a 100644
--- a/ojluni/src/main/java/java/lang/reflect/Field.java
+++ b/ojluni/src/main/java/java/lang/reflect/Field.java
@@ -61,7 +61,7 @@
private int accessFlags;
private Class<?> declaringClass;
- private int dexFieldIndex;
+ private int artFieldIndex;
private int offset;
private Class<?> type;
@@ -82,12 +82,17 @@
*/
public String getName() {
// Android-changed: getName() implemented differently.
- if (dexFieldIndex == -1) {
+ if (declaringClass.isProxy()) {
// Proxy classes have 1 synthesized static field with no valid dex index.
- if (!declaringClass.isProxy()) {
- throw new AssertionError();
+ if ((getModifiers() & Modifier.STATIC) == 0) {
+ throw new AssertionError("Invalid modifiers for proxy field: " + getModifiers());
}
- return "throws";
+ // Only 2 fields are present on proxy classes.
+ switch (artFieldIndex) {
+ case 0: return "interfaces";
+ case 1: return "throws";
+ default: throw new AssertionError("Invalid index for proxy: " + artFieldIndex);
+ }
}
return getNameInternal();
@@ -928,15 +933,6 @@
// BEGIN Android-added: Methods for use by Android-specific code.
/**
- * Returns the index of this field's ID in its dex file.
- *
- * @hide
- */
- public int getDexFieldIndex() {
- return dexFieldIndex;
- }
-
- /**
* Returns the offset of the field within an instance, or for static fields, the class.
*
* @hide
diff --git a/ojluni/src/main/java/java/net/NetworkInterface.java b/ojluni/src/main/java/java/net/NetworkInterface.java
index c8044fd..d6cd330 100644
--- a/ojluni/src/main/java/java/net/NetworkInterface.java
+++ b/ojluni/src/main/java/java/net/NetworkInterface.java
@@ -47,7 +47,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 > 29. http://b/141455849
+// Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
/**
* This class represents a Network Interface made up of a name,
* and a list of IP addresses assigned to this interface.
@@ -58,9 +58,9 @@
* <p>
* <a name="access-restrictions"></a>Note that information about
* {@link NetworkInterface}s may be restricted. For example, non-system apps
- * with {@code targetSdkVersion > 29} will only have access to information
- * about {@link NetworkInterface}s that are associated with an
- * {@link InetAddress}.
+ * with {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R} will only
+ * have access to information about {@link NetworkInterface}s that are
+ * associated with an {@link Inet4Address}.
*
* @since 1.4
*/
@@ -272,7 +272,7 @@
return "".equals(displayName) ? null : displayName;
}
- // Android-added: Document restrictions for targetSdkVersion > 29. http://b/141455849
+ // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
/**
* Searches for the network interface with the specified name.
*
@@ -304,7 +304,7 @@
return null;
}
- // Android-added: Document restrictions for targetSdkVersion > 29. http://b/141455849
+ // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
/**
* Get a network interface given its index.
*
@@ -373,7 +373,7 @@
return null;
}
- // Android-added: Document restrictions for targetSdkVersion > 29. http://b/141455849
+ // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
/**
* Returns all the interfaces on this machine. The {@code Enumeration}
* contains at least one element, possibly representing a loopback
@@ -383,9 +383,10 @@
* NOTE: can use getNetworkInterfaces()+getInetAddresses()
* to obtain all IP addresses for this node
* <p>
- * For non-system apps with {@code targetSdkVersion > 29}, this
+ * 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}.
+ * are associated with an {@link Inet4Address}.
*
* @return an Enumeration of NetworkInterfaces found on this machine
* that <a href="#access-restrictions">are accessible</a>.
@@ -558,7 +559,7 @@
return (getFlags() & IFF_MULTICAST) != 0;
}
- // Android-added: Document restrictions for targetSdkVersion > 29. http://b/141455849
+ // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
/**
* Returns the hardware address (usually MAC) of the interface if it
* has one and if it can be accessed given the current privileges.
@@ -570,7 +571,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 targeting API levels > 29.
+ * non-system apps having
+ * {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R}.
*
* @exception SocketException if an I/O error occurs.
* @since 1.6
diff --git a/support/src/test/java/libcore/java/security/CpuFeatures.java b/support/src/test/java/libcore/java/security/CpuFeatures.java
index 8ab610f..df65ed2 100644
--- a/support/src/test/java/libcore/java/security/CpuFeatures.java
+++ b/support/src/test/java/libcore/java/security/CpuFeatures.java
@@ -16,47 +16,87 @@
package libcore.java.security;
+import android.system.Os;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import dalvik.system.VMRuntime;
-class CpuFeatures {
+public class CpuFeatures {
+ /** Machine architecture, determined from the "machine" value returned by uname() */
+ private enum Arch {
+ // 64bit ARM can return armv8 or aarch64.
+ // 32bit ARM should return armv7 or armv7a
+ ARM("^aarch.*|^arm.*"),
+ // 64bit Android and Linux generally return x86_64.
+ // 32bit Android and Linux generally return i686
+ // Other host architectures can potentially return x86 or i386.
+ X86("^x86.*|i386|i686");
+
+ private final String machineRegex;
+
+ Arch(String machineRegex) {
+ this.machineRegex = machineRegex;
+ }
+
+ /**
+ * Returns the architecture of this machine by matching against output from uname()
+ * against the regex for each known family.
+ */
+ public static Arch currentArch() {
+ String machine = Os.uname().machine;
+ for (Arch type : values()) {
+ if (machine.matches(type.machineRegex)) {
+ return type;
+ }
+ }
+ throw new IllegalStateException("Unknown machine value: " + machine);
+ }
+ }
+
+ private enum InstructionSet {
+ ARM_32(Arch.ARM, "arm"),
+ ARM_64(Arch.ARM, "arm64"),
+ X86_32(Arch.X86, "x86"),
+ X86_64(Arch.X86, "x86_64");
+
+ private final Arch arch;
+ private final String name;
+
+ InstructionSet(Arch arch, String name) {
+ this.arch = arch;
+ this.name = name;
+ }
+
+ public Arch architecture() {
+ return arch;
+ }
+
+ /**
+ * Returns the current InstructionSet set by matching against the name fields above.
+ */
+ public static InstructionSet currentInstructionSet() {
+ // Always returns one of the values from VMRuntime.ABI_TO_INSTRUCTION_SET_MAP.
+ String instructionSet = VMRuntime.getCurrentInstructionSet();
+ for (InstructionSet set : values()) {
+ if (instructionSet.equals(set.name)) {
+ return set;
+ }
+ }
+ throw new IllegalStateException("Unknown instruction set: " + instructionSet);
+ }
+ }
+
private CpuFeatures() {
}
- static boolean isAESHardwareAccelerated() {
- // Expectations based on CPU type: If these aren't met then Conscrypt
- // integration tests will fail and the cause should be investigated.
- String instructionSet = VMRuntime.getCurrentInstructionSet();
- if (instructionSet.startsWith("arm")) {
- // All ARM CPUs with the "aes" feature should have hardware AES.
- List<String> features = getListFromCpuinfo("Features");
- if (features != null && features.contains("aes")) {
- return true;
- }
- } else if (instructionSet.startsWith("x86")) {
- // x86 CPUs with the "aes" flag and running in 64bit mode should have hardware AES.
- if ("x86_64".equals(instructionSet)) {
- List<String> flags = getListFromCpuinfo("flags");
- if (flags != null && flags.contains("aes")) {
- return true;
- }
- } else {
- // Hardware AES not supported in 32bit mode.
- return false;
- }
- }
-
- // Otherwise trust Conscrypt NativeCrypto's own checks, for example if we're in an
- // emulated ABI, it might bridge to a library that has accelerated AES instructions.
+ /**
+ * Returns true if this device has hardware AES support as determined by BoringSSL.
+ */
+ public static boolean isAesHardwareAccelerated() {
try {
Class<?> nativeCrypto = Class.forName("com.android.org.conscrypt.NativeCrypto");
Method EVP_has_aes_hardware = nativeCrypto.getDeclaredMethod("EVP_has_aes_hardware");
@@ -71,33 +111,51 @@
return false;
}
- private static String getFieldFromCpuinfo(String field) {
- try {
- BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"));
- Pattern p = Pattern.compile(field + "\\s*:\\s*(.*)");
+ /**
+ * Returns true if this device should have hardware AES support based on CPU information.
+ *
+ * A return value of false means that acceleration isn't expected, but it may still be available
+ * e.g. via bridging to a native library in an emulated environment.
+ */
+ public static boolean isKnownToSupportHardwareAes() {
+ Arch architecture = Arch.currentArch();
+ InstructionSet instructionSet = InstructionSet.currentInstructionSet();
- try {
- String line;
- while ((line = br.readLine()) != null) {
- Matcher m = p.matcher(line);
- if (m.matches()) {
- return m.group(1);
- }
+ if (!instructionSet.architecture().equals(architecture)) {
+ // Different architectures imply an emulated environment, so unable to determine if
+ // hardware acceleration is expected. Assume not.
+ return false;
+ }
+
+ if (architecture.equals(Arch.ARM)) {
+ // All ARM CPUs (32 and 64 bit) with the "aes" feature should have hardware AES.
+ return cpuFieldContainsAes("Features");
+ } else if (instructionSet.equals(InstructionSet.X86_64)) {
+ // x86 CPUs with the "aes" flag and running in 64bit mode should have hardware AES.
+ // Hardware AES is not *expected* in 32bit mode, but may be available.
+ return cpuFieldContainsAes("flags");
+ }
+ return false;
+ }
+
+
+ /**
+ * Returns true if any line in the output from /proc/cpuinfo matches the provided
+ * field name and contains the word "aes" in its list of values.
+ *
+ * Example line from /proc/cpuinfo: Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
+ */
+ private static boolean cpuFieldContainsAes(String fieldName) {
+ try (BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"))) {
+ String regex = "^" + fieldName + "\\s*:.*\\baes\\b.*";
+ String line;
+ while ((line = br.readLine()) != null) {
+ if (line.matches(regex)) {
+ return true;
}
- } finally {
- br.close();
}
} catch (IOException ignored) {
}
-
- return null;
- }
-
- private static List<String> getListFromCpuinfo(String fieldName) {
- String features = getFieldFromCpuinfo(fieldName);
- if (features == null)
- return null;
-
- return Arrays.asList(features.split("\\s"));
+ return false;
}
}
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index d53117b..7521cf9 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -757,7 +757,7 @@
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
"SSL_RSA_WITH_RC4_128_MD5",
"TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
- : CpuFeatures.isAESHardwareAccelerated() ? CIPHER_SUITES_ANDROID_AES_HARDWARE
+ : CpuFeatures.isAesHardwareAccelerated() ? CIPHER_SUITES_ANDROID_AES_HARDWARE
: CIPHER_SUITES_ANDROID_SOFTWARE;
private static final Map<String, Class<? extends KeySpec>> PRIVATE_KEY_SPEC_CLASSES;