Add ANGLE Rules File Hostside Tests

Add ANGLE CTS hostside tests to ensure that ANGLE can successfully
process rules files that determine if ANGLE should be loaded or not.

Bug: 80239516
Test: Verify new and existing ANGLE CTS hostside tests pass.
Change-Id: Ib7424692251ed8cf7b0dda1498248ac3a1624f61
diff --git a/hostsidetests/angle/Android.mk b/hostsidetests/angle/Android.mk
index 0a2cb80..e54985d 100644
--- a/hostsidetests/angle/Android.mk
+++ b/hostsidetests/angle/Android.mk
@@ -17,6 +17,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_JAVA_RESOURCE_DIRS := assets/
+
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
diff --git a/hostsidetests/angle/AndroidTest.xml b/hostsidetests/angle/AndroidTest.xml
index d6d5d6f..c72618a 100644
--- a/hostsidetests/angle/AndroidTest.xml
+++ b/hostsidetests/angle/AndroidTest.xml
@@ -19,7 +19,7 @@
     <option name="config-descriptor:metadata" key="component" value="graphics" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsAngleDeveloperOptionTestCases.apk" />
+        <option name="test-file-name" value="CtsAngleDriverTestCases.apk" />
     </target_preparer>
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsAngleIntegrationHostTestCases.jar" />
diff --git a/hostsidetests/angle/app/developerOptionSecondary/Android.mk b/hostsidetests/angle/app/developerOptionSecondary/Android.mk
deleted file mode 100644
index c8c94c0..0000000
--- a/hostsidetests/angle/app/developerOptionSecondary/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-java-files-under, ../common)
-
-LOCAL_MODULE_TAGS := tests
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_PACKAGE_NAME := CtsAngleDeveloperOptionSecondaryTestCases
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test AngleIntegrationTestCommon
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/angle/app/developerOptionSecondary/AndroidManifest.xml b/hostsidetests/angle/app/developerOptionSecondary/AndroidManifest.xml
deleted file mode 100755
index 8274dd9..0000000
--- a/hostsidetests/angle/app/developerOptionSecondary/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-# Copyright (C) 2018 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.angleIntegrationTest.developerOptionSecondary">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-
-        <activity android:name="com.android.angleIntegrationTest.common.AngleIntegrationTestActivity" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.angleIntegrationTest.developerOptionSecondary" />
-
-</manifest>
-
-
diff --git a/hostsidetests/angle/app/developerOption/Android.mk b/hostsidetests/angle/app/driverTest/Android.mk
similarity index 95%
rename from hostsidetests/angle/app/developerOption/Android.mk
rename to hostsidetests/angle/app/driverTest/Android.mk
index 3bb059f..9d8d629 100644
--- a/hostsidetests/angle/app/developerOption/Android.mk
+++ b/hostsidetests/angle/app/driverTest/Android.mk
@@ -22,7 +22,7 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_PACKAGE_NAME := CtsAngleDeveloperOptionTestCases
+LOCAL_PACKAGE_NAME := CtsAngleDriverTestCases
 
 LOCAL_SDK_VERSION := current
 
diff --git a/hostsidetests/angle/app/developerOption/AndroidManifest.xml b/hostsidetests/angle/app/driverTest/AndroidManifest.xml
similarity index 93%
rename from hostsidetests/angle/app/developerOption/AndroidManifest.xml
rename to hostsidetests/angle/app/driverTest/AndroidManifest.xml
index fbafe93..03c3c53 100755
--- a/hostsidetests/angle/app/developerOption/AndroidManifest.xml
+++ b/hostsidetests/angle/app/driverTest/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.angleIntegrationTest.developerOption">
+    package="com.android.angleIntegrationTest.driverTest">
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -31,7 +31,7 @@
 
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.angleIntegrationTest.developerOption" />
+        android:targetPackage="com.android.angleIntegrationTest.driverTest" />
 
 </manifest>
 
diff --git a/hostsidetests/angle/app/developerOption/src/com/android/angleIntegrationTest/developerOption/AngleDeveloperOptionActivityTest.java b/hostsidetests/angle/app/driverTest/src/com/android/angleIntegrationTest/driverTest/AngleDriverTestActivity.java
similarity index 95%
rename from hostsidetests/angle/app/developerOption/src/com/android/angleIntegrationTest/developerOption/AngleDeveloperOptionActivityTest.java
rename to hostsidetests/angle/app/driverTest/src/com/android/angleIntegrationTest/driverTest/AngleDriverTestActivity.java
index 2e5470e..ca81946 100644
--- a/hostsidetests/angle/app/developerOption/src/com/android/angleIntegrationTest/developerOption/AngleDeveloperOptionActivityTest.java
+++ b/hostsidetests/angle/app/driverTest/src/com/android/angleIntegrationTest/driverTest/AngleDriverTestActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.angleIntegrationTest.developerOption;
+package com.android.angleIntegrationTest.driverTest;
 
 import com.android.angleIntegrationTest.common.AngleIntegrationTestActivity;
 import com.android.angleIntegrationTest.common.GlesView;
@@ -35,7 +35,7 @@
 import java.lang.Override;
 
 @RunWith(AndroidJUnit4.class)
-public class AngleDeveloperOptionActivityTest {
+public class AngleDriverTestActivity {
 
     private final String TAG = this.getClass().getSimpleName();
 
diff --git a/hostsidetests/angle/app/developerOption/Android.mk b/hostsidetests/angle/app/driverTestSecondary/Android.mk
similarity index 95%
copy from hostsidetests/angle/app/developerOption/Android.mk
copy to hostsidetests/angle/app/driverTestSecondary/Android.mk
index 3bb059f..87855e8 100644
--- a/hostsidetests/angle/app/developerOption/Android.mk
+++ b/hostsidetests/angle/app/driverTestSecondary/Android.mk
@@ -22,7 +22,7 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_PACKAGE_NAME := CtsAngleDeveloperOptionTestCases
+LOCAL_PACKAGE_NAME := CtsAngleDriverTestCasesSecondary
 
 LOCAL_SDK_VERSION := current
 
diff --git a/hostsidetests/angle/app/developerOption/AndroidManifest.xml b/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
similarity index 93%
copy from hostsidetests/angle/app/developerOption/AndroidManifest.xml
copy to hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
index fbafe93..1d8f1a7 100755
--- a/hostsidetests/angle/app/developerOption/AndroidManifest.xml
+++ b/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.angleIntegrationTest.developerOption">
+    package="com.android.angleIntegrationTest.driverTestSecondary">
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -31,8 +31,6 @@
 
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.angleIntegrationTest.developerOption" />
+        android:targetPackage="com.android.angleIntegrationTest.driverTestSecondary" />
 
 </manifest>
-
-
diff --git a/hostsidetests/angle/app/developerOptionSecondary/src/com/android/angleIntegrationTest/developerOptionSecondary/AngleDeveloperOptionActivityTest.java b/hostsidetests/angle/app/driverTestSecondary/src/com/android/angleIntegrationTest/driverTestSecondary/AngleDriverTestActivity.java
similarity index 94%
rename from hostsidetests/angle/app/developerOptionSecondary/src/com/android/angleIntegrationTest/developerOptionSecondary/AngleDeveloperOptionActivityTest.java
rename to hostsidetests/angle/app/driverTestSecondary/src/com/android/angleIntegrationTest/driverTestSecondary/AngleDriverTestActivity.java
index 2065a04..0ecd766 100644
--- a/hostsidetests/angle/app/developerOptionSecondary/src/com/android/angleIntegrationTest/developerOptionSecondary/AngleDeveloperOptionActivityTest.java
+++ b/hostsidetests/angle/app/driverTestSecondary/src/com/android/angleIntegrationTest/driverTestSecondary/AngleDriverTestActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.angleIntegrationTest.developerOptionSecondary;
+package com.android.angleIntegrationTest.driverTestSecondary;
 
 import com.android.angleIntegrationTest.common.AngleIntegrationTestActivity;
 import com.android.angleIntegrationTest.common.GlesView;
@@ -35,7 +35,7 @@
 import java.lang.Override;
 
 @RunWith(AndroidJUnit4.class)
-public class AngleDeveloperOptionActivityTest {
+public class AngleDriverTestActivity {
 
     private final String TAG = this.getClass().getSimpleName();
 
diff --git a/hostsidetests/angle/assets/emptyRules.json b/hostsidetests/angle/assets/emptyRules.json
new file mode 100644
index 0000000..77fa0c0
--- /dev/null
+++ b/hostsidetests/angle/assets/emptyRules.json
@@ -0,0 +1,8 @@
+{
+  "Rules":[
+    {
+      "Rule":"Default Rule (i.e. use native driver)",
+      "UseANGLE":false
+    }
+  ]
+}
diff --git a/hostsidetests/angle/assets/enableAngleRules.json b/hostsidetests/angle/assets/enableAngleRules.json
new file mode 100644
index 0000000..90f4893
--- /dev/null
+++ b/hostsidetests/angle/assets/enableAngleRules.json
@@ -0,0 +1,17 @@
+{
+  "Rules":[
+    {
+      "Rule":"Default Rule (i.e. use native driver)",
+      "UseANGLE":false
+    },
+    {
+      "Rule":"Supported application(s) (e.g. Maps on Google devices)",
+      "UseANGLE":true,
+      "Applications":[
+        {
+          "AppName":"com.android.angleIntegrationTest.driverTest"
+        }
+      ]
+    }
+  ]
+}
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
new file mode 100644
index 0000000..a789ca4
--- /dev/null
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 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 android.angle.cts;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.device.PackageInfo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CtsAngleCommon {
+    // Settings.Global
+    static final String SETTINGS_GLOBAL_ALL_USE_ANGLE = "angle_gl_driver_all_angle";
+    static final String SETTINGS_GLOBAL_DRIVER_PKGS = "angle_gl_driver_selection_pkgs";
+    static final String SETTINGS_GLOBAL_DRIVER_VALUES = "angle_gl_driver_selection_values";
+
+    // System Properties
+    static final String PROPERTY_BUILD_TYPE = "ro.build.type";
+    static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
+    static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+    static final String PROPERTY_TEMP_RULES_FILE = "debug.angle.rules";
+    static final String PROPERTY_ENABLE_RULES_FILE = "debug.angle.enable";
+
+    // Rules File
+    static final String DEVICE_TEMP_RULES_FILE_DIRECTORY = "/data/local/tmp";
+    static final String DEVICE_TEMP_RULES_FILE_FILENAME = "a4a_rules.json";
+    static final String DEVICE_TEMP_RULES_FILE_PATH = DEVICE_TEMP_RULES_FILE_DIRECTORY + "/" + DEVICE_TEMP_RULES_FILE_FILENAME;
+
+    // ANGLE
+    static final String ANGLE_PKG = "com.google.android.angle";
+    static final String ANGLE_DRIVER_TEST_PKG = "com.android.angleIntegrationTest.driverTest";
+    static final String ANGLE_DRIVER_TEST_SEC_PKG = "com.android.angleIntegrationTest.driverTestSecondary";
+    static final String ANGLE_DRIVER_TEST_CLASS = "AngleDriverTestActivity";
+    static final String ANGLE_DRIVER_TEST_DEFAULT_METHOD = "testUseDefaultDriver";
+    static final String ANGLE_DRIVER_TEST_ANGLE_METHOD = "testUseAngleDriver";
+    static final String ANGLE_DRIVER_TEST_NATIVE_METHOD = "testUseNativeDriver";
+    static final String ANGLE_DRIVER_TEST_APP = "CtsAngleDriverTestCases.apk";
+    static final String ANGLE_DRIVER_TEST_SEC_APP = "CtsAngleDriverTestCasesSecondary.apk";
+    static final String ANGLE_DRIVER_TEST_ACTIVITY =
+            ANGLE_DRIVER_TEST_PKG + "/com.android.angleIntegrationTest.common.AngleIntegrationTestActivity";
+    static final String ANGLE_DRIVER_TEST_SEC_ACTIVITY =
+            ANGLE_DRIVER_TEST_SEC_PKG + "/com.android.angleIntegrationTest.common.AngleIntegrationTestActivity";
+    static final String ANGLE_MAIN_ACTIVTY = ANGLE_PKG + "/.MainActivity";
+
+    enum OpenGlDriverChoice {
+        DEFAULT,
+        NATIVE,
+        ANGLE
+    }
+
+    static final Map<OpenGlDriverChoice, String> sDriverGlobalSettingMap = buildDriverGlobalSettingMap();
+    static Map<OpenGlDriverChoice, String> buildDriverGlobalSettingMap() {
+        Map<OpenGlDriverChoice, String> map = new HashMap<>();
+        map.put(OpenGlDriverChoice.DEFAULT, "default");
+        map.put(OpenGlDriverChoice.ANGLE, "angle");
+        map.put(OpenGlDriverChoice.NATIVE, "native");
+
+        return map;
+    }
+
+    static final Map<OpenGlDriverChoice, String> sDriverTestMethodMap = buildDriverTestMethodMap();
+    static Map<OpenGlDriverChoice, String> buildDriverTestMethodMap() {
+        Map<OpenGlDriverChoice, String> map = new HashMap<>();
+        map.put(OpenGlDriverChoice.DEFAULT, ANGLE_DRIVER_TEST_DEFAULT_METHOD);
+        map.put(OpenGlDriverChoice.ANGLE, ANGLE_DRIVER_TEST_ANGLE_METHOD);
+        map.put(OpenGlDriverChoice.NATIVE, ANGLE_DRIVER_TEST_NATIVE_METHOD);
+
+        return map;
+    }
+
+    static void clearSettings(ITestDevice device) throws Exception {
+        device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_ALL_USE_ANGLE, "0");
+        device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS, "\"\"");
+        device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES, "\"\"");
+        CtsAngleCommon.setProperty(device, CtsAngleCommon.PROPERTY_TEMP_RULES_FILE, "\"\"");
+        CtsAngleCommon.setProperty(device, CtsAngleCommon.PROPERTY_ENABLE_RULES_FILE, "0");
+    }
+
+    static boolean isAngleLoadable(ITestDevice device) throws Exception {
+        PackageInfo anglePkgInfo = device.getAppPackageInfo(ANGLE_PKG);
+        String propDisablePreloading = device.getProperty(PROPERTY_DISABLE_OPENGL_PRELOADING);
+        String propGfxDriver = device.getProperty(PROPERTY_GFX_DRIVER);
+
+        // Make sure ANGLE exists on the device
+        if(anglePkgInfo == null) {
+            return false;
+        }
+
+        // This logic is attempting to mimic ZygoteInit.java::ZygoteInit#preloadOpenGL()
+        if (((propDisablePreloading != null) && propDisablePreloading.equals("false")) &&
+                ((propGfxDriver == null) || propGfxDriver.isEmpty())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    static void startActivity(ITestDevice device, String activity) throws Exception {
+        // Run the ANGLE activity so it'll clear up any 'default' settings.
+        device.executeShellCommand("am start -S -W -n \"" + activity + "\"");
+    }
+
+    static void stopPackage(ITestDevice device, String pkgName) throws Exception {
+        device.executeShellCommand("am force-stop " + pkgName);
+    }
+
+    /**
+     * Work around the fact that INativeDevice.enableAdbRoot() is not supported.
+     */
+    static void setProperty(ITestDevice device, String property, String value) throws Exception {
+        device.executeShellCommand("setprop " + property + " " + value);
+    }
+}
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
index e973ad7..cda98e3 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
@@ -18,7 +18,6 @@
 import com.android.ddmlib.Log.LogLevel;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.PackageInfo;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.IDeviceTest;
@@ -45,76 +44,6 @@
 
     private static final String TAG = CtsAngleDeveloperOptionHostTest.class.getSimpleName();
 
-    // Settings.Global
-    private static final String SETTINGS_GLOBAL_ALL_USE_ANGLE = "angle_gl_driver_all_angle";
-    private static final String SETTINGS_GLOBAL_DRIVER_PKGS = "angle_gl_driver_selection_pkgs";
-    private static final String SETTINGS_GLOBAL_DRIVER_VALUES = "angle_gl_driver_selection_values";
-
-    // System Properties
-    private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
-    private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
-
-    // ANGLE
-    private static final String ANGLE_PKG = "com.google.android.angle";
-    private static final String ANGLE_DEV_OPTION_PKG = "com.android.angleIntegrationTest.developerOption";
-    private static final String ANGLE_DEV_OPTION_SEC_PKG = "com.android.angleIntegrationTest.developerOptionSecondary";
-    private static final String ANGLE_DEV_OPTION_CLASS = "AngleDeveloperOptionActivityTest";
-    private static final String ANGLE_DEV_OPTION_DEFAULT_METHOD = "testUseDefaultDriver";
-    private static final String ANGLE_DEV_OPTION_ANGLE_METHOD = "testUseAngleDriver";
-    private static final String ANGLE_DEV_OPTION_NATIVE_METHOD = "testUseNativeDriver";
-    private static final String ANGLE_DEV_OPTION_APP = "CtsAngleDeveloperOptionTestCases.apk";
-    private static final String ANGLE_DEV_OPTION_SEC_APP = "CtsAngleDeveloperOptionSecondaryTestCases.apk";
-    private static final String ANGLE_DEV_OPTION_ACTIVITY =
-            ANGLE_DEV_OPTION_PKG + "/com.android.angleIntegrationTest.common.AngleIntegrationTestActivity";
-    private static final String ANGLE_DEV_OPTION_SEC_ACTIVITY =
-            ANGLE_DEV_OPTION_SEC_PKG + "/com.android.angleIntegrationTest.common.AngleIntegrationTestActivity";
-    private static final String ANGLE_MAIN_ACTIVTY = ANGLE_PKG + "/.MainActivity";
-
-    enum OpenGlDriverChoice {
-        DEFAULT,
-        NATIVE,
-        ANGLE
-    }
-
-    private static final Map<OpenGlDriverChoice, String> sDriverGlobalSettingMap = buildDriverGlobalSettingMap();
-    private static Map<OpenGlDriverChoice, String> buildDriverGlobalSettingMap() {
-        Map<OpenGlDriverChoice, String> map = new HashMap<>();
-        map.put(OpenGlDriverChoice.DEFAULT, "default");
-        map.put(OpenGlDriverChoice.ANGLE, "angle");
-        map.put(OpenGlDriverChoice.NATIVE, "native");
-
-        return map;
-    }
-
-    private static final Map<OpenGlDriverChoice, String> sDriverTestMethodMap = buildDriverTestMethodMap();
-    private static Map<OpenGlDriverChoice, String> buildDriverTestMethodMap() {
-        Map<OpenGlDriverChoice, String> map = new HashMap<>();
-        map.put(OpenGlDriverChoice.DEFAULT, ANGLE_DEV_OPTION_DEFAULT_METHOD);
-        map.put(OpenGlDriverChoice.ANGLE, ANGLE_DEV_OPTION_ANGLE_METHOD);
-        map.put(OpenGlDriverChoice.NATIVE, ANGLE_DEV_OPTION_NATIVE_METHOD);
-
-        return map;
-    }
-
-    private boolean isAngleLoadable() throws Exception {
-        PackageInfo anglePkgInfo = getDevice().getAppPackageInfo(ANGLE_PKG);
-        String propDisablePreloading = getDevice().getProperty(PROPERTY_DISABLE_OPENGL_PRELOADING);
-        String propGfxDriver = getDevice().getProperty(PROPERTY_GFX_DRIVER);
-
-        // Make sure ANGLE exists on the device
-        if(anglePkgInfo == null) {
-            return false;
-        }
-
-        // This logic is attempting to mimic ZygoteInit.java::ZygoteInit#preloadOpenGL()
-        if (((propDisablePreloading != null) && propDisablePreloading.equals("false")) &&
-            ((propGfxDriver == null) || propGfxDriver.isEmpty())) {
-            return false;
-        }
-
-        return true;
-    }
-
     private String getDevOption(String devOption) throws Exception {
         return getDevice().getSetting("global", devOption);
     }
@@ -123,53 +52,50 @@
         CLog.logAndDisplay(LogLevel.INFO, "Updating Global.Settings: pkgName = '" +
                 pkgName + "', driverValue = '" + driverValue + "'");
 
-        getDevice().setSetting("global", SETTINGS_GLOBAL_DRIVER_PKGS, pkgName);
-        getDevice().setSetting("global", SETTINGS_GLOBAL_DRIVER_VALUES, driverValue);
+        getDevice().setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS, pkgName);
+        getDevice().setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES, driverValue);
 
-        String devOption = getDevOption(SETTINGS_GLOBAL_DRIVER_PKGS);
+        String devOption = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS);
         Assert.assertEquals(
-                "Developer option '" + SETTINGS_GLOBAL_DRIVER_PKGS +
+                "Developer option '" + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS +
                         "' was not set correctly: '" + devOption + "'",
                 pkgName, devOption);
 
-        devOption = getDevOption(SETTINGS_GLOBAL_DRIVER_VALUES);
+        devOption = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES);
         Assert.assertEquals(
-                "Developer option '" + SETTINGS_GLOBAL_DRIVER_VALUES +
+                "Developer option '" + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES +
                         "' was not set correctly: '" + driverValue + "'",
                 driverValue, devOption);
     }
 
-    private void startActivity(String activity) throws Exception {
-        // Run the ANGLE activity so it'll clear up any 'default' settings.
-        getDevice().executeShellCommand("am start -S -W -n \"" + activity + "\"");
-    }
+    private void setAndValidatePkgDriver(String pkgName, CtsAngleCommon.OpenGlDriverChoice driver) throws Exception {
+        CtsAngleCommon.stopPackage(getDevice(), pkgName);
 
-    private void stopPackage(String pkgName) throws Exception {
-        getDevice().executeShellCommand("am force-stop " + pkgName);
-    }
+        setAndValidateAngleDevOptionPkgDriver(pkgName, CtsAngleCommon.sDriverGlobalSettingMap.get(driver));
 
-    private void setAndValidatePkgDriver(String pkgName, OpenGlDriverChoice driver) throws Exception {
-        stopPackage(pkgName);
-
-        setAndValidateAngleDevOptionPkgDriver(pkgName, sDriverGlobalSettingMap.get(driver));
-
-        startActivity(ANGLE_MAIN_ACTIVTY);
+        CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
         CLog.logAndDisplay(LogLevel.INFO, "Validating driver selection (" +
-                driver + ") with method '" + sDriverTestMethodMap.get(driver) + "'");
+                driver + ") with method '" + CtsAngleCommon.sDriverTestMethodMap.get(driver) + "'");
 
         runDeviceTests(
                 pkgName,
-                pkgName + "." + ANGLE_DEV_OPTION_CLASS,
-                sDriverTestMethodMap.get(driver));
+                pkgName + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.sDriverTestMethodMap.get(driver));
     }
 
     @Before
     public void setUp() throws Exception {
-        stopPackage(ANGLE_PKG);
-        stopPackage(ANGLE_DEV_OPTION_PKG);
-        stopPackage(ANGLE_DEV_OPTION_SEC_PKG);
-        getDevice().setSetting("global", SETTINGS_GLOBAL_ALL_USE_ANGLE, "0");
+        CtsAngleCommon.clearSettings(getDevice());
+
+        CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_PKG);
+        CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_PKG);
+        CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        CtsAngleCommon.clearSettings(getDevice());
     }
 
     /**
@@ -177,26 +103,26 @@
      */
     @Test
     public void testEnableAngleForAll() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.DEFAULT));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.DEFAULT));
 
-        getDevice().setSetting("global", SETTINGS_GLOBAL_ALL_USE_ANGLE, "1");
+        getDevice().setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_ALL_USE_ANGLE, "1");
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
-        installPackage(ANGLE_DEV_OPTION_SEC_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_ANGLE_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_ANGLE_METHOD);
         runDeviceTests(
-                ANGLE_DEV_OPTION_SEC_PKG,
-                ANGLE_DEV_OPTION_SEC_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_ANGLE_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_ANGLE_METHOD);
     }
 
     /**
@@ -204,17 +130,17 @@
      */
     @Test
     public void testUseDefaultDriver() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.DEFAULT));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_DEFAULT_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_DEFAULT_METHOD);
     }
 
     /**
@@ -222,17 +148,17 @@
      */
     @Test
     public void testUseAngleDriver() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_ANGLE_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_ANGLE_METHOD);
     }
 
     /**
@@ -240,17 +166,17 @@
      */
     @Test
     public void testUseNativeDriver() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.NATIVE));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_NATIVE_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_NATIVE_METHOD);
     }
 
     /**
@@ -258,23 +184,24 @@
      */
     @Test
     public void testSettingsLengthMismatch() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG + "," + ANGLE_DEV_OPTION_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," +
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
-        installPackage(ANGLE_DEV_OPTION_SEC_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_DEFAULT_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_DEFAULT_METHOD);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_SEC_PKG,
-                ANGLE_DEV_OPTION_SEC_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_DEFAULT_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_DEFAULT_METHOD);
     }
 
     /**
@@ -282,16 +209,16 @@
      */
     @Test
     public void testUseInvalidDriver() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG, "timtim");
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG, "timtim");
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_DEFAULT_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_DEFAULT_METHOD);
     }
 
     /**
@@ -299,17 +226,17 @@
      */
     @Test
     public void testUpdateDriverValues() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
 
-        for (OpenGlDriverChoice firstDriver : OpenGlDriverChoice.values()) {
-            for (OpenGlDriverChoice secondDriver : OpenGlDriverChoice.values()) {
+        for (CtsAngleCommon.OpenGlDriverChoice firstDriver : CtsAngleCommon.OpenGlDriverChoice.values()) {
+            for (CtsAngleCommon.OpenGlDriverChoice secondDriver : CtsAngleCommon.OpenGlDriverChoice.values()) {
                 CLog.logAndDisplay(LogLevel.INFO, "Testing updating Global.Settings from '" +
                         firstDriver + "' to '" + secondDriver + "'");
 
-                setAndValidatePkgDriver(ANGLE_DEV_OPTION_PKG, firstDriver);
-                setAndValidatePkgDriver(ANGLE_DEV_OPTION_PKG, secondDriver);
+                setAndValidatePkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG, firstDriver);
+                setAndValidatePkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG, secondDriver);
             }
         }
     }
@@ -321,24 +248,25 @@
      */
     @Test
     public void testMultipleDevOptionsAngleNative() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG + "," + ANGLE_DEV_OPTION_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," +
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE) + "," +
+                        CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.NATIVE));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
-        installPackage(ANGLE_DEV_OPTION_SEC_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_PKG,
-                ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_ANGLE_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_ANGLE_METHOD);
 
         runDeviceTests(
-                ANGLE_DEV_OPTION_SEC_PKG,
-                ANGLE_DEV_OPTION_SEC_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                ANGLE_DEV_OPTION_NATIVE_METHOD);
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_NATIVE_METHOD);
     }
 
     /**
@@ -346,61 +274,61 @@
      */
     @Test
     public void testMultipleUpdateDriverValues() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
-        installPackage(ANGLE_DEV_OPTION_SEC_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
 
         // Set the first PKG to always use ANGLE
-        setAndValidatePkgDriver(ANGLE_DEV_OPTION_PKG, OpenGlDriverChoice.ANGLE);
+        setAndValidatePkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG, CtsAngleCommon.OpenGlDriverChoice.ANGLE);
 
-        for (OpenGlDriverChoice firstDriver : OpenGlDriverChoice.values()) {
-            for (OpenGlDriverChoice secondDriver : OpenGlDriverChoice.values()) {
+        for (CtsAngleCommon.OpenGlDriverChoice firstDriver : CtsAngleCommon.OpenGlDriverChoice.values()) {
+            for (CtsAngleCommon.OpenGlDriverChoice secondDriver : CtsAngleCommon.OpenGlDriverChoice.values()) {
                 CLog.logAndDisplay(LogLevel.INFO, "Testing updating Global.Settings from '" +
                         firstDriver + "' to '" + secondDriver + "'");
 
                 setAndValidateAngleDevOptionPkgDriver(
-                        ANGLE_DEV_OPTION_PKG + "," + ANGLE_DEV_OPTION_SEC_PKG,
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                                sDriverGlobalSettingMap.get(firstDriver));
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," + CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                        CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE) + "," +
+                                CtsAngleCommon.sDriverGlobalSettingMap.get(firstDriver));
 
-                startActivity(ANGLE_MAIN_ACTIVTY);
+                CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
                 CLog.logAndDisplay(LogLevel.INFO, "Validating driver selection (" +
-                        firstDriver + ") with method '" + sDriverTestMethodMap.get(firstDriver) + "'");
+                        firstDriver + ") with method '" + CtsAngleCommon.sDriverTestMethodMap.get(firstDriver) + "'");
 
                 runDeviceTests(
-                        ANGLE_DEV_OPTION_SEC_PKG,
-                        ANGLE_DEV_OPTION_SEC_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                        sDriverTestMethodMap.get(firstDriver));
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                        CtsAngleCommon.sDriverTestMethodMap.get(firstDriver));
 
                 setAndValidateAngleDevOptionPkgDriver(
-                        ANGLE_DEV_OPTION_PKG + "," + ANGLE_DEV_OPTION_SEC_PKG,
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                                sDriverGlobalSettingMap.get(secondDriver));
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," + CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                        CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE) + "," +
+                                CtsAngleCommon.sDriverGlobalSettingMap.get(secondDriver));
 
-                startActivity(ANGLE_MAIN_ACTIVTY);
+                CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
                 CLog.logAndDisplay(LogLevel.INFO, "Validating driver selection (" +
-                        secondDriver + ") with method '" + sDriverTestMethodMap.get(secondDriver) + "'");
+                        secondDriver + ") with method '" + CtsAngleCommon.sDriverTestMethodMap.get(secondDriver) + "'");
 
                 runDeviceTests(
-                        ANGLE_DEV_OPTION_SEC_PKG,
-                        ANGLE_DEV_OPTION_SEC_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                        sDriverTestMethodMap.get(secondDriver));
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                        CtsAngleCommon.sDriverTestMethodMap.get(secondDriver));
 
                 // Make sure the first PKG's driver value was not modified
-                startActivity(ANGLE_MAIN_ACTIVTY);
+                CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
-                String devOptionPkg = getDevOption(SETTINGS_GLOBAL_DRIVER_PKGS);
-                String devOptionValue = getDevOption(SETTINGS_GLOBAL_DRIVER_VALUES);
+                String devOptionPkg = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS);
+                String devOptionValue = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES);
                 CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
                         devOptionPkg + "', driver value = '" + devOptionValue + "'");
 
                 runDeviceTests(
-                        ANGLE_DEV_OPTION_PKG,
-                        ANGLE_DEV_OPTION_PKG + "." + ANGLE_DEV_OPTION_CLASS,
-                        ANGLE_DEV_OPTION_ANGLE_METHOD);
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                        CtsAngleCommon.ANGLE_DRIVER_TEST_ANGLE_METHOD);
             }
         }
     }
@@ -411,27 +339,27 @@
      */
     @Test
     public void testDefaultNotInSettings() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.DEFAULT));
 
         // Install the package so the setting isn't removed because the package isn't present.
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
 
         // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(ANGLE_MAIN_ACTIVTY);
+        CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
-        String devOptionPkg = getDevOption(SETTINGS_GLOBAL_DRIVER_PKGS);
-        String devOptionValue = getDevOption(SETTINGS_GLOBAL_DRIVER_VALUES);
+        String devOptionPkg = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS);
+        String devOptionValue = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES);
         CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
                 devOptionPkg + "', driver value = '" + devOptionValue + "'");
 
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
                 "", devOptionPkg);
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
                 "", devOptionValue);
     }
 
@@ -440,26 +368,26 @@
      */
     @Test
     public void testUninstalledPkgsNotInSettings() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        uninstallPackage(getDevice(), ANGLE_DEV_OPTION_PKG);
+        uninstallPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_PKG);
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.NATIVE));
 
         // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(ANGLE_MAIN_ACTIVTY);
+        CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
-        String devOptionPkg = getDevOption(SETTINGS_GLOBAL_DRIVER_PKGS);
-        String devOptionValue = getDevOption(SETTINGS_GLOBAL_DRIVER_VALUES);
+        String devOptionPkg = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS);
+        String devOptionValue = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES);
         CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
                 devOptionPkg + "', driver value = '" + devOptionValue + "'");
 
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
                 "", devOptionPkg);
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
                 "", devOptionValue);
     }
 
@@ -472,27 +400,27 @@
      */
     @Test
     public void testMultipleDevOptionsAngleDefault() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG + "," + ANGLE_DEV_OPTION_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," + CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE) + "," +
+                        CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.DEFAULT));
 
-        installPackage(ANGLE_DEV_OPTION_APP, new String[0]);
-        installPackage(ANGLE_DEV_OPTION_SEC_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
 
         // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(ANGLE_MAIN_ACTIVTY);
+        CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
-        String devOption = getDevOption(SETTINGS_GLOBAL_DRIVER_PKGS);
+        String devOption = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS);
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOption + "'",
-                ANGLE_DEV_OPTION_PKG, devOption);
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOption + "'",
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG, devOption);
 
-        devOption = getDevOption(SETTINGS_GLOBAL_DRIVER_VALUES);
+        devOption = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES);
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOption + "'",
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE), devOption);
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOption + "'",
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE), devOption);
     }
 
     /**
@@ -504,27 +432,27 @@
      */
     @Test
     public void testMultipleDevOptionsAngleNativeUninstall() throws Exception {
-        Assume.assumeTrue(isAngleLoadable());
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
 
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DEV_OPTION_PKG + "," + ANGLE_DEV_OPTION_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE));
+        setAndValidateAngleDevOptionPkgDriver(CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," + CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.ANGLE) + "," +
+                        CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.NATIVE));
 
-        installPackage(ANGLE_DEV_OPTION_SEC_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
 
         // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(ANGLE_MAIN_ACTIVTY);
+        CtsAngleCommon.startActivity(getDevice(), CtsAngleCommon.ANGLE_MAIN_ACTIVTY);
 
-        String devOptionPkg = getDevOption(SETTINGS_GLOBAL_DRIVER_PKGS);
-        String devOptionValue = getDevOption(SETTINGS_GLOBAL_DRIVER_VALUES);
+        String devOptionPkg = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS);
+        String devOptionValue = getDevOption(CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES);
         CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
                 devOptionPkg + "', driver value = '" + devOptionValue + "'");
 
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
-                ANGLE_DEV_OPTION_SEC_PKG, devOptionPkg);
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG, devOptionPkg);
         Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE), devOptionValue);
+                "Invalid developer option: " + CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
+                CtsAngleCommon.sDriverGlobalSettingMap.get(CtsAngleCommon.OpenGlDriverChoice.NATIVE), devOptionValue);
     }
 }
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
new file mode 100644
index 0000000..f4f495a
--- /dev/null
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 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 android.angle.cts;
+
+import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+/**
+ * Tests ANGLE Rules File Opt-In/Out functionality.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CtsAngleRulesFileTest extends BaseHostJUnit4Test {
+
+    private final String TAG = this.getClass().getSimpleName();
+
+    File mRulesFile;
+
+    // Rules Files
+    private static final String RULES_FILE_EMPTY = "emptyRules.json";
+    private static final String RULES_FILE_ENABLE_ANGLE = "enableAngleRules.json";
+
+    private void pushRulesFile(String hostFilename) throws Exception {
+        byte[] rulesFileBytes =
+                ByteStreams.toByteArray(getClass().getResourceAsStream("/" + hostFilename));
+
+        Assert.assertTrue("Loaded empty rules file", rulesFileBytes.length > 0); // sanity check
+        mRulesFile = File.createTempFile("rulesFile", "tempRules.json");
+        Files.write(rulesFileBytes, mRulesFile);
+
+        Assert.assertTrue(getDevice().pushFile(mRulesFile, CtsAngleCommon.DEVICE_TEMP_RULES_FILE_PATH));
+
+        CtsAngleCommon.setProperty(getDevice(), CtsAngleCommon.PROPERTY_TEMP_RULES_FILE,
+                CtsAngleCommon.DEVICE_TEMP_RULES_FILE_PATH);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        CtsAngleCommon.clearSettings(getDevice());
+
+        // Enable checking the rules file
+        CtsAngleCommon.setProperty(getDevice(), CtsAngleCommon.PROPERTY_ENABLE_RULES_FILE, "1");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        CtsAngleCommon.clearSettings(getDevice());
+
+        FileUtil.deleteFile(mRulesFile);
+    }
+
+    /**
+     * Test ANGLE is not loaded when an empty rules file is used.
+     */
+    @Test
+    public void testEmptyRulesFile() throws Exception {
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
+
+        pushRulesFile(RULES_FILE_EMPTY);
+
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+
+        runDeviceTests(
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_NATIVE_METHOD);
+    }
+
+    /**
+     * Test ANGLE is loaded for only the PKG the rules file specifies.
+     */
+    @Test
+    public void testEnableAngleRulesFile() throws Exception {
+        Assume.assumeTrue(CtsAngleCommon.isAngleLoadable(getDevice()));
+
+        pushRulesFile(RULES_FILE_ENABLE_ANGLE);
+
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_APP, new String[0]);
+        installPackage(CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_APP, new String[0]);
+
+        runDeviceTests(
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_ANGLE_METHOD);
+
+        runDeviceTests(
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
+                CtsAngleCommon.ANGLE_DRIVER_TEST_NATIVE_METHOD);
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/compilation/AndroidTest.xml b/hostsidetests/compilation/AndroidTest.xml
index fe17ac8..9383a79 100644
--- a/hostsidetests/compilation/AndroidTest.xml
+++ b/hostsidetests/compilation/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Config for CTS Compilation Test">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="art" />
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsCompilationTestCases.jar" />
         <option name="runtime-hint" value="9m45s" />