[Cherrypick] Allow enabling ANGLE for dEQP.

For example, the "--module-arg 'CtsDeqpTestCases:deqp-use-angle:vulkan'"
in the following command:

Bug: 80239516
Test: run cts-unit-tests
Change-Id: I55de264817123e3a87b0deae3f434e65ac3d54f8
Merged-In: If7fa753ee12b66e147bee3fe1e2ec6016bfa556a
diff --git a/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java b/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
index 1e239aa..ad94193 100644
--- a/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
+++ b/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
@@ -92,6 +92,10 @@
     private static final int TESTCASE_BATCH_LIMIT = 1000;
     private static final int UNRESPONSIVE_CMD_TIMEOUT_MS = 10 * 60 * 1000; // 10min
 
+    private static final String ANGLE_NONE = "none";
+    private static final String ANGLE_VULKAN = "vulkan";
+    private static final String ANGLE_OPENGLES = "opengles";
+
     // !NOTE: There's a static method copyOptions() for copying options during split.
     // If you add state update copyOptions() as appropriate!
 
@@ -141,6 +145,11 @@
             description="The estimated config runtime. Defaults to 200ms x num tests.")
     private long mRuntimeHint = -1;
 
+    @Option(name="deqp-use-angle",
+            description="ANGLE backend ('none', 'vulkan', 'opengles'). Defaults to 'none' (don't use ANGLE)",
+            importance=Option.Importance.NEVER)
+    private String mAngle = "none";
+
     private Collection<TestDescription> mRemainingTests = null;
     private Map<TestDescription, Set<BatchRunConfiguration>> mTestInstances = null;
     private final TestInstanceResultListener mInstanceListerner = new TestInstanceResultListener();
@@ -2010,6 +2019,72 @@
     }
 
     /**
+     * Set up the test environment.
+     */
+    private void setupTestEnvironment() throws DeviceNotAvailableException {
+        try {
+            // Get the system into a known state.
+            // FIXME -- b/115906203 -- Skia Vulkan workaround
+            mDevice.executeShellCommand("setprop debug.hwui.renderer none");
+            // Clear ANGLE Global.Settings values
+            mDevice.executeShellCommand("settings put global angle_gl_driver_selection_pkgs \"\"");
+            mDevice.executeShellCommand("settings put global angle_gl_driver_selection_values \"\"");
+
+            // ANGLE
+            if (mAngle.equals(ANGLE_VULKAN)) {
+                CLog.i("Configuring ANGLE to use: " + mAngle);
+                // FIXME -- b/115906203 -- Skia Vulkan workaround
+                mDevice.executeShellCommand("setprop debug.hwui.renderer skiavk");
+                // Force dEQP to use ANGLE
+                mDevice.executeShellCommand(
+                    "settings put global angle_gl_driver_selection_pkgs " + DEQP_ONDEVICE_PKG);
+                mDevice.executeShellCommand(
+                    "settings put global angle_gl_driver_selection_values angle");
+                // Configure ANGLE to use Vulkan
+                mDevice.executeShellCommand("setprop debug.angle.backend 2");
+            } else if (mAngle.equals(ANGLE_OPENGLES)) {
+                CLog.i("Configuring ANGLE to use: " + mAngle);
+                // Force dEQP to use ANGLE
+                mDevice.executeShellCommand(
+                    "settings put global angle_gl_driver_selection_pkgs " + DEQP_ONDEVICE_PKG);
+                mDevice.executeShellCommand(
+                    "settings put global angle_gl_driver_selection_values angle");
+                // Configure ANGLE to use Vulkan
+                mDevice.executeShellCommand("setprop debug.angle.backend 0");
+            }
+        } catch (DeviceNotAvailableException ex) {
+            // chain forward
+            CLog.e("Failed to set up ANGLE correctly.");
+            throw new DeviceNotAvailableException("Device not available",
+                mDevice.getSerialNumber());
+        }
+    }
+
+    /**
+     * Clean up the test environment.
+     */
+    private void teardownTestEnvironment() throws DeviceNotAvailableException {
+        // ANGLE
+        try {
+            if (!mAngle.equals(ANGLE_NONE)) {
+                CLog.i("Cleaning up ANGLE");
+                if (mAngle.equals(ANGLE_VULKAN)) {
+                    // FIXME -- b/115906203 -- Undo Skia Vulkan workaround
+                    mDevice.executeShellCommand("setprop debug.hwui.renderer none");
+                }
+                // Stop forcing dEQP to use ANGLE
+                mDevice.executeShellCommand("settings put global angle_gl_driver_selection_pkgs \"\"");
+                mDevice.executeShellCommand("settings put global angle_gl_driver_selection_values \"\"");
+            }
+        } catch (DeviceNotAvailableException ex) {
+            // chain forward
+            CLog.e("Failed to clean up ANGLE correctly.");
+            throw new DeviceNotAvailableException("Device not available",
+                mDevice.getSerialNumber());
+        }
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -2040,7 +2115,9 @@
             } else if (!mRemainingTests.isEmpty()) {
                 mInstanceListerner.setSink(listener);
                 mDeviceRecovery.setDevice(mDevice);
+                setupTestEnvironment();
                 runTests();
+                teardownTestEnvironment();
             }
         } catch (CapabilityQueryFailureException ex) {
             // Platform is not behaving correctly, for example crashing when trying to create
@@ -2138,6 +2215,7 @@
         destination.mAbi = source.mAbi;
         destination.mLogData = source.mLogData;
         destination.mCollectTestsOnly = source.mCollectTestsOnly;
+        destination.mAngle = source.mAngle;
     }
 
     /**
diff --git a/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java b/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java
index 06e5b0c..8fae4b7 100644
--- a/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java
+++ b/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java
@@ -224,6 +224,13 @@
         if (majorVersion > requiredMajorVersion
                 || (majorVersion == requiredMajorVersion && minorVersion >= requiredMinorVersion)) {
 
+            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+                andReturn("").once();
+            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+                andReturn("").once();
+            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+                andReturn("").once();
+
             expectRenderConfigQuery(mockDevice, requiredMajorVersion,
                     requiredMinorVersion);
 
@@ -368,6 +375,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testStarted(EasyMock.eq(testId));
         EasyMock.expectLastCall().once();
 
@@ -525,6 +539,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), testPaths.length);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         for (int i = 0; i < testPaths.length; i++) {
             mockListener.testStarted(EasyMock.eq(testIds[i]));
             EasyMock.expectLastCall().once();
@@ -605,6 +626,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), expectedTests.size());
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         IDevice mockIDevice = EasyMock.createMock(IDevice.class);
         if (thereAreTests)
         {
@@ -767,6 +795,7 @@
                 = EasyMock.createStrictMock(ITestInvocationListener.class);
         mockListener.testRunStarted(getTestId(deqpTest), 0);
         EasyMock.expectLastCall().once();
+
         mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
         EasyMock.expectLastCall().once();
 
@@ -854,6 +883,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), testPaths.length);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         for (int i = 0; i < testPaths.length; i++) {
             mockListener.testStarted(EasyMock.eq(testIds[i]));
             EasyMock.expectLastCall().once();
@@ -911,6 +947,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
         EasyMock.expectLastCall().once();
 
@@ -953,6 +996,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
         EasyMock.expectLastCall().once();
 
@@ -1055,6 +1105,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testStarted(EasyMock.eq(testId));
         EasyMock.expectLastCall().once();
 
@@ -1264,6 +1321,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testStarted(EasyMock.eq(testId));
         EasyMock.expectLastCall().once();
 
@@ -1621,6 +1685,14 @@
 
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
+
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testRunEnded(EasyMock.anyLong(), (Map<String, String>) EasyMock.anyObject());
         EasyMock.expectLastCall().once();
 
@@ -1663,6 +1735,13 @@
             mockListener.testRunStarted(getTestId(shard), shardTests.size());
             EasyMock.expectLastCall().once();
 
+            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+                andReturn("").once();
+            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+                andReturn("").once();
+            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+                andReturn("").once();
+
             expectRenderConfigQuery(mockDevice, 3, 0);
 
             String testOut = buildTestProcessOutput(shardTests);
@@ -1814,6 +1893,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), 1);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         mockListener.testStarted(EasyMock.eq(testId));
         EasyMock.expectLastCall().once();
 
@@ -1970,6 +2056,13 @@
         mockListener.testRunStarted(getTestId(deqpTest), testPaths.length);
         EasyMock.expectLastCall().once();
 
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("setprop debug.hwui.renderer none"))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_pkgs \"\""))).
+            andReturn("").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("settings put global angle_gl_driver_selection_values \"\""))).
+            andReturn("").once();
+
         for (int i = 0; i < testPaths.length; i++) {
             mockListener.testStarted(EasyMock.eq(testIds[i]));
             EasyMock.expectLastCall().once();