Merge "Implement virtual-device-only known failures in LibcoreTest."
diff --git a/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/LibcoreTest.java b/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/LibcoreTest.java
index f4021b2..980315a 100644
--- a/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/LibcoreTest.java
+++ b/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/LibcoreTest.java
@@ -16,6 +16,8 @@
 
 package com.android.compatibility.testtype;
 
+import static java.util.stream.Collectors.toList;
+
 import com.android.tradefed.config.Option;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
@@ -25,6 +27,8 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
 
 /**
  * A specialized test type for Libcore tests that provides the ability to specify a set of
@@ -41,13 +45,20 @@
             + "expectation file")
     private List<String> mCoreExpectations = new ArrayList<>();
 
+    @Option(name = "virtual-device-core-expectation", description = "Provides failure expectations "
+            + "on virtual devices only for libcore tests via the specified file; the path must be "
+            + "absolute and will be resolved to matching bundled resource files; this parameter "
+            + "should be repeated for each expectation file")
+    private List<String> mVirtualDeviceCoreExpectations = new ArrayList<>();
+
     /**
      * {@inheritDoc}
      */
     @Override
     public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        if (!mCoreExpectations.isEmpty()) {
-            addInstrumentationArg(INSTRUMENTATION_ARG_NAME, ArrayUtil.join(",", mCoreExpectations));
+        List<String> coreExpectations = getCoreExpectations();
+        if (!coreExpectations.isEmpty()) {
+            addInstrumentationArg(INSTRUMENTATION_ARG_NAME, ArrayUtil.join(",", coreExpectations));
         }
 
         if (getTestPackageName() != null && getClassName() != null) {
@@ -61,4 +72,18 @@
         }
         super.run(listener);
     }
+
+    private List<String> getCoreExpectations() throws DeviceNotAvailableException {
+        if (isVirtualDevice()) {
+                return Stream.concat(
+                        mCoreExpectations.stream(), mVirtualDeviceCoreExpectations.stream())
+                    .collect(toList());
+        } else {
+            return mCoreExpectations;
+        }
+    }
+
+    private boolean isVirtualDevice() throws DeviceNotAvailableException {
+        return Objects.equals(getDevice().getProperty("ro.hardware.virtual_device"), "1");
+    }
 }
diff --git a/tests/libcore/luni/Android.bp b/tests/libcore/luni/Android.bp
index bd647c7..1a4416b 100644
--- a/tests/libcore/luni/Android.bp
+++ b/tests/libcore/luni/Android.bp
@@ -55,8 +55,6 @@
         "general-tests",
 	"mts",
     ],
-    // NOTE: virtualdeviceknownfailures.txt is only used for simulated/cloud-based
-    // continuous build configurations, so it's not referenced in AndroidTest.xml
     java_resources: [
         ":libcore-expectations-knownfailures",
         ":libcore-expectations-virtualdeviceknownfailures",
diff --git a/tests/libcore/luni/AndroidTest.xml b/tests/libcore/luni/AndroidTest.xml
index 85728a8..7fef84d 100644
--- a/tests/libcore/luni/AndroidTest.xml
+++ b/tests/libcore/luni/AndroidTest.xml
@@ -33,6 +33,7 @@
         <option name="instrumentation-arg" key="filter"
                 value="com.android.cts.core.runner.ExpectationBasedFilter" />
         <option name="core-expectation" value="/knownfailures.txt" />
+        <option name="virtual-device-core-expectation" value="/virtualdeviceknownfailures.txt" />
         <option name="runtime-hint" value="45m"/>
         <!-- 20x default timeout of 600sec -->
         <option name="shell-timeout" value="12000000"/>