diff --git a/Android.mk b/Android.mk
index 5b3b76a..1437ab1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,7 +14,7 @@
 
 LOCAL_PATH := $(call my-dir)
 COMPATIBILITY.tradefed_tests_dir := \
-  $(COMPATIBILITY.tradefed_tests_dir) $(LOCAL_PATH)/res/config $(LOCAL_PATH)/tests/res/config $(LOCAL_PATH)/prod-tests/res/config
+  $(COMPATIBILITY.tradefed_tests_dir) $(LOCAL_PATH)/res/config $(LOCAL_PATH)/tests/res/config
 
 include $(CLEAR_VARS)
 
@@ -36,7 +36,7 @@
 # Note that this is incompatible with `make dist`.  If you want to make
 # the distribution, you must run `tapas` with the individual target names.
 .PHONY: tradefed-core
-tradefed-core: tradefed atest_tradefed tf-prod-tests tf-prod-metatests tradefed-contrib script_help
+tradefed-core: tradefed atest_tradefed tradefed-contrib tf-contrib-tests script_help
 
 .PHONY: tradefed-all
 tradefed-all: tradefed-core tradefed-tests tradefed_win verify loganalysis-tests
@@ -56,7 +56,7 @@
 ########################################################
 # Zip up the built files and dist it as tradefed.zip
 
-tradefed_dist_host_jars := tradefed tradefed-tests tf-prod-tests tf-prod-metatests emmalib jack-jacoco-reporter loganalysis loganalysis-tests tf-remote-client tradefed-contrib tools-common-prebuilt
+tradefed_dist_host_jars := tradefed tradefed-tests emmalib jack-jacoco-reporter loganalysis loganalysis-tests tf-remote-client tradefed-contrib tf-contrib-tests tools-common-prebuilt
 tradefed_dist_host_jar_files := $(foreach m, $(tradefed_dist_host_jars), $(HOST_OUT_JAVA_LIBRARIES)/$(m).jar)
 
 tradefed_dist_host_exes := tradefed.sh tradefed_win.bat script_help.sh verify.sh run_tf_cmd.sh atest_tradefed.sh
diff --git a/atest/Android.bp b/atest/Android.bp
index 3891566..a53d3f9 100644
--- a/atest/Android.bp
+++ b/atest/Android.bp
@@ -66,3 +66,28 @@
         "constants_default.py"
     ],
 }
+
+// Move asuite_default and asuite_metrics to //tools/asuite when atest is
+// running as a prebuilt.
+python_defaults {
+    name: "asuite_default",
+    pkg_path: "asuite",
+    version: {
+        py2: {
+            enabled: true,
+            embedded_launcher: false,
+        },
+        py3: {
+            enabled: true,
+            embedded_launcher: false,
+        },
+    },
+}
+
+python_library_host {
+    name: "asuite_metrics",
+    defaults: ["asuite_default"],
+    srcs: [
+        "asuite_metrics.py",
+    ],
+}
diff --git a/atest/asuite_metrics.py b/atest/asuite_metrics.py
new file mode 100644
index 0000000..78bfff9
--- /dev/null
+++ b/atest/asuite_metrics.py
@@ -0,0 +1,101 @@
+# Copyright 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.
+
+"""Asuite simple Metrics Functions"""
+
+import json
+import logging
+import os
+import urllib2
+import uuid
+
+_JSON_HEADERS = {'Content-Type': 'application/json'}
+_METRICS_RESPONSE = 'done'
+_DUMMY_UUID = '00000000-0000-4000-8000-000000000000'
+_METRICS_TIMEOUT = 2 #seconds
+_META_FILE = os.path.join(os.path.expanduser('~'),
+                          '.config', 'asuite', '.metadata')
+_ANDROID_BUILD_TOP = 'ANDROID_BUILD_TOP'
+
+
+#pylint: disable=broad-except
+def log_event(metrics_url, dummy_key_fallback=True, **kwargs):
+    """Base log event function for asuite backend.
+
+    Args:
+        metrics_url: String, URL to report metrics to.
+        dummy_key_fallback: Boolean, If True and unable to get grouping key,
+                            use a dummy key otherwise return out. Sometimes we
+                            don't want to return metrics for users we are
+                            unable to identify. Default True.
+        kwargs: Dict, additional fields we want to return metrics for.
+    """
+    try:
+        try:
+            key = str(_get_grouping_key())
+        except Exception:
+            if not dummy_key_fallback:
+                return
+            key = _DUMMY_UUID
+        data = {'grouping_key': key,
+                'run_id': str(uuid.uuid4())}
+        if kwargs:
+            data.update(kwargs)
+        data = json.dumps(data)
+        request = urllib2.Request(metrics_url, data=data,
+                                  headers=_JSON_HEADERS)
+        response = urllib2.urlopen(request, timeout=_METRICS_TIMEOUT)
+        content = response.read()
+        if content != _METRICS_RESPONSE:
+            raise Exception('Unexpected metrics response: %s' % content)
+    except Exception as e:
+        logging.debug('Exception sending metrics: %s', e)
+
+
+def _get_grouping_key():
+    """Get grouping key. Returns UUID.uuid4."""
+    if os.path.isfile(_META_FILE):
+        with open(_META_FILE) as f:
+            try:
+                return uuid.UUID(f.read(), version=4)
+            except ValueError:
+                logging.debug('malformed group_key in file, rewriting')
+    # TODO: Delete get_old_key() on 11/17/2018
+    key = _get_old_key() or uuid.uuid4()
+    dir_path = os.path.dirname(_META_FILE)
+    if os.path.isfile(dir_path):
+        os.remove(dir_path)
+    try:
+        os.makedirs(dir_path)
+    except OSError as e:
+        if not os.path.isdir(dir_path):
+            raise e
+    with open(_META_FILE, 'w+') as f:
+        f.write(str(key))
+    return key
+
+
+def _get_old_key():
+    """Get key from old meta data file if exists, else return None."""
+    old_file = os.path.join(os.environ[_ANDROID_BUILD_TOP],
+                            'tools/tradefederation/core/atest', '.metadata')
+    key = None
+    if os.path.isfile(old_file):
+        with open(old_file) as f:
+            try:
+                key = uuid.UUID(f.read(), version=4)
+            except ValueError:
+                logging.debug('error reading old key')
+        os.remove(old_file)
+    return key
diff --git a/atest/atest_metrics.py b/atest/atest_metrics.py
index 818fa9c..d2ac3ad 100755
--- a/atest/atest_metrics.py
+++ b/atest/atest_metrics.py
@@ -16,67 +16,11 @@
 
 """Simple Metrics Functions"""
 
-import json
-import logging
-import os
-import urllib2
-import uuid
-
 import constants
+import asuite_metrics
 
-JSON_HEADERS = {'Content-Type': 'application/json'}
 
 #pylint: disable=broad-except
 def log_start_event():
     """Log that atest started."""
-    try:
-        try:
-            key = str(get_grouping_key())
-        except Exception:
-            key = constants.DUMMY_UUID
-        data = {'grouping_key': key,
-                'run_id': str(uuid.uuid4())}
-        data = json.dumps(data)
-        request = urllib2.Request(constants.METRICS_URL, data=data, headers=JSON_HEADERS)
-        response = urllib2.urlopen(request, timeout=constants.METRICS_TIMEOUT)
-        content = response.read()
-        if content != constants.METRICS_RESPONSE:
-            raise Exception('Unexpected metrics response: %s' % content)
-    except Exception as e:
-        logging.debug('Exception sending metrics: %s', e)
-
-def get_grouping_key():
-    """Get grouping key. Returns UUID."""
-    if os.path.isfile(constants.META_FILE):
-        with open(constants.META_FILE) as f:
-            try:
-                return uuid.UUID(f.read(), version=4)
-            except ValueError:
-                logging.debug('malformed group_key in file, rewriting')
-    # TODO: Delete get_old_key() on 11/17/2018
-    key = get_old_key() or uuid.uuid4()
-    dir_path = os.path.dirname(constants.META_FILE)
-    if os.path.isfile(dir_path):
-        os.remove(dir_path)
-    try:
-        os.makedirs(dir_path)
-    except OSError as e:
-        if not os.path.isdir(dir_path):
-            raise e
-    with open(constants.META_FILE, 'w+') as f:
-        f.write(str(key))
-    return key
-
-def get_old_key():
-    """Get key from old meta data file if exists, else return None."""
-    old_file = os.path.join(os.environ[constants.ANDROID_BUILD_TOP],
-                            'tools/tradefederation/core/atest', '.metadata')
-    key = None
-    if os.path.isfile(old_file):
-        with open(old_file) as f:
-            try:
-                key = uuid.UUID(f.read(), version=4)
-            except ValueError:
-                logging.debug('error reading old key')
-        os.remove(old_file)
-    return key
+    asuite_metrics.log_event(constants.METRICS_URL)
diff --git a/atest/constants_default.py b/atest/constants_default.py
index ee1eb85..ce0dc15 100644
--- a/atest/constants_default.py
+++ b/atest/constants_default.py
@@ -16,7 +16,6 @@
 Various globals used by atest.
 """
 
-import os
 
 MODE = 'DEFAULT'
 
@@ -112,12 +111,7 @@
 BOTH_TEST = 'both'
 
 # Metrics
-META_FILE = os.path.join(os.path.expanduser('~'),
-                         '.config', 'asuite', '.metadata')
 METRICS_URL = 'http://asuite-218222.appspot.com/atest/metrics'
-METRICS_TIMEOUT = 2 #seconds
-METRICS_RESPONSE = 'done'
-DUMMY_UUID = '00000000-0000-4000-8000-000000000000'
 
 # VTS plans
 VTS_STAGING_PLAN = 'vts-staging-default'
diff --git a/prod-tests/.classpath b/prod-tests/.classpath
deleted file mode 100644
index d3c1487..0000000
--- a/prod-tests/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="junit"/>
-	<classpathentry kind="src" path="res"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/tradefederation"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/loganalysis"/>
-	<classpathentry kind="var" path="TRADEFED_ROOT/out/host/common/obj/JAVA_LIBRARIES/host-libprotobuf-java-full_intermediates/classes.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/prod-tests/.project b/prod-tests/.project
deleted file mode 100644
index ce64e84..0000000
--- a/prod-tests/.project
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>tf-prod-tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-	<linkedResources>
-		<link>
-			<name>junit</name>
-			<type>2</type>
-			<locationURI>TRADEFED_ROOT/external/junit/src/main/java</locationURI>
-		</link>
-	</linkedResources>
-</projectDescription>
diff --git a/prod-tests/Android.mk b/prod-tests/Android.mk
deleted file mode 100644
index 00abe3b..0000000
--- a/prod-tests/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2011 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)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_JAVACFLAGS += -g -Xlint
--include tools/tradefederation/core/error_prone_rules.mk
-
-LOCAL_MODULE := tf-prod-tests
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed loganalysis
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# makefile rules to copy jars to HOST_OUT/tradefed
-# so tradefed.sh can automatically add to classpath
-DEST_JAR := $(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar
-$(DEST_JAR): $(LOCAL_BUILT_MODULE)
-	$(copy-file-to-new-target)
-
-# this dependency ensure the above rule will be executed if jar is built
-$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/prod-tests/MANIFEST.mf b/prod-tests/MANIFEST.mf
deleted file mode 100644
index 19d17b0..0000000
--- a/prod-tests/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Implementation-Version: default
diff --git a/prod-tests/README b/prod-tests/README
deleted file mode 100644
index 4da837c..0000000
--- a/prod-tests/README
+++ /dev/null
@@ -1,5 +0,0 @@
-This directory contains test harness code that make use of the tradefed
-framework to run tests on Android platform.
-
-They are distinct from code in the 'tests' directory, which are unit tests for
-the tradefed framework itself.
diff --git a/prod-tests/res/config/app/launch.xml b/prod-tests/res/config/app/launch.xml
deleted file mode 100644
index 684aad6..0000000
--- a/prod-tests/res/config/app/launch.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Runs app install and launch test with given apk">
-    <option name="enable-root" value="false" />
-    <build_provider class="com.android.tradefed.build.LocalAppBuildProvider" />
-    <!--  to install AppLaunch.apk -->
-    <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup" />
-    <test class="com.android.app.tests.AppLaunchTest" />
-    <logger class="com.android.tradefed.log.FileLogger"/>
-</configuration>
diff --git a/prod-tests/res/config/build/image-stats.xml b/prod-tests/res/config/build/image-stats.xml
deleted file mode 100644
index 2cdaa93..0000000
--- a/prod-tests/res/config/build/image-stats.xml
+++ /dev/null
@@ -1,19 +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.
--->
-<configuration description="Runs download manager host-based tests">
-    <option name="null-device" value="true" />
-    <test class="com.android.build.tests.ImageStats" />
-</configuration>
diff --git a/prod-tests/res/config/framework/download-mgr.xml b/prod-tests/res/config/framework/download-mgr.xml
deleted file mode 100644
index 5df3b6e..0000000
--- a/prod-tests/res/config/framework/download-mgr.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs download manager host-based tests">
-    <test class="com.android.framework.tests.DownloadManagerHostTests" />
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level-display" value="debug" />
-    </logger>
-</configuration>
diff --git a/prod-tests/res/config/framework/package-mgr-ota.xml b/prod-tests/res/config/framework/package-mgr-ota.xml
deleted file mode 100644
index b8b3b3d..0000000
--- a/prod-tests/res/config/framework/package-mgr-ota.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
- <!-- Copyright 2012 Google Inc. All Rights Reserved -->
-<configuration description="Runs package manager ota host-based tests">
-
-    <test class="com.android.framework.tests.PackageManagerOTATests">
-    </test>
-    <logger class="com.android.tradefed.log.FileLogger" />
-    <result_reporter class="com.android.tradefed.result.XmlResultReporter" />
-</configuration>
diff --git a/prod-tests/res/config/framework/package-mgr-stress.xml b/prod-tests/res/config/framework/package-mgr-stress.xml
deleted file mode 100644
index 92de5df..0000000
--- a/prod-tests/res/config/framework/package-mgr-stress.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs package manager host-based stress tests">
-    <test class="com.android.framework.tests.PackageManagerStressHostTests" />
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level-display" value="debug" />
-    </logger>
-</configuration>
diff --git a/prod-tests/res/config/framework/package-mgr.xml b/prod-tests/res/config/framework/package-mgr.xml
deleted file mode 100644
index 9fd19f6..0000000
--- a/prod-tests/res/config/framework/package-mgr.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs download manager host-based tests">
-    <test class="com.android.framework.tests.PackageManagerHostTests" />
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level-display" value="debug" />
-    </logger>
-</configuration>
diff --git a/prod-tests/res/config/framework/preloaded-classes.xml b/prod-tests/res/config/framework/preloaded-classes.xml
deleted file mode 100644
index 38332d3..0000000
--- a/prod-tests/res/config/framework/preloaded-classes.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-<configuration description="Runs tests to report preloaded classes information">
-    <!-- Download preload tool -->
-    <option name="device-launch-control:additional-files-filter" value=".*preload2.jar" />
-    <!-- Install test apps -->
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup" />
-    <!-- Preload test configuration -->
-    <option name="test-tag" value="preloaded-classes" />
-    <test class="com.android.framework.tests.PreloadedClassesTest" />
-</configuration>
diff --git a/prod-tests/res/config/google/example/hello-world-multi.xml b/prod-tests/res/config/google/example/hello-world-multi.xml
deleted file mode 100644
index a9af98e..0000000
--- a/prod-tests/res/config/google/example/hello-world-multi.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<configuration description="Multi device Hello World Example">
-    <!-- Some option for the whole configuration-->
-    <option name="test-tag" value="multi-device-hello-world" />
-
-    <!-- Each device configuration -->
-    <device name="device1">
-        <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
-            <option name="disable" value="true" />
-        </target_preparer>
-    </device>
-
-    <!-- A device tag can be completely empty if it doesn't require any setup -->
-    <device name="device2" />
-
-    <!-- preparer that affects all the devices, called after the individual target_preparer -->
-    <!-- Not required: If you have none, you can remove all the 'multi_target_preparer' -->
-    <multi_target_preparer class="com.android.tradefed.targetprep.multi.StubMultiTargetPreparer" />
-    <multi_target_preparer class="com.android.tradefed.targetprep.multi.HelloWorldMultiTargetPreparer" />
-
-    <!-- logger in verbose for the example -->
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level" value="VERBOSE" />
-        <option name="log-level-display" value="VERBOSE" />
-    </logger>
-
-    <!-- tests that will be ran -->
-    <test class="com.android.tradefed.HelloWorldMultiDevices" />
-
-    <!-- result reporters -->
-    <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
-
-</configuration>
-
diff --git a/prod-tests/res/config/longevity/metrics-collectors.xml b/prod-tests/res/config/longevity/metrics-collectors.xml
deleted file mode 100644
index 3c328b7..0000000
--- a/prod-tests/res/config/longevity/metrics-collectors.xml
+++ /dev/null
@@ -1,48 +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.
--->
-<!-- Metric collectors for longevity runs. -->
-<configuration description="Metric collectors for longevity runs.">
-  <metrics_collector class="com.android.tradefed.device.metric.ScheduleMultipleDeviceMetricCollector">
-    <!-- Collect fragmentation info every 2 minutes. -->
-    <option name="metric-collection-intervals" key="fragmentation" value="120000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.BuddyInfoMetricCollector" />
-
-    <!-- Collect compact memory dump every 3 minutes. -->
-    <option name="metric-collection-intervals" key="compact-meminfo" value="180000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.MemInfoMetricCollector" />
-
-    <!-- Collect graphicsstats dump every 4 minutes. -->
-    <option name="metric-collection-intervals" key="jank" value="240000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.GraphicsStatsMetricCollector" />
-
-    <!-- Collect bugreport every 1 hour. -->
-    <option name="metric-collection-intervals" key="bugreportz" value="3600000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.BugreportzMetricCollector" />
-
-    <!-- Collect ion audio and system heap info every 15 minutes. -->
-    <option name="metric-collection-intervals" key="ion" value="900000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.IonHeapInfoMetricCollector" />
-
-    <!-- Collect pagetype info every 10 minutes. -->
-    <option name="metric-collection-intervals" key="pagetypeinfo" value="600000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.PagetypeInfoMetricCollector" />
-
-    <!-- Collect trace every 20 minutes. -->
-    <option name="metric-collection-intervals" key="trace" value="1200000" />
-    <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.TraceMetricCollector" />
-    <!-- Add more if there are requests. -->
-  </metrics_collector>
-</configuration>
diff --git a/prod-tests/res/config/longevity/preparers.xml b/prod-tests/res/config/longevity/preparers.xml
deleted file mode 100644
index 5168a62..0000000
--- a/prod-tests/res/config/longevity/preparers.xml
+++ /dev/null
@@ -1,21 +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.
--->
-<!-- Preparer configuration for longevity runs. -->
-<configuration description="Preparer configuration for longevity runs.">
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="PhoneLongevityTests.apk" />
-    </target_preparer>
-</configuration>
diff --git a/prod-tests/res/config/longevity/test.xml b/prod-tests/res/config/longevity/test.xml
deleted file mode 100644
index 754ea35..0000000
--- a/prod-tests/res/config/longevity/test.xml
+++ /dev/null
@@ -1,34 +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.
--->
-<!-- Test configuration for longevity runs. -->
-<configuration description="Test configuration for longevity runs.">
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <!-- Test run setup and configuration. -->
-        <option name="package" value="android.longevity.platform" />
-        <option name="class" value="android.longevity.platform.PhoneSuite" />
-        <option name="instrumentation-arg" key="iterations" value="100" />
-        <option name="instrumentation-arg" key="shuffle" value="true" />
-
-        <!-- Timeout configurations. Test: 5m. Suite: 10h. Battery: 5%. -->
-        <option name="instrumentation-arg" key="timeout_msec" value="300000" />
-        <option name="instrumentation-arg" key="suite-timeout_msec" value="36000000" />
-        <option name="instrumentation-arg" key="min-battery" value="0.05" />
-
-        <!-- Override or negate instrumentation defaults. -->
-        <option name="shell-timeout" value="0" />
-        <option name="test-timeout" value="0" />
-      </test>
-</configuration>
diff --git a/prod-tests/res/config/monkey/app-metrics.xml b/prod-tests/res/config/monkey/app-metrics.xml
deleted file mode 100644
index 76b8cee..0000000
--- a/prod-tests/res/config/monkey/app-metrics.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Run monkey using existing pre-prepared device with defaults appropriate for a single application being targeted. Use --package to specify application.">
-    <option name = "enable-root" value="false" />
-    <option name = "reboot-device" value="false" />
-    <test class="com.android.monkey.MonkeyMetricsTest">
-        <option name="category" value="android.intent.category.CAR_DOCK" />
-        <option name="category" value="android.intent.category.INFO" />
-        <option name="category" value="android.intent.category.LAUNCHER" />
-        <option name="category" value="android.intent.category.MONKEY" />
-        <option name="category" value="android.intent.category.SAMPLE_CODE" />
-        <option name="target-count" value="10000" />
-        <option name="throttle" value="100" />
-        <option name="idle-time" value="0" />
-        <!-- 30 minute timeout for the monkey -->
-        <option name="monkey-timeout" value="30" />
-        <option name="retry-on-failure" value="true" />
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/prod-tests/res/config/monkey/application.xml b/prod-tests/res/config/monkey/application.xml
deleted file mode 100644
index 711538d..0000000
--- a/prod-tests/res/config/monkey/application.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Run monkey using existing pre-prepared device with defaults appropriate for a single application being targeted. Use --package to specify application.">
-    <option name = "enable-root" value="false" />
-    <option name = "reboot-device" value="false" />
-    <test class="com.android.monkey.MonkeyBase">
-        <option name="category" value="android.intent.category.CAR_DOCK" />
-        <option name="category" value="android.intent.category.INFO" />
-        <option name="category" value="android.intent.category.LAUNCHER" />
-        <option name="category" value="android.intent.category.MONKEY" />
-        <option name="category" value="android.intent.category.SAMPLE_CODE" />
-        <option name="target-count" value="10000" />
-        <option name="throttle" value="100" />
-        <option name="idle-time" value="30" />
-        <!-- 30 minute timeout for the monkey -->
-        <option name="monkey-timeout" value="30" />
-        <option name="retry-on-failure" value="true" />
-    </test>
-    <logger class="com.android.tradefed.log.FileLogger" />
-</configuration>
\ No newline at end of file
diff --git a/prod-tests/res/config/monkey/system.xml b/prod-tests/res/config/monkey/system.xml
deleted file mode 100644
index fb5463b..0000000
--- a/prod-tests/res/config/monkey/system.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Run monkey using existing pre-prepared device with defaults appropriate for the entire system being targeted. Use --package to restrict run to specified applications.">
-    <option name = "enable-root" value="false" />
-    <option name = "reboot-device" value="false" />
-    <test class="com.android.monkey.MonkeyBase">
-        <option name="category" value="android.intent.category.LAUNCHER" />
-        <option name="target-count" value="125000" />
-        <option name="idle-time" value="0" />
-    </test>
-    <logger class="com.android.tradefed.log.FileLogger" />
-</configuration>
diff --git a/prod-tests/res/config/performance/app-transitions.xml b/prod-tests/res/config/performance/app-transitions.xml
deleted file mode 100644
index 9816f1e..0000000
--- a/prod-tests/res/config/performance/app-transitions.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-<configuration description="Testing the transition delay performance" >
-
-    <option name="test-tag" value="AppTransitionTests" />
-
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup" >
-        <option name="test-file-name" value="AppTransitionTests.apk" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer" />
-
-    <test class="com.android.performance.tests.AppTransitionTests" />
-
-</configuration>
diff --git a/prod-tests/res/config/performance/hermetic-launch.xml b/prod-tests/res/config/performance/hermetic-launch.xml
deleted file mode 100644
index dc74149..0000000
--- a/prod-tests/res/config/performance/hermetic-launch.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<configuration description="Testing the app launch performance" >
-
-    <option
-        name="test-tag"
-        value="HermeticLaunchTest" />
-
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup" >
-        <option
-            name="test-file-name"
-            value="PerformanceLaunch.apk" />
-        <option
-            name="test-file-name"
-            value="PerformanceAppTest.apk" />
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup" />
-
-    <target_preparer class="com.android.tradefed.targetprep.CpuThrottlingWaiter" />
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer" />
-
-    <test class="com.android.performance.tests.HermeticLaunchTest" >
-        <option
-            name="package"
-            value="com.android.performanceapp.tests" />
-        <option
-            name="target-package"
-            value="com.android.performanceLaunch" />
-        <option
-            name="launch-count"
-            value="15" />
-        <option
-            name="save-atrace"
-            value="true" />
-    </test>
-
-</configuration>
diff --git a/prod-tests/res/config/performance/hermetic-memory.xml b/prod-tests/res/config/performance/hermetic-memory.xml
deleted file mode 100644
index d6dbfab..0000000
--- a/prod-tests/res/config/performance/hermetic-memory.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2016 Google Inc. All Rights Reserved -->
-<configuration description="Testing system memory and app memory usage after launching app">
-    <!--apk-path option should point to the location of the test apk path-->
-    <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup" >
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.TimeWaster" >
-          <option name="delay" value="60000" />
-    </target_preparer>
-    <test class="com.android.performance.tests.HermeticMemoryTest"/>
-</configuration>
diff --git a/prod-tests/res/config/stability/reboot-stress.xml b/prod-tests/res/config/stability/reboot-stress.xml
deleted file mode 100644
index a858174..0000000
--- a/prod-tests/res/config/stability/reboot-stress.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Runs reboot stress test">
-    <test class="com.android.stability.tests.RebootStressTest" />
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level-display" value="debug" />
-    </logger>
-    <result_reporter class="com.android.tradefed.result.XmlResultReporter" />
-</configuration>
diff --git a/prod-tests/res/config/template/android-junit.xml b/prod-tests/res/config/template/android-junit.xml
deleted file mode 100644
index 0065e94..0000000
--- a/prod-tests/res/config/template/android-junit.xml
+++ /dev/null
@@ -1,22 +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.
--->
-<!-- A template for running non-custom, Android JUnit-style tests. -->
-<configuration description="Android JUnit Google Tradefed XML">
-    <!-- Required: specify the package to run. -->
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-    </test>
-</configuration>
diff --git a/prod-tests/res/config/template/local.xml b/prod-tests/res/config/template/local.xml
deleted file mode 100644
index 6520e72..0000000
--- a/prod-tests/res/config/template/local.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<!-- Common base configuration for local runs. -->
-<configuration description="Common base configuration for local runs">
-    <option name="bugreport-on-invocation-ended" value="true" />
-    <build_provider class="com.android.tradefed.build.BootstrapBuildProvider" />
-    <!-- Provides a mechanism for overwriting the preloaded classes that is disabled by default. -->
-    <target_preparer class="com.android.tradefed.targetprep.PreloadedClassesPreparer">
-        <option name="disable" value="true" />
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
-        <option name="screen-always-on" value="on" />
-        <option name="screen-adaptive-brightness" value="off" />
-        <option name="screen-brightness" value="30" />
-    </target_preparer>
-
-    <template-include name="preparers" default="empty" />
-
-    <template-include name="test" />
-
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level" value="VERBOSE" />
-        <option name="log-level-display" value="VERBOSE" />
-    </logger>
-    <log_saver class="com.android.tradefed.result.FileSystemLogSaver" />
-    <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
-    <result_reporter class="com.android.tradefed.result.InvocationFailureEmailResultReporter" />
-    <result_reporter class="com.android.tradefed.result.DeviceUnavailEmailResultReporter" />
-    <template-include name="reporters" default="empty" />
-</configuration>
diff --git a/prod-tests/res/config/template/local_min.xml b/prod-tests/res/config/template/local_min.xml
deleted file mode 100644
index 2707eb2..0000000
--- a/prod-tests/res/config/template/local_min.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<!-- Common base configuration for local runs with minimum overhead. -->
-<configuration description="Common base configuration for local runs with minimum overhead">
-    <build_provider class="com.android.tradefed.build.BootstrapBuildProvider" />
-    <target_preparer class="com.android.tradefed.targetprep.PreloadedClassesPreparer">
-        <option name="disable" value="true" />
-    </target_preparer>
-
-    <template-include name="preparers" default="empty" />
-
-    <template-include name="test" default="empty" />
-
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level" value="VERBOSE" />
-        <option name="log-level-display" value="VERBOSE" />
-    </logger>
-    <log_saver class="com.android.tradefed.result.FileSystemLogSaver" />
-    <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
-    <result_reporter class="com.android.tradefed.result.suite.SuiteResultReporter" />
-    <result_reporter class="com.android.tradefed.result.MetricsXMLResultReporter"/>
-    <template-include name="reporters" default="empty" />
-    <template-include name="metrics_collector" default="empty" />
-</configuration>
diff --git a/prod-tests/res/config/uiautomator/uiautomator-demo.xml b/prod-tests/res/config/uiautomator/uiautomator-demo.xml
deleted file mode 100644
index 4e0d610..0000000
--- a/prod-tests/res/config/uiautomator/uiautomator-demo.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs the UI Automator Demo Test">
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
-    <!--
-        This test requires deploying the UI Automator demo test onto device.
-        The demo test is located under Android source tree:
-          frameworks/testing/uiautomator/samples/SkeletonTest
-        After the uiautomator.skeletontest.jar is built, insert "__push"
-        parameter to this TradFed test to deploy:
-          __push /path/to/uiautomator.skeletontest.jar->/data/local/tmp/uiautomator.skeletontest.jar
-    -->
-    <test class="com.android.tradefed.testtype.UiAutomatorTest">
-        <option name="jar-path" value="uiautomator.skeletontest.jar" />
-        <option name="class" value="com.android.uiautomator.samples.skeleton.DemoTestCase" />
-    </test>
-    <logger class="com.android.tradefed.log.FileLogger">
-        <option name="log-level-display" value="debug" />
-    </logger>
-</configuration>
diff --git a/prod-tests/src/com/android/app/tests/AppLaunchTest.java b/prod-tests/src/com/android/app/tests/AppLaunchTest.java
deleted file mode 100644
index 051979c..0000000
--- a/prod-tests/src/com/android/app/tests/AppLaunchTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.app.tests;
-
-import com.android.tradefed.build.IAppBuildInfo;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.VersionedFile;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.InstrumentationTest;
-import com.android.tradefed.util.AaptParser;
-import com.android.tradefed.util.FileUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.util.HashMap;
-
-/**
- * A harness that installs and launches an app on device and verifies it doesn't crash.
- * <p/>
- * Requires a {@link IAppBuildInfo} and 'aapt' being present in path. Assume the AppLaunch
- * test app is already present on device.
- */
-public class AppLaunchTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
-
-    private static final String RUN_NAME = "AppLaunch";
-    private ITestDevice mDevice;
-    private IBuildInfo mBuild;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = buildInfo;
-    }
-
-    /**
-     * Installs all apks listed in {@link IAppBuildInfo}, then attempts to run the package in the
-     * first apk.  Note that this does <emph>not</emph> attempt to uninstall the apks, and requires
-     * external cleanup.
-     * <p />
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        long startTime = System.currentTimeMillis();
-        listener.testRunStarted(RUN_NAME, 2);
-        try {
-            Assert.assertTrue(mBuild instanceof IAppBuildInfo);
-            IAppBuildInfo appBuild = (IAppBuildInfo)mBuild;
-            Assert.assertFalse(appBuild.getAppPackageFiles().isEmpty());
-
-            // We assume that the first apk is the one to be executed, and any others are to be
-            // installed and uninstalled.
-            File appApkFile = appBuild.getAppPackageFiles().get(0).getFile();
-            AaptParser p = AaptParser.parse(appApkFile);
-            Assert.assertNotNull(p);
-            String packageName = p.getPackageName();
-            Assert.assertNotNull(String.format("Failed to parse package name from %s",
-                    appApkFile.getAbsolutePath()), packageName);
-
-            for (final VersionedFile apkVersionedFile : appBuild.getAppPackageFiles()) {
-                final File apkFile = apkVersionedFile.getFile();
-                performInstallTest(apkFile, listener);
-            }
-
-            performLaunchTest(packageName, listener);
-        } catch (AssertionError e) {
-            listener.testRunFailed(e.toString());
-        } finally {
-            listener.testRunEnded(
-                    System.currentTimeMillis() - startTime, new HashMap<String, Metric>());
-        }
-
-    }
-
-    private void performInstallTest(File apkFile, ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        TestDescription installTest =
-                new TestDescription(
-                        "com.android.app.tests.InstallTest",
-                        FileUtil.getBaseName(apkFile.getName()));
-        listener.testStarted(installTest);
-        String result = getDevice().installPackage(apkFile, true);
-        if (result != null) {
-            listener.testFailed(installTest, result);
-        }
-        listener.testEnded(installTest, new HashMap<String, Metric>());
-    }
-
-    private void performLaunchTest(String packageName, ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        InstrumentationTest i = new InstrumentationTest();
-        i.setRunName(RUN_NAME);
-        i.setPackageName("com.android.applaunchtest");
-        i.setRunnerName("com.android.applaunchtest.AppLaunchRunner");
-        i.setDevice(getDevice());
-        i.addInstrumentationArg("packageName", packageName);
-        i.run(listener);
-        try (InputStreamSource s = getDevice().getScreenshot()) {
-            listener.testLog("screenshot", LogDataType.PNG, s);
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/build/tests/ImageStats.java b/prod-tests/src/com/android/build/tests/ImageStats.java
deleted file mode 100644
index 9d9c6ef..0000000
--- a/prod-tests/src/com/android/build/tests/ImageStats.java
+++ /dev/null
@@ -1,286 +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.
- */
-
-package com.android.build.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A device-less test that parses standard Android build image stats file and performs aggregation
- */
-@OptionClass(alias = "image-stats")
-public class ImageStats implements IRemoteTest, IBuildReceiver {
-
-    // built-in aggregation labels
-    private static final String LABEL_TOTAL = "total";
-    private static final String LABEL_CATEGORIZED = "categorized";
-    private static final String LABEL_UNCATEGORIZED = "uncategorized";
-
-    private static final String FILE_SIZES = "fileSizes";
-
-    @Option(name = "size-stats-file", description = "Specify the name of the file containing image "
-            + "stats; when \"file-from-build-info\" is set to true, the name refers to a file that "
-            + "can be found in build info (note that build provider must be properly configured to "
-            + "download it), otherwise it refers to a local file, typically used for debugging "
-            + "purposes", mandatory = true)
-    private String mStatsFileName = null;
-
-    @Option(name = "file-from-build-info", description = "If the \"size-stats-file\" references a "
-            + "file from build info, or local; use local file for debugging purposes.")
-    private boolean mFileFromBuildInfo = false;
-
-    @Option(name = "aggregation-pattern", description = "A key value pair consists of a regex as "
-            + "key and a string label as value. The regex is used to scan and group file size "
-            + "entries together for aggregation; that is, all files with names matching the "
-            + "pattern are grouped together for summing; this also means that a file could be "
-            + "counted multiple times; note that the regex must be a full match, not substring. "
-            + "The string label is used for identifying the summed group of file sizes when "
-            + "reporting; the regex may contain unnamed capturing groups, and values may contain "
-            + "numerical \"back references\" as place holders to be replaced with content of "
-            + "corresponding capturing group, example: ^.+\\.(.+)$ -> group-by-extension-\\1; back "
-            + "references are 1-indexed and there maybe up to 9 capturing groups; no strict checks "
-            + "are performed to ensure that capturing groups and place holders are 1:1 mapping. "
-            + "There are 3 built-in aggregations: total, categorized and uncategorized.")
-    private Map<String, String> mAggregationPattern = new HashMap<>();
-
-    @Option(name = "min-report-size", description = "Minimum size in bytes that an aggregated "
-            + "category needs to reach before being included in reported metrics. 0 for no limit. "
-            + "Note that built-in categories are always reported.")
-    private long mMinReportSize = 0;
-
-    private IBuildInfo mBuildInfo;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuildInfo = buildInfo;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        File statsFile;
-        if (mFileFromBuildInfo) {
-            statsFile = mBuildInfo.getFile(mStatsFileName);
-        } else {
-            statsFile = new File(mStatsFileName);
-        }
-        long start = System.currentTimeMillis();
-        Map<String, String> fileSizes = null;
-        // fixed run name, 1 test to run
-        listener.testRunStarted("image-stats", 1);
-        if (statsFile == null || !statsFile.exists()) {
-            throw new RuntimeException(
-                    "Invalid image stats file (<null>) specified or it does not exist.");
-        } else {
-            TestDescription td = new TestDescription(ImageStats.class.getName(), FILE_SIZES);
-            listener.testStarted(td);
-            try (InputStream in = new FileInputStream(statsFile)) {
-                fileSizes = performAggregation(parseFileSizes(in),
-                        processAggregationPatterns(mAggregationPattern));
-            } catch (IOException ioe) {
-                String message = String.format("Failed to parse image stats file: %s",
-                        statsFile.getAbsolutePath());
-                CLog.e(message);
-                CLog.e(ioe);
-                listener.testFailed(td, ioe.toString());
-                listener.testEnded(td, new HashMap<String, Metric>());
-                listener.testRunFailed(message);
-                listener.testRunEnded(
-                        System.currentTimeMillis() - start, new HashMap<String, Metric>());
-                throw new RuntimeException(message, ioe);
-            }
-            String logOutput = String.format("File sizes: %s", fileSizes.toString());
-            if (mFileFromBuildInfo) {
-                CLog.v(logOutput);
-            } else {
-                // assume local debug, print outloud
-                CLog.logAndDisplay(Log.LogLevel.VERBOSE, logOutput);
-            }
-            listener.testEnded(td, TfMetricProtoUtil.upgradeConvert(fileSizes));
-        }
-        listener.testRunEnded(System.currentTimeMillis() - start, new HashMap<String, Metric>());
-    }
-
-    /**
-     * Processes text files like 'installed-files.txt' (as built by standard Android build rules for
-     * device targets) into a map of file path to file sizes
-     * @param in an unread {@link InputStream} for the content of the file sizes; the stream will be
-     *           fully read after executing the method
-     * @return
-     */
-    protected Map<String, Long> parseFileSizes(InputStream in) throws IOException {
-        Map<String, Long> ret = new HashMap<>();
-        try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
-            String line;
-            while ((line = br.readLine()) != null) {
-                // trim both ends of the raw line and make a split by whitespaces
-                // e.g. trying to match a line like this:
-                //     96992106  /system/app/Chrome/Chrome.apk
-                String[] fields = line.trim().split("\\s+");
-                if (fields.length != 2) {
-                    CLog.w("Unable to split line to file size and name: %s", line);
-                    continue;
-                }
-                long size = 0;
-                try {
-                    size = Long.parseLong(fields[0]);
-                } catch (NumberFormatException nfe) {
-                    CLog.w("Failed to parse file size from field '%s', ignored", fields[0]);
-                    continue;
-                }
-                ret.put(fields[1], size);
-            }
-        }
-        return ret;
-    }
-
-    /** Compiles the supplied aggregation regex's */
-    protected Map<Pattern, String> processAggregationPatterns(Map<String, String> rawPatterns) {
-        Map<Pattern, String> ret = new HashMap<>();
-        for (Map.Entry<String, String> e : rawPatterns.entrySet()) {
-            Pattern p = Pattern.compile(e.getKey());
-            ret.put(p, e.getValue());
-        }
-        return ret;
-    }
-
-    /**
-     * Converts a matched file entry to the final aggregation label name.
-     * <p>
-     * The main thing being converted here is that capturing groups in the regex (used to match the
-     * filenames) are extracted, and used to replace the corresponding placeholders in raw label.
-     * For each 1-indexed capturing group, the captured content is used to replace the "\x"
-     * placeholders in raw label, with x being a number between 1-9, corresponding to the index of
-     * the capturing group.
-     *
-     * @param matcher  the {@link Matcher} representing the matched result from the regex and input
-     * @param rawLabel the corresponding aggregation label
-     * @return
-     */
-    protected String getAggregationLabel(Matcher matcher, String rawLabel) {
-        if (matcher.groupCount() == 0) {
-            // no capturing groups, return label as is
-            return rawLabel;
-        }
-        if (matcher.groupCount() > 9) {
-            // since we are doing replacement of back references to capturing groups manually,
-            // artificially limiting this to avoid overly complex code to handle \1 vs \10
-            // in other words, "9 capturing groups ought to be enough for anybody"
-            throw new RuntimeException("too many capturing groups");
-        }
-        String label = rawLabel;
-        for (int i = 1; i <= matcher.groupCount(); i++) {
-            String marker = String.format("\\%d", i); // e.g. "\1"
-            if (label.indexOf(marker) == -1) {
-                CLog.w("Capturing groups were defined in regex '%s', but corresponding "
-                        + "back-reference placeholder '%s' not found in label '%s'",
-                        matcher.pattern(), marker, rawLabel);
-                continue;
-            }
-            label = label.replace(marker, matcher.group(i));
-        }
-        // ensure that the resulting label is not the same as the fixed "uncategorized" label
-        if (LABEL_UNCATEGORIZED.equals(label)) {
-            throw new IllegalArgumentException(String.format("Use of aggregation label '%s' "
-                    + "conflicts with built-in default.", LABEL_UNCATEGORIZED));
-        }
-        return label;
-    }
-
-    /**
-     * Performs aggregation by adding raw file size entries together based on the regex's the full
-     * path names are matched. Note that this means a file entry could get aggregated multiple
-     * times. The returned map will also include a fixed entry called "uncategorized" that adds the
-     * sizes of all file entries that were never matched together.
-     * @param stats the map of raw stats: full path name -> file size
-     * @param patterns the map of aggregation patterns: a regex that could match file names -> the
-     *                 name of the aggregated result category (e.g. all apks)
-     * @return
-     */
-    protected Map<String, String> performAggregation(Map<String, Long> stats,
-            Map<Pattern, String> patterns) {
-        Set<String> uncategorizedFiles = new HashSet<>(stats.keySet());
-        Map<String, Long> result = new HashMap<>();
-        long total = 0;
-
-        for (Map.Entry<String, Long> stat : stats.entrySet()) {
-            // aggregate for total first
-            total += stat.getValue();
-            for (Map.Entry<Pattern, String> pattern : patterns.entrySet()) {
-                Matcher m = pattern.getKey().matcher(stat.getKey());
-                if (m.matches()) {
-                    // the file entry being looked at matches one of the preconfigured rules
-                    String label = getAggregationLabel(m, pattern.getValue());
-                    Long size = result.get(label);
-                    if (size == null) {
-                        size = 0L;
-                    }
-                    size += stat.getValue();
-                    result.put(label, size);
-                    // keep track of files that we've already aggregated at least once
-                    if (uncategorizedFiles.contains(stat.getKey())) {
-                        uncategorizedFiles.remove(stat.getKey());
-                    }
-                }
-            }
-        }
-        // final pass for uncategorized files
-        long uncategorized = 0;
-        for (String file : uncategorizedFiles) {
-            uncategorized += stats.get(file);
-        }
-        Map<String, String> ret = new HashMap<>();
-        for (Map.Entry<String, Long> e : result.entrySet()) {
-            if (mMinReportSize > 0 && e.getValue() < mMinReportSize) {
-                // has a min report size requirement and current category does not meet it
-                CLog.v("Skipped reporting for %s (value %d): it's below threshold %d",
-                        e.getKey(), e.getValue(), mMinReportSize);
-                continue;
-            }
-            ret.put(e.getKey(), Long.toString(e.getValue()));
-        }
-        ret.put(LABEL_UNCATEGORIZED, Long.toString(uncategorized));
-        ret.put(LABEL_TOTAL, Long.toString(total));
-        ret.put(LABEL_CATEGORIZED, Long.toString(total - uncategorized));
-        return ret;
-    }
-}
diff --git a/prod-tests/src/com/android/continuous/SmokeTest.java b/prod-tests/src/com/android/continuous/SmokeTest.java
deleted file mode 100644
index 93f221f..0000000
--- a/prod-tests/src/com/android/continuous/SmokeTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.continuous;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.DeviceFileReporter;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.NameMangleListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.InstrumentationTest;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * A test that runs the smoke tests
- * <p />
- * Simply {@link InstrumentationTest} with extra reporting.  Should be re-integrated with
- * {@link InstrumentationTest} after it's clear that it works as expected.
- */
-@OptionClass(alias = "smoke")
-public class SmokeTest extends InstrumentationTest {
-    @Option(name = "capture-file-pattern", description = "File glob of on-device files to log " +
-            "if found.  Takes two arguments: the glob, and the file type " +
-            "(text/xml/zip/gzip/png/unknown).  May be repeated.", importance = Importance.IF_UNSET)
-    private Map<String, LogDataType> mUploadFilePatterns = new LinkedHashMap<String, LogDataType>();
-
-    @Option(name = "bugreport-device-wait-time", description = "How many seconds to wait for the " +
-            "device to become available so we can capture a bugreport.  Useful in case the smoke " +
-            "tests fail due to a device reboot.")
-    private int mDeviceWaitTime = 60;
-
-    /**
-     * Simple constructor that disables an incompatible runmode from the superclass
-     */
-    public SmokeTest() {
-        super();
-        // Re-run mode doesn't work properly with Smoke
-        setRerunMode(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // trimListener should be the first thing to receive any results.  It will pass the results
-        // through to the bugListener, which will forward them (after collecting any necessary
-        // bugreports) to the real Listener(s).
-        final BugreportCollector bugListener = new BugreportCollector(listener, getDevice());
-        bugListener.setDeviceWaitTime(mDeviceWaitTime);
-        bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
-        final ITestInvocationListener trimListener = new TrimListener(bugListener);
-
-        super.run(trimListener);
-
-        final DeviceFileReporter dfr = new DeviceFileReporter(getDevice(), trimListener);
-        dfr.addPatterns(mUploadFilePatterns);
-        dfr.run();
-    }
-
-    /**
-     * A class to adjust the test identifiers from something like this:
-     * com.android.smoketest.SmokeTestRunner$3#com.android.voicedialer.VoiceDialerActivity
-     * To this:
-     * SmokeFAST#com.android.voicedialer.VoiceDialerActivity
-     */
-    static class TrimListener extends NameMangleListener {
-        public TrimListener(ITestInvocationListener listener) {
-            super(listener);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        protected TestDescription mangleTestId(TestDescription test) {
-            final String method = test.getTestName();
-            final String klass = test.getClassName().replaceFirst(
-                    "com.android.smoketest.SmokeTestRunner(?:\\$\\d+)?", "SmokeFAST");
-            return new TestDescription(klass, method);
-        }
-    }
-}
-
diff --git a/prod-tests/src/com/android/continuous/SmokeTestFailureReporter.java b/prod-tests/src/com/android/continuous/SmokeTestFailureReporter.java
deleted file mode 100644
index dfc66228..0000000
--- a/prod-tests/src/com/android/continuous/SmokeTestFailureReporter.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.continuous;
-
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestFailureEmailResultReporter;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
-import com.android.tradefed.util.Email;
-import com.android.tradefed.util.IEmail;
-
-import java.util.Map;
-
-/**
- * A customized failure reporter that sends emails in a specific format
- */
-@OptionClass(alias = "smoke-failure-email")
-public class SmokeTestFailureReporter extends TestFailureEmailResultReporter {
-    /**
-     * Default constructor
-     */
-    public SmokeTestFailureReporter() {
-        this(new Email());
-    }
-
-    /**
-     * Create a {@link SmokeTestFailureReporter} with a custom {@link IEmail} instance to use.
-     *
-     * <p>Exposed for unit testing.
-     *
-     * @param mailer the {@link IEmail} instance to use.
-     */
-    protected SmokeTestFailureReporter(IEmail mailer) {
-        super(mailer);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected String generateEmailSubject() {
-        final IInvocationContext context = getInvocationContext();
-        StringBuilder sb = new StringBuilder();
-        sb.append(context.getTestTag());
-        sb.append(" SmokeFAST failed on: ");
-        for (IBuildInfo build : context.getBuildInfos()) {
-            sb.append(build.toString());
-        }
-        return sb.toString();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected String generateEmailBody() {
-        StringBuilder sb = new StringBuilder();
-
-        for (TestRunResult run : getMergedTestRunResults()) {
-            if (run.hasFailedTests()) {
-                final Map<TestDescription, TestResult> tests = run.getTestResults();
-                for (Map.Entry<TestDescription, TestResult> test : tests.entrySet()) {
-                    final TestDescription id = test.getKey();
-                    final TestResult result = test.getValue();
-
-                    if (result.getStatus() == TestStatus.PASSED) continue;
-
-                    sb.append(String.format("%s#%s %s\n",
-                            id.getClassName(), id.getTestName(),
-                            describeStatus(result.getStatus())));
-
-                    final String trace = result.getStackTrace();
-                    if (trace != null) {
-                        sb.append("Stack trace:\n");
-                        sb.append(trace);
-                        sb.append("\n");
-                    }
-                }
-            }
-        }
-
-        sb.append("\n");
-        sb.append(super.generateEmailBody());
-        return sb.toString();
-    }
-
-    private String describeStatus(TestStatus status) {
-        switch (status) {
-            case FAILURE:
-                return "failed";
-            case PASSED:
-                return "passed";
-            case INCOMPLETE:
-                return "did not complete";
-            case ASSUMPTION_FAILURE:
-                return "assumption failed";
-            case IGNORED:
-                return "ignored";
-        }
-        return "had an unknown result";
-    }
-}
diff --git a/prod-tests/src/com/android/fastboot/tests/FastbootTest.java b/prod-tests/src/com/android/fastboot/tests/FastbootTest.java
deleted file mode 100644
index 8159314..0000000
--- a/prod-tests/src/com/android/fastboot/tests/FastbootTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.fastboot.tests;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionSetter;
-import com.android.tradefed.device.DeviceDisconnectedException;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IManagedTestDevice;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.ITestDevice.RecoveryMode;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.DeviceFlashPreparer;
-import com.android.tradefed.targetprep.IDeviceFlasher.UserDataFlashOption;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Flashes the device as part of the test, report device post-flash status as test results.
- * TODO: Add more fastboot test validation step.
- */
-public class FastbootTest implements IRemoteTest, IDeviceTest, IBuildReceiver {
-
-    private static final String FASTBOOT_TEST = FastbootTest.class.getName();
-    /** the desired recentness of battery level **/
-    private static final long BATTERY_FRESHNESS_MS = 30 * 1000;
-    private static final long INVALID_TIME_DURATION = -1;
-    private static final String INITIAL_BOOT_TIME = "initial-boot";
-    private static final String ONLINE_TIME = "online";
-
-    @Option(name = "device-boot-time", description = "Max time in ms to wait for"
-            + " device to boot.", isTimeVal = true)
-    private long mDeviceBootTimeMs = 5 * 60 * 1000;
-
-    @Option(name = "userdata-flash", description = "Specify handling of userdata partition.")
-    private UserDataFlashOption mUserDataFlashOption = UserDataFlashOption.WIPE;
-
-    @Option(name = "concurrent-flasher-limit", description = "The maximum number of concurrent"
-            + " flashers (may be useful to avoid memory constraints)")
-    private Integer mConcurrentFlasherLimit = null;
-
-    @Option(name = "skip-battery-check", description = "If true, the battery reading test will"
-            + " be skipped.")
-    private boolean mSkipBatteryCheck = false;
-
-    @Option(name = "flasher-class", description = "The Flasher class (implementing "
-            + "DeviceFlashPreparer) to be used for the fastboot test", mandatory = true)
-    private String mFlasherClass;
-
-    private IBuildInfo mBuildInfo;
-    private ITestDevice mDevice;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuildInfo = buildInfo;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        long start = System.currentTimeMillis();
-        listener.testRunStarted(FASTBOOT_TEST, 1);
-        String originalFastbootpath = ((IManagedTestDevice)mDevice).getFastbootPath();
-        try {
-            testFastboot(listener);
-        } finally {
-            // reset fastboot path
-            ((IManagedTestDevice)mDevice).setFastbootPath(originalFastbootpath);
-            listener.testRunEnded(
-                    System.currentTimeMillis() - start, new HashMap<String, Metric>());
-        }
-    }
-
-    /**
-     * Flash the device and calculate the time to bring the device online and first boot.
-     * @param listener
-     * @throws DeviceNotAvailableException
-     */
-    private void testFastboot(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        HashMap<String, Metric> result = new HashMap<>();
-        TestDescription firstBootTestId =
-                new TestDescription(
-                        String.format("%s.%s", FASTBOOT_TEST, FASTBOOT_TEST), FASTBOOT_TEST);
-        listener.testStarted(firstBootTestId);
-        DeviceFlashPreparer flasher = loadFlashPreparerClass();
-        long bootStart = INVALID_TIME_DURATION;
-        long onlineTime = INVALID_TIME_DURATION;
-        long bootTime = INVALID_TIME_DURATION;
-        try {
-            if (flasher == null) {
-                throw new RuntimeException(String.format("Could not find flasher %s",
-                        mFlasherClass));
-            }
-            try {
-                OptionSetter setter = new OptionSetter(flasher);
-                // duping and passing parameters down to flasher
-                setter.setOptionValue("device-boot-time", Long.toString(mDeviceBootTimeMs));
-                setter.setOptionValue("userdata-flash", mUserDataFlashOption.toString());
-                if (mConcurrentFlasherLimit != null) {
-                    setter.setOptionValue("concurrent-flasher-limit",
-                            mConcurrentFlasherLimit.toString());
-                }
-                // always to skip because the test needs to detect device online
-                // and available state individually
-                setter.setOptionValue("skip-post-flashing-setup", "true");
-                setter.setOptionValue("force-system-flash", "true");
-            } catch (ConfigurationException ce) {
-                // this really shouldn't happen, but if it does, it'll indicate a setup problem
-                // so this should be exposed, even at the expense of categorizing the build as
-                // having a critical failure
-                throw new RuntimeException("failed to set options for flasher", ce);
-            }
-
-            File fastboot = getFastbootFile(mBuildInfo);
-            if (fastboot == null) {
-                listener.testFailed(firstBootTestId,
-                        "Couldn't find the fastboot binary in build info.");
-                return;
-            }
-            // Set the fastboot path for device
-            ((IManagedTestDevice)mDevice).setFastbootPath(fastboot.getAbsolutePath());
-
-            // flash it!
-            CLog.v("Flashing device %s", mDevice.getSerialNumber());
-            try {
-                flasher.setUp(mDevice, mBuildInfo);
-                // we are skipping post boot setup so this is the start of boot process
-                bootStart = System.currentTimeMillis();
-            } catch (TargetSetupError | BuildError e) {
-                // setUp() may throw DeviceNotAvailableException, TargetSetupError and BuildError.
-                // DNAE is allowed to get thrown here so that a tool failure is triggered and build
-                // maybe retried; the other 2x types are also rethrown as RuntimeException's for
-                // the same purpose. In general, these exceptions reflect flashing or infra related
-                // flakiness, so retrying is a reasonable mitigation.
-                throw new RuntimeException("Exception during device flashing", e);
-            }
-            // check if device is online after flash, i.e. if adb is broken
-            CLog.v("Waiting for device %s online", mDevice.getSerialNumber());
-            mDevice.setRecoveryMode(RecoveryMode.ONLINE);
-            try {
-                mDevice.waitForDeviceOnline();
-                onlineTime = System.currentTimeMillis() - bootStart;
-            } catch (DeviceNotAvailableException dnae) {
-                CLog.e("Device not online after flashing");
-                CLog.e(dnae);
-                listener.testRunFailed("Device not online after flashing");
-                throw new DeviceDisconnectedException("Device not online after flashing",
-                        mDevice.getSerialNumber());
-            }
-            // check if device can be fully booted, i.e. if application framework won't boot
-            CLog.v("Waiting for device %s boot complete", mDevice.getSerialNumber());
-            mDevice.setRecoveryMode(RecoveryMode.AVAILABLE);
-            try {
-                mDevice.waitForDeviceAvailable(mDeviceBootTimeMs);
-                bootTime = System.currentTimeMillis() - bootStart;
-            } catch (DeviceNotAvailableException dnae) {
-                CLog.e("Device %s not available after flashing", mDevice.getSerialNumber());
-                CLog.e(dnae);
-                // only report as test failure, not test run failure because we were able to run the
-                // test until the end, despite the failure verdict, and the device is returned to
-                // the pool in a useable state
-                listener.testFailed(firstBootTestId, "Device not available after flashing");
-                return;
-            }
-            CLog.v("Device %s boot complete", mDevice.getSerialNumber());
-            if (mSkipBatteryCheck) {
-                // If we skip the battery Check, we can return directly after boot complete.
-                return;
-            }
-            // We check if battery level are readable as non root to ensure that device is usable.
-            mDevice.disableAdbRoot();
-            try {
-                Future<Integer> batteryFuture = mDevice.getIDevice()
-                        .getBattery(BATTERY_FRESHNESS_MS, TimeUnit.MILLISECONDS);
-                // get cached value or wait up to 500ms for battery level query
-                Integer level = batteryFuture.get(500, TimeUnit.MILLISECONDS);
-                CLog.d("Battery level value reading is: '%s'", level);
-                if (level == null) {
-                    listener.testFailed(firstBootTestId, "Reading of battery level is wrong.");
-                    return;
-                }
-            } catch (InterruptedException | ExecutionException |
-                    java.util.concurrent.TimeoutException e) {
-                CLog.e("Failed to query battery level for %s", mDevice.getSerialNumber());
-                CLog.e(e);
-                listener.testFailed(firstBootTestId, "Failed to query battery level.");
-                return;
-            } finally {
-                mDevice.enableAdbRoot();
-            }
-        } finally {
-            CLog.d("Device online time: %dms, initial boot time: %dms", onlineTime, bootTime);
-            if (onlineTime != INVALID_TIME_DURATION) {
-                result.put(
-                        ONLINE_TIME, TfMetricProtoUtil.stringToMetric(Long.toString(onlineTime)));
-            }
-            if (bootTime != INVALID_TIME_DURATION) {
-                result.put(
-                        INITIAL_BOOT_TIME,
-                        TfMetricProtoUtil.stringToMetric(Long.toString(bootTime)));
-            }
-            listener.testEnded(firstBootTestId, result);
-        }
-    }
-
-    /**
-     * Attempt to load the class implementing {@link DeviceFlashPreparer} based on the option
-     * flasher-class, allows anybody to tests fastboot using their own implementation of it.
-     */
-    private DeviceFlashPreparer loadFlashPreparerClass() {
-        try {
-            Class<?> flasherClass = Class.forName(mFlasherClass);
-            Object flasherObject = flasherClass.newInstance();
-            if (flasherObject instanceof DeviceFlashPreparer) {
-                return (DeviceFlashPreparer)flasherObject;
-            } else {
-                CLog.e("Loaded class '%s' is not an instance of DeviceFlashPreparer.",
-                        flasherObject);
-                return null;
-            }
-        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
-            CLog.e(e);
-            return null;
-        }
-    }
-
-    /**
-     * Helper to find the fastboot file as part of the buildinfo file list.
-     */
-    private File getFastbootFile(IBuildInfo buildInfo) {
-        File fastboot = buildInfo.getFile("fastboot");
-        if (fastboot == null) {
-            return null;
-        }
-        FileUtil.chmodGroupRWX(fastboot);
-        return fastboot;
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTest.java b/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTest.java
deleted file mode 100644
index 3b999a1..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTest.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.framework.tests.BandwidthStats.CompareResult;
-import com.android.framework.tests.BandwidthStats.ComparisonRecord;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil.IRunnableResult;
-import com.android.tradefed.util.MultiMap;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.net.HttpHelper;
-import com.android.tradefed.util.net.IHttpHelper;
-import com.android.tradefed.util.net.IHttpHelper.DataSizeException;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Test that instruments a bandwidth test, gathers bandwidth metrics, and posts
- * the results to the Release Dashboard.
- */
-public class BandwidthMicroBenchMarkTest implements IDeviceTest, IRemoteTest {
-
-    ITestDevice mTestDevice = null;
-
-    @Option(name = "test-package-name", description = "Android test package name.")
-    private String mTestPackageName;
-
-    @Option(name = "test-class-name", description = "Test class name.")
-    private String mTestClassName;
-
-    @Option(name = "test-method-name", description = "Test method name.")
-    private String mTestMethodName;
-
-    @Option(name = "test-label",
-            description = "Test label to identify the test run.")
-    private String mTestLabel;
-
-    @Option(name = "bandwidth-test-server",
-            description = "Test label to use when posting to dashboard.",
-            importance=Option.Importance.IF_UNSET)
-    private String mTestServer;
-
-    @Option(name = "ssid",
-            description = "The ssid to use for the wifi connection.")
-    private String mSsid;
-
-    @Option(name = "initial-server-poll-interval-ms",
-            description = "The initial poll interval in msecs for querying the test server.")
-    private int mInitialPollIntervalMs = 1 * 1000;
-
-    @Option(name = "server-total-timeout-ms",
-            description = "The total timeout in msecs for querying the test server.")
-    private int mTotalTimeoutMs = 40 * 60 * 1000;
-
-    @Option(name = "server-query-op-timeout-ms",
-            description = "The timeout in msecs for a single operation to query the test server.")
-    private int mQueryOpTimeoutMs = 2 * 60 * 1000;
-
-    @Option(name="difference-threshold",
-            description="The maximum allowed difference between network stats in percent")
-    private int mDifferenceThreshold = 5;
-
-    @Option(name="server-difference-threshold",
-            description="The maximum difference between the stats reported by the " +
-            "server and the device in percent")
-    private int mServerDifferenceThreshold = 6;
-
-    @Option(name = "compact-ru-key",
-            description = "Name of the reporting unit for pass/fail results")
-    private String mCompactRuKey;
-
-    @Option(name = "iface", description="Network interface on the device to use for stats",
-            importance = Option.Importance.ALWAYS)
-    private String mIface;
-
-    private static final String TEST_RUNNER = "com.android.bandwidthtest.BandwidthTestRunner";
-    private static final String TEST_SERVER_QUERY = "query";
-    private static final String DEVICE_ID_LABEL = "device_id";
-    private static final String TIMESTAMP_LABEL = "timestamp";
-
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-
-        Assert.assertNotNull("Need a test server, specify it using --bandwidth-test-server",
-                mTestServer);
-
-        // Run test
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName,
-                TEST_RUNNER, mTestDevice.getIDevice());
-        runner.setMethodName(mTestClassName, mTestMethodName);
-        if (mSsid != null) {
-            runner.addInstrumentationArg("ssid", mSsid);
-        }
-        runner.addInstrumentationArg("server", mTestServer);
-
-        CollectingTestListener collectingListener = new CollectingTestListener();
-        Assert.assertTrue(
-                mTestDevice.runInstrumentationTests(runner, collectingListener, listener));
-
-        // Collect bandwidth metrics from the instrumentation test out.
-        Map<String, String> bandwidthTestMetrics = new HashMap<String, String>();
-        Collection<TestResult> testResults =
-                collectingListener.getCurrentRunResults().getTestResults().values();
-        if (testResults != null && testResults.iterator().hasNext()) {
-            Map<String, String> testMetrics = testResults.iterator().next().getMetrics();
-            if (testMetrics != null) {
-                bandwidthTestMetrics.putAll(testMetrics);
-            }
-        }
-
-        // Fetch the data from the test server.
-        String deviceId = bandwidthTestMetrics.get(DEVICE_ID_LABEL);
-        String timestamp = bandwidthTestMetrics.get(TIMESTAMP_LABEL);
-        Assert.assertNotNull("Failed to fetch deviceId from server", deviceId);
-        Assert.assertNotNull("Failed to fetch timestamp from server", timestamp);
-        Map<String, String> serverData = fetchDataFromTestServer(deviceId, timestamp);
-
-        // Calculate additional network sanity stats - pre-framework logic network stats
-        BandwidthUtils bw = new BandwidthUtils(mTestDevice, mIface);
-        reportPassFail(listener, mCompactRuKey, bw, serverData, bandwidthTestMetrics);
-
-        saveFile("/proc/net/dev", "proc_net_dev", listener);
-        saveFile("/proc/net/xt_qtaguid/stats", "qtaguid_stats", listener);
-
-    }
-
-    private void saveFile(String remoteFilename, String spongeName,
-            ITestInvocationListener listener) throws DeviceNotAvailableException {
-        File f = mTestDevice.pullFile(remoteFilename);
-        if (f == null) {
-            CLog.w("Failed to pull %s", remoteFilename);
-            return;
-        }
-
-        saveFile(spongeName, listener, f);
-    }
-
-    private void saveFile(String spongeName, ITestInvocationListener listener, File file) {
-        try (InputStreamSource stream = new FileInputStreamSource(file)) {
-            listener.testLog(spongeName, LogDataType.TEXT, stream);
-        }
-    }
-
-    /**
-     * Fetch the bandwidth test data recorded on the test server.
-     *
-     * @param deviceId
-     * @param timestamp
-     * @return a map of the data that was recorded by the test server.
-     */
-    private Map<String, String> fetchDataFromTestServer(String deviceId, String timestamp) {
-        IHttpHelper httphelper = new HttpHelper();
-        MultiMap<String,String> params = new MultiMap<String,String> ();
-        params.put("device_id", deviceId);
-        params.put("timestamp", timestamp);
-        String queryUrl = mTestServer;
-        if (!queryUrl.endsWith("/")) {
-            queryUrl += "/";
-        }
-        queryUrl += TEST_SERVER_QUERY;
-        QueryRunnable runnable = new QueryRunnable(httphelper, queryUrl, params);
-        if (RunUtil.getDefault().runEscalatingTimedRetry(mQueryOpTimeoutMs, mInitialPollIntervalMs,
-                mQueryOpTimeoutMs, mTotalTimeoutMs, runnable)) {
-            return runnable.getServerResponse();
-        } else {
-            CLog.w("Failed to query test server", runnable.getException());
-        }
-        return null;
-    }
-
-    private static class QueryRunnable implements IRunnableResult {
-        private final IHttpHelper mHttpHelper;
-        private final String mBaseUrl;
-        private final MultiMap<String,String> mParams;
-        private Map<String, String> mServerResponse = null;
-        private Exception mException = null;
-
-        public QueryRunnable(IHttpHelper helper, String testServerUrl,
-                MultiMap<String,String> params) {
-            mHttpHelper = helper;
-            mBaseUrl = testServerUrl;
-            mParams = params;
-        }
-
-        /**
-         * Perform a single bandwidth test server query, storing the response or
-         * the associated exception in case of error.
-         */
-        @Override
-        public boolean run() {
-            try {
-                String serverResponse = mHttpHelper.doGet(mHttpHelper.buildUrl(mBaseUrl, mParams));
-                mServerResponse = parseServerResponse(serverResponse);
-                return true;
-            } catch (IOException e) {
-                CLog.i("IOException %s when contacting test server", e.getMessage());
-                mException = e;
-            } catch (DataSizeException e) {
-                CLog.i("Unexpected oversized response when contacting test server");
-                mException = e;
-            }
-            return false;
-        }
-
-        /**
-         * Returns exception.
-         *
-         * @return the last {@link Exception} that occurred when performing
-         *         run().
-         */
-        public Exception getException() {
-            return mException;
-        }
-
-        /**
-         * Returns the server response.
-         *
-         * @return a map of the server response.
-         */
-        public Map<String, String> getServerResponse() {
-            return mServerResponse;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void cancel() {
-            // ignore
-        }
-    }
-
-    /**
-     * Helper to parse test server's response into a map
-     * <p>
-     * Exposed for unit testing.
-     *
-     * @param serverResponse {@link String} for the test server http request
-     * @return a map representation of the server response
-     */
-    public static Map<String, String> parseServerResponse(String serverResponse) {
-        // No such test run was recorded.
-        if (serverResponse == null || serverResponse.trim().length() == 0) {
-            return null;
-        }
-        final String[] responseLines = serverResponse.split("\n");
-        Map<String, String> results = new HashMap<String, String>();
-        for (String responseLine : responseLines) {
-            final String[] responsePairs = responseLine.split(" ");
-            for (String responsePair : responsePairs) {
-                final String[] pair = responsePair.split(":", 2);
-                if (pair.length >= 2) {
-                    results.put(pair[0], pair[1]);
-                } else {
-                    CLog.w("Invalid server response: %s", responsePair);
-                }
-            }
-        }
-        return results;
-    }
-
-    /**
-     * Fetch the last stats from event log and calculate the differences.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    private boolean evaluateEventLog(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // issue a force update of stats
-        String res = mTestDevice.executeShellCommand("dumpsys netstats poll");
-        if (!res.contains("Forced poll")) {
-            CLog.w("Failed to force a poll on the device.");
-        }
-        // fetch events log
-        String log = mTestDevice.executeShellCommand("logcat -d -b events");
-        if (log != null) {
-            return evaluateStats("netstats_mobile_sample", log, listener);
-        }
-        return false;
-    }
-
-    /**
-     * Parse a log output for a given key and calculate the network stats.
-     *
-     * @param key {@link String} to search for in the log
-     * @param log obtained from adb logcat -b events
-     * @param listener the {@link ITestInvocationListener} where to report results.
-     */
-    private boolean evaluateStats(String key, String log, ITestInvocationListener listener) {
-        File filteredEventLog = null;
-        BufferedWriter out = null;
-        boolean passed = true;
-
-        try {
-            filteredEventLog = File.createTempFile(String.format("%s_event_log", key), ".txt");
-            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filteredEventLog)));
-            String[] parts = log.split("\n");
-            for (int i = parts.length - 1; i > 0; i--) {
-                String str = parts[i];
-                if (str.contains(key)) {
-                    out.write(str);
-                    passed = passed && evaluateEventLogLine(str);
-                }
-            }
-            out.flush();
-            saveFile(key + "_event_log", listener, filteredEventLog);
-            return passed;
-        } catch (FileNotFoundException e) {
-            CLog.w("Could not create file to save event log: %s", e.getMessage());
-            return false;
-        } catch (IOException e) {
-            CLog.w("Could not save event log file: %s", e.getMessage());
-        } finally {
-            StreamUtil.close(out);
-            FileUtil.deleteFile(filteredEventLog);
-        }
-        return false;
-    }
-
-    private boolean evaluateEventLogLine(String line) {
-        int start = line.lastIndexOf("[");
-        int end = line.lastIndexOf("]");
-        String subStr = line.substring(start + 1, end);
-        String[] statsStrArray = subStr.split(",");
-        if (statsStrArray.length != 13) {
-            CLog.e("Failed to parse for \"%s\" in log.", line);
-            return false;
-        }
-        long xtRb = Long.parseLong(statsStrArray[4].trim());
-        long xtTb = Long.parseLong(statsStrArray[5].trim());
-        long xtRp = Long.parseLong(statsStrArray[6].trim());
-        long xtTp = Long.parseLong(statsStrArray[7].trim());
-        long uidRb = Long.parseLong(statsStrArray[8].trim());
-        long uidTb = Long.parseLong(statsStrArray[9].trim());
-        long uidRp = Long.parseLong(statsStrArray[10].trim());
-        long uidTp = Long.parseLong(statsStrArray[11].trim());
-
-        BandwidthStats xtStats = new BandwidthStats(xtRb, xtRp, xtTb, xtTp);
-        BandwidthStats uidStats = new BandwidthStats(uidRb, uidRp, uidTb, uidTp);
-        boolean result = true;
-        CompareResult compareResult = xtStats.compareAll(uidStats, mDifferenceThreshold);
-        result &= compareResult.getResult();
-        if (!compareResult.getResult()) {
-            CLog.i("Failure comparing netstats_mobile_sample xt and uid");
-            printFailures(compareResult);
-        }
-        if (!result) {
-            CLog.i("Failed line: %s", line);
-        }
-        return result;
-    }
-
-    /**
-     * Compare the data reported by instrumentation to uid breakdown reported by the kernel,
-     * the sum of uid breakdown and the total reported by the kernel and the data reported by
-     * instrumentation to the data reported by the server.
-     * @param listener result reporter
-     * @param compactRuKey key to use when posting to rdb.
-     * @param utils data parsed from the kernel.
-     * @param instrumentationData data reported by the test.
-     * @param serverData data reported by the server.
-     * @throws DeviceNotAvailableException
-     */
-    private void reportPassFail(ITestInvocationListener listener, String compactRuKey,
-            BandwidthUtils utils, Map<String, String> serverData,
-            Map<String, String> instrumentationData) throws DeviceNotAvailableException {
-        if (compactRuKey == null) return;
-
-        int passCount = 0;
-        int failCount = 0;
-
-        // Calculate the difference between what framework reports and what the kernel reports
-        boolean download = Boolean.parseBoolean(serverData.get("download"));
-        long frameworkUidBytes = 0;
-        if (download) {
-            frameworkUidBytes = Long.parseLong(instrumentationData.get("PROF_rx"));
-        } else {
-            frameworkUidBytes = Long.parseLong(instrumentationData.get("PROF_tx"));
-        }
-
-        // Compare data reported by the server and the instrumentation
-        long serverBytes = Long.parseLong(serverData.get("size"));
-        float diff = Math.abs(BandwidthStats.computePercentDifference(
-                serverBytes, frameworkUidBytes));
-        if (diff < mServerDifferenceThreshold) {
-            passCount += 1;
-        } else {
-            CLog.i("Comparing between server and instrumentation failed expected %d got %d",
-                    serverBytes, frameworkUidBytes);
-            failCount += 1;
-        }
-
-        if (evaluateEventLog(listener)) {
-            passCount += 1;
-        } else {
-            failCount += 1;
-        }
-
-        Map<String, String> postMetrics = new HashMap<String, String>();
-        postMetrics.put("Pass", String.valueOf(passCount));
-        postMetrics.put("Fail", String.valueOf(failCount));
-
-        listener.testRunStarted(compactRuKey, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(postMetrics));
-    }
-
-    private void printFailures(CompareResult result) {
-        for (ComparisonRecord failure : result.getFailures()) {
-            CLog.i(failure.toString());
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTestTest.java b/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTestTest.java
deleted file mode 100644
index f39a632..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTestTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import junit.framework.TestCase;
-
-import java.util.Map;
-
-public class BandwidthMicroBenchMarkTestTest extends TestCase {
-
-    /**
-     * Test method for {@link BandwidthMicroBenchMarkTest#parseServerResponse(String)} on empty
-     * response.
-     */
-    public void testParseNullResponse() throws Exception {
-        assertNull(BandwidthMicroBenchMarkTest.parseServerResponse(""));
-        assertNull(BandwidthMicroBenchMarkTest.parseServerResponse(null));
-    }
-
-    /**
-     * Test method for {@link BandwidthMicroBenchMarkTest#parseServerResponse(String)} on standard
-     * response.
-     */
-    public void testParseCorrectResponse() throws Exception {
-        Map<String, String> result = BandwidthMicroBenchMarkTest.parseServerResponse(
-                "foo:bar blue:red\nandroid:google\n");
-       assertNotNull(result);
-       assertEquals(3, result.size());
-       assertTrue(result.containsKey("foo"));
-       assertEquals("bar", result.get("foo"));
-       assertEquals("red", result.get("blue"));
-       assertEquals("google", result.get("android"));
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthStats.java b/prod-tests/src/com/android/framework/tests/BandwidthStats.java
deleted file mode 100644
index 21e5f8b..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthStats.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Simple container class used to store network Stats.
- */
-public class BandwidthStats {
-    private long mRxBytes = 0;
-    private long mRxPackets = 0;
-    private long mTxBytes = 0;
-    private long mTxPackets = 0;
-
-    public BandwidthStats (long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        mRxBytes = rxBytes;
-        mRxPackets = rxPackets;
-        mTxBytes = txBytes;
-        mTxPackets = txPackets;
-    }
-
-    public BandwidthStats() {
-    }
-
-    /**
-     * Compute percent difference between a and b.
-     * @param a
-     * @param b
-     * @return % difference of a and b.
-     */
-    static float computePercentDifference(float a, float b) {
-        if (a == b) {
-            return 0;
-        }
-        if (a == 0) {
-            CLog.d("Invalid value for a: %f", a);
-            return Float.MIN_VALUE;
-        }
-        return ( a - b) / a * 100;
-    }
-
-    public long getRxBytes() {
-        return mRxBytes;
-    }
-
-    public void setRxBytes(long rxBytes) {
-        this.mRxBytes = rxBytes;
-    }
-
-    public long getRxPackets() {
-        return mRxPackets;
-    }
-
-    public void setRxPackets(long rxPackets) {
-        this.mRxPackets = rxPackets;
-    }
-
-    public long getTxBytes() {
-        return mTxBytes;
-    }
-
-    public void setTxBytes(long txBytes) {
-        this.mTxBytes = txBytes;
-    }
-
-    public long getTxPackets() {
-        return mTxPackets;
-    }
-
-    public void setTxPackets(long txPackets) {
-        this.mTxPackets = txPackets;
-    }
-
-    public CompareResult compareAll(BandwidthStats stats, float mDifferenceThreshold) {
-        CompareResult result = new CompareResult();
-        result.addRecord(this.compareRb(stats), mDifferenceThreshold);
-        result.addRecord(this.compareRp(stats), mDifferenceThreshold);
-        result.addRecord(this.compareTb(stats), mDifferenceThreshold);
-        result.addRecord(this.compareTp(stats), mDifferenceThreshold);
-        return result;
-    }
-
-    private ComparisonRecord compareTp(BandwidthStats stats) {
-        float difference = BandwidthStats.computePercentDifference(
-                this.mTxPackets, stats.mTxPackets);
-
-        ComparisonRecord result = new ComparisonRecord("Tp", this.mTxPackets, stats.mTxPackets,
-                difference);
-
-        return result;
-    }
-
-    private ComparisonRecord compareTb(BandwidthStats stats) {
-        float difference = BandwidthStats.computePercentDifference(
-                this.mTxBytes, stats.mTxBytes);
-
-        ComparisonRecord result = new ComparisonRecord("Tb", this.mTxBytes, stats.mTxBytes,
-                difference);
-
-        return result;
-    }
-
-    private ComparisonRecord compareRp(BandwidthStats stats) {
-        float difference = BandwidthStats.computePercentDifference(
-                this.mRxPackets, stats.mRxPackets);
-
-        ComparisonRecord result = new ComparisonRecord("Rp", this.mRxPackets, stats.mRxPackets,
-                difference);
-
-        return result;
-    }
-
-    private ComparisonRecord compareRb(BandwidthStats stats) {
-        float difference = BandwidthStats.computePercentDifference(
-                this.mRxBytes, stats.mRxBytes);
-
-        ComparisonRecord result = new ComparisonRecord("Rb", this.mRxBytes, stats.mRxBytes,
-                difference);
-
-        return result;
-    }
-
-    /**
-     * Holds the record of comparing a single stat like transmitted packets. All comparisons are
-     * recorded so it is easier to see which one failed later.
-     */
-    public static class ComparisonRecord {
-        private String mStatName;
-        private long mFirst;
-        private long mSecond;
-        private float mDifference;
-
-        public ComparisonRecord(String statName, long first, long second, float difference) {
-            this.mStatName = statName;
-            this.mFirst = first;
-            this.mSecond = second;
-            this.mDifference = difference;
-        }
-
-        public String getStatName() {
-            return mStatName;
-        }
-
-        public long getFirst() {
-            return mFirst;
-        }
-
-        public long getSecond() {
-            return mSecond;
-        }
-
-        public float getDifference() {
-            return mDifference;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("%s expected %d actual %d difference is %f%%",
-                    mStatName, mFirst, mSecond, mDifference);
-        }
-    }
-
-    /**
-     * Holds the result of comparing bandwidth stats from different sources. The result is passed
-     * if all individual stats are within a threshold. Also keeps track of which individual stats
-     * failed the comparison for debugging purposes.
-     *
-     */
-    public static class CompareResult {
-        private boolean mPassed;
-        private List<ComparisonRecord> mFailures;
-
-        public CompareResult() {
-            mPassed = true;
-            mFailures = new ArrayList<ComparisonRecord>();
-        }
-
-        public void addRecord(ComparisonRecord record, float threshold) {
-            if (record.getDifference() < threshold) {
-                mPassed &= true;
-            } else {
-                mPassed = false;
-                mFailures.add(record);
-            }
-        }
-
-        public boolean getResult() {
-            return mPassed;
-        }
-
-        public Collection<ComparisonRecord> getFailures() {
-            return mFailures;
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthUtils.java b/prod-tests/src/com/android/framework/tests/BandwidthUtils.java
deleted file mode 100644
index af48baa..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthUtils.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.StreamUtil;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-public class BandwidthUtils {
-
-    private BandwidthStats mDevStats;
-    private Map<Integer, BandwidthStats> mUidStats = new HashMap<Integer, BandwidthStats>();
-    private String mIface;
-    ITestDevice mTestDevice = null;
-
-    BandwidthUtils(ITestDevice device, String iface) throws DeviceNotAvailableException {
-        mTestDevice = device;
-        mIface = iface;
-        parseUidStats();
-        parseNetDevStats();
-    }
-
-    public BandwidthStats getStatsForUid(int uid) {
-        return mUidStats.get(uid);
-    }
-
-    public BandwidthStats getDevStats() {
-        return mDevStats;
-    }
-
-    public BandwidthStats getSumOfUidStats() {
-        long rb = 0, rp = 0, tb = 0, tp = 0;
-        for (BandwidthStats stats : mUidStats.values()) {
-            rb += stats.getRxBytes();
-            rp += stats.getRxPackets();
-            tb += stats.getTxBytes();
-            tp += stats.getTxPackets();
-        }
-        return new BandwidthStats(rb, rp, tb, tp);
-    }
-
-    /**
-     * Parses the uid stats from /proc/net/xt_qtaguid/stats
-     * @throws DeviceNotAvailableException
-     */
-    private void parseUidStats() throws DeviceNotAvailableException {
-        File statsFile = mTestDevice.pullFile("/proc/net/xt_qtaguid/stats");
-        FileInputStream fStream = null;
-        try {
-            fStream = new FileInputStream(statsFile);
-            String tmp = StreamUtil.getStringFromStream(fStream);
-            String[] lines = tmp.split("\n");
-            for (String line : lines) {
-                if (line.contains("idx")) {
-                    continue;
-                }
-                String[] parts = line.trim().split(" ");
-                String iface = parts[1];
-                if (!mIface.equals(iface)) {  // skip if its not iface we need
-                    continue;
-                }
-                String foreground = parts[4];
-                if (!"0".equals(foreground)) { // test uses background data, skip foreground
-                    continue;
-                }
-                String tag = parts[2];
-                int uid = Integer.parseInt(parts[3]);
-                int rb = Integer.parseInt(parts[5]);
-                int rp = Integer.parseInt(parts[6]);
-                int tb = Integer.parseInt(parts[7]);
-                int tp = Integer.parseInt(parts[8]);
-                if ("0x0".equals(tag)) {
-                    CLog.v("qtag iface %s pid %d rb %d rp %d tb %d tp %d",
-                            iface, uid, rb, rp, tb, tp);
-                    mUidStats.put(uid, new BandwidthStats(rb, rp, tb, tp));
-                }
-            }
-        } catch (IOException e) {
-            CLog.d("Failed to read file %s: %s", statsFile.toString(), e.getMessage());
-        } finally {
-            StreamUtil.close(fStream);
-        }
-    }
-
-    /**
-     * Add stats, if the iface is currently active or it is an unknown iface found in /proc/net/dev.
-     * @throws DeviceNotAvailableException
-     */
-    private void parseNetDevStats() throws DeviceNotAvailableException {
-        File file = mTestDevice.pullFile("/proc/net/dev");
-        FileInputStream fStream = null;
-        try {
-            fStream = new FileInputStream(file);
-            String tmp = StreamUtil.getStringFromStream(fStream);
-            String[] lines = tmp.split("\n");
-            for (String line : lines) {
-                if (line.contains("Receive") || line.contains("multicast")) {
-                    continue;
-                }
-                String[] parts = line.trim().split("[ :]+");
-                String iface = parts[0].replace(":", "").trim();
-                if (mIface.equals(iface)) {
-                    int rb = Integer.parseInt(parts[1]);
-                    int rp = Integer.parseInt(parts[2]);
-                    int tb = Integer.parseInt(parts[9]);
-                    int tp = Integer.parseInt(parts[10]);
-                    CLog.v("net iface %s rb %d rp %d tb %d tp %d", iface, rb, rp, tb, tp);
-                    mDevStats = new BandwidthStats(rb, rp, tb, tp);
-                    break;
-                }
-            }
-        } catch (IOException e) {
-            CLog.d("Failed to read file %s: %s", file.toString(), e.getMessage());
-        } finally {
-            StreamUtil.close(fStream);
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/DataIdleTest.java b/prod-tests/src/com/android/framework/tests/DataIdleTest.java
deleted file mode 100644
index 38ecdd3..0000000
--- a/prod-tests/src/com/android/framework/tests/DataIdleTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Test that measures the data usage for an idle device and reports it to the result listener.
- */
-public class DataIdleTest implements IDeviceTest, IRemoteTest {
-
-    ITestDevice mTestDevice = null;
-    DataIdleTestHelper mTestHelper = null;
-
-    @Option(name = "test-package-name", description = "Android test package name.")
-    private String mTestPackageName;
-
-    @Option(name = "test-class-name", description = "Optional test class name to test.")
-    private String mTestClassName;
-
-    @Option(name = "test-method-name", description = "Optional test method name to run.")
-    private String mTestMethodName;
-
-    @Option(name = "test-label",
-            description = "Test label to identify the test run.")
-    private String mTestLabel;
-
-    @Option(name = "mobile-data-only",
-            description = "If this test is to use mobile data or not.")
-    private boolean mMobileDataOnly;
-
-    @Option(name = "idle-time-msecs", description = "Time in msecs to wait for data to propagate.")
-    private int mIdleTime = 60 * 60 * 1000;
-
-    private static final String BUG_REPORT_LABEL = "bugreport";
-    private static final String DUMPSYS_REPORT_LABEL = "dumpsys";
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        mTestHelper = new DataIdleTestHelper(mTestDevice);
-        // if mobile data only, then wifi should be disabled, or vice versa
-        Assert.assertEquals("incorrect wifi status for current test parameters",
-                mMobileDataOnly, !mTestDevice.isWifiEnabled());
-        // Test the Internet connection.
-        Assert.assertTrue("Failed to connect to get data.", mTestHelper.pingTest());
-
-        CLog.v("Sleeping for %d", mIdleTime);
-        RunUtil.getDefault().sleep(mIdleTime);
-
-
-        // Run test to dump all the data stats gathered by the system.
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName,
-                mTestDevice.getIDevice());
-
-        if (mTestClassName != null) {
-            runner.setClassName(mTestClassName);
-        }
-        if (mTestClassName != null && mTestMethodName != null) {
-            runner.setMethodName(mTestClassName, mTestMethodName);
-        }
-
-        CollectingTestListener collectingListener = new CollectingTestListener();
-        Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, collectingListener));
-
-        // Collect bandwidth metrics from the instrumentation test out.
-        Map<String, String> idleTestMetrics = new HashMap<String, String>();
-        Collection<TestResult> testResults =
-                collectingListener.getCurrentRunResults().getTestResults().values();
-        if (testResults != null && testResults.iterator().hasNext()) {
-            Map<String, String> testMetrics = testResults.iterator().next().getMetrics();
-            if (testMetrics != null) {
-                idleTestMetrics.putAll(testMetrics);
-                idleTestMetrics.put("Idle time", Integer.toString(mIdleTime));
-                reportMetrics(listener, mTestLabel, idleTestMetrics);
-            }
-        }
-        // Capture the bugreport.
-        logBugReport(listener);
-        logNetStats(listener);
-    }
-
-    /**
-     * Capture the bugreport and log it.
-     * @param listener {@link ITestInvocationListener}
-     */
-    void logBugReport(ITestInvocationListener listener) {
-        try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
-            listener.testLog(BUG_REPORT_LABEL, LogDataType.BUGREPORT, bugreport);
-        }
-    }
-
-    /**
-     * Fetch the whole netstats details.
-     * @param listener {@link ITestInvocationListener}
-     * @throws DeviceNotAvailableException
-     */
-    void logNetStats(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        String output = mTestDevice.executeShellCommand("dumpsys netstats detail full");
-        InputStreamSource is = new ByteArrayInputStreamSource(output.getBytes());
-        listener.testLog(DUMPSYS_REPORT_LABEL, LogDataType.TEXT, is);
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in.
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @param runName the test name
-     * @param metrics the {@link Map} that contains metrics for the given test
-     */
-    void reportMetrics(ITestInvocationListener listener, String runName,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics: %s", metrics);
-        listener.testRunStarted(runName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-}
diff --git a/prod-tests/src/com/android/framework/tests/DataIdleTestHelper.java b/prod-tests/src/com/android/framework/tests/DataIdleTestHelper.java
deleted file mode 100644
index 78447fa..0000000
--- a/prod-tests/src/com/android/framework/tests/DataIdleTestHelper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.RunUtil;
-
-public class DataIdleTestHelper {
-    private final static String[] PING_SERVER_LIST = {"www.google.com", "www.facebook.com",
-        "www.bing.com", "www.ask.com", "www.yahoo.com"};
-    private final static String PING_FAIL_STRING = "ping: unknown host";
-    private ITestDevice mDevice;
-    private final static int RETRY_ATTEMPTS = 5;
-    private final static int PING_WAITING_TIME = 30 * 10000;  // 30 seconds
-
-    DataIdleTestHelper(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * Ping a series of popular servers to check for Internet connection.
-     *
-     * @return true if the device is able to ping the test servers.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean pingTest() throws DeviceNotAvailableException {
-        for (int i = 0; i < RETRY_ATTEMPTS; ++i) {
-            for (int j = 0; j < PING_SERVER_LIST.length; ++j) {
-                String host = PING_SERVER_LIST[j];
-                CLog.d("Start ping test, ping %s", host);
-                String res = mDevice.executeShellCommand("ping -c 10 -w 100 " + host);
-                CLog.d("res: %s", res);
-                if (!res.contains(PING_FAIL_STRING)) {
-                    return true;
-                }
-            }
-            RunUtil.getDefault().sleep(PING_WAITING_TIME);
-        }
-        return false;
-    }
-
-
-}
diff --git a/prod-tests/src/com/android/framework/tests/DownloadManagerHostTests.java b/prod-tests/src/com/android/framework/tests/DownloadManagerHostTests.java
deleted file mode 100644
index d41b890..0000000
--- a/prod-tests/src/com/android/framework/tests/DownloadManagerHostTests.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.framework.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.ResultForwarder;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.DeviceTestCase;
-
-import java.util.Hashtable;
-
-/**
- * Host-based tests of the DownloadManager API. (Uses a device-based app to actually invoke the
- * various tests.)
- */
-public class DownloadManagerHostTests extends DeviceTestCase {
-    protected PackageManagerHostTestUtils mPMUtils = null;
-
-    private static final String LOG_TAG = "android.net.DownloadManagerHostTests";
-    private static final String FILE_DOWNLOAD_PKG = "com.android.frameworks.downloadmanagertests";
-    private static final String FILE_DOWNLOAD_CLASS =
-            "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
-    private static final String DOWNLOAD_TEST_RUNNER_NAME =
-            "com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner";
-
-    // Extra parameters to pass to the TestRunner
-    private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
-
-    Hashtable<String, String> mExtraParams = null;
-
-    @Option(name = "external-download-uri", description =
-            "external URI under which the files downloaded by the tests can be found. Uri " +
-                    "must be accessible by the device during a test run.",
-                    importance = Importance.IF_UNSET)
-    private String mExternalDownloadUriValue = null;
-
-    @Option(name="wifi-network", description="the name of wifi network to connect to.")
-    private String mWifiNetwork = null;
-
-    @Option(name="wifi-psk", description="WPA-PSK passphrase of wifi network to connect to.")
-    private String mWifiPsk = null;
-
-    @Option(name = "wifi-attempts", description =
-            "maximum number of attempts to connect to wifi network.")
-    private int mWifiAttempts = 2;
-
-    private ITestDevice mDevice = null;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mDevice = getDevice();
-        assertNotNull(mDevice);
-        mPMUtils = new PackageManagerHostTestUtils(mDevice);
-        assertNotNull("Missing external-download-uri option", mExternalDownloadUriValue);
-        mExtraParams = getExtraParams();
-        assertTrue("Failed to connect to wifi!", connectToWifi());
-    }
-
-    /**
-     * Helper function to connect to wifi
-     * @throws DeviceNotAvailableException
-     */
-    protected boolean connectToWifi() throws DeviceNotAvailableException {
-        return PackageManagerHostTestUtils.connectToWifi(mDevice,
-                mWifiNetwork, mWifiPsk, mWifiAttempts);
-    }
-
-    /**
-     * Helper function to get extra params that can be used to pass into the helper app.
-     */
-    protected Hashtable<String, String> getExtraParams() {
-        Hashtable<String, String> extraParams = new Hashtable<String, String>();
-        extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, mExternalDownloadUriValue);
-        return extraParams;
-    }
-
-    /**
-     * Tests that a large download over WiFi
-     * @throws Exception if the test failed at any point
-     */
-    public void testLargeDownloadOverWiFi() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "runLargeDownloadOverWiFi", DOWNLOAD_TEST_RUNNER_NAME,
-                mExtraParams);
-        assertTrue("Failed to install large file over WiFi in < 10 minutes!", testPassed);
-    }
-
-    /**
-     * Spawns a device-based function to initiate a download on the device, reboots the device,
-     * then waits and verifies the download succeeded.
-     *
-     * @throws Exception if the test failed at any point
-     */
-    public void testDownloadManagerSingleReboot() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
-                mExtraParams);
-
-        assertTrue("Failed to initiate download properly!", testPassed);
-        mDevice.reboot();
-        assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
-        testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
-                mExtraParams);
-        assertTrue("Failed to verify initiated download completed properly!", testPassed);
-    }
-
-    /**
-     * Spawns a device-based function to initiate a download on the device, reboots the device three
-     * times (using different intervals), then waits and verifies the download succeeded.
-     *
-     * @throws Exception if the test failed at any point
-     */
-    public void testDownloadManagerMultipleReboots() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
-                mExtraParams);
-
-        assertTrue("Failed to initiate download properly!", testPassed);
-        Thread.sleep(5000);
-
-        // Do 3 random reboots - after 9, 5, and 6 seconds
-        Log.i(LOG_TAG, "First reboot...");
-        mDevice.reboot();
-        assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
-        Thread.sleep(9000);
-        Log.i(LOG_TAG, "Second reboot...");
-        mDevice.reboot();
-        assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
-        Thread.sleep(5000);
-        Log.i(LOG_TAG, "Third reboot...");
-        mDevice.reboot();
-        assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
-        Thread.sleep(6000);
-        testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
-                mExtraParams);
-        assertTrue("Failed to verify initiated download completed properyly!", testPassed);
-    }
-
-    /**
-     * Spawns a device-based function to test download while WiFi is enabled/disabled multiple times
-     * during the download.
-     *
-     * @throws Exception if the test failed at any point
-     */
-    public void testDownloadMultipleWiFiEnableDisable() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "runDownloadMultipleWiFiEnableDisable",
-                DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
-        assertTrue(testPassed);
-    }
-
-    /**
-     * Spawns a device-based function to test switching on/off both airplane mode and WiFi
-     *
-     * @throws Exception if the test failed at any point
-     */
-    public void testDownloadMultipleSwitching() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "runDownloadMultipleSwitching",
-                DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
-        assertTrue(testPassed);
-    }
-
-    /**
-     * Spawns a device-based function to test switching on/off airplane mode multiple times
-     *
-     * @throws Exception if the test failed at any point
-     */
-    public void testDownloadMultipleAirplaneModeEnableDisable() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "runDownloadMultipleAirplaneModeEnableDisable",
-                DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
-        assertTrue(testPassed);
-    }
-
-    /**
-     * Spawns a device-based function to test 15 concurrent downloads of 5,000,000-byte files
-     *
-     * @throws Exception if the test failed at any point
-     */
-    public void testDownloadMultipleSimultaneously() throws Exception {
-        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
-                FILE_DOWNLOAD_CLASS, "runDownloadMultipleSimultaneously",
-                DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
-        assertTrue(testPassed);
-    }
-
-    /**
-     * Saves dumpsys wifi log output if one of the tests fail.
-     */
-    private class WifiLogSaver extends ResultForwarder {
-
-        public WifiLogSaver(ITestInvocationListener listener) {
-            super(listener);
-        }
-
-        /** Take dumpsys wifi when test fails. */
-        @Override
-        public void testFailed(TestDescription test, String trace) {
-            try {
-                String output = mDevice.executeShellCommand("dumpsys wifi");
-                if (output == null) {
-                    CLog.w("dumpsys wifi did not return output");
-                } else {
-                    String name = test.getTestName() +"-dumpsys-wifi";
-                    try (ByteArrayInputStreamSource stream =
-                            new ByteArrayInputStreamSource(output.getBytes())) {
-                        super.testLog(name, LogDataType.TEXT, stream);
-                    }
-                }
-            } catch (DeviceNotAvailableException e) {
-                CLog.e("Error getting dumpsys wifi");
-                CLog.e(e);
-            } finally {
-                super.testFailed(test, trace);
-            }
-        }
-    }
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        WifiLogSaver proxy = new WifiLogSaver(listener);
-        super.run(proxy);
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/FrameworkPerfTest.java b/prod-tests/src/com/android/framework/tests/FrameworkPerfTest.java
deleted file mode 100644
index 366aca9..0000000
--- a/prod-tests/src/com/android/framework/tests/FrameworkPerfTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.junit.Assert;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test that measures the average latency of foreground and background
- * operations in various scenarios.
- */
-public class FrameworkPerfTest implements IRemoteTest, IDeviceTest {
-
-    private static final String TEST_PACKAGE_NAME = "com.android.frameworkperffg";
-    private static final String TEST_RUNNER_NAME = "android.test.InstrumentationTestRunner";
-    private static final int PERF_TIMEOUT = 30 * 60 * 1000; //30 minutes timeout
-    private static final int PRE_TEST_SLEEP_MS = 30 *1000; //30s sleep prior to test start
-
-    private static final String LAYOUT = "frameworkfg_perf_layout";
-    private static final String GC = "frameworkfg_perf_gc";
-    private static final String XML = "frameworkfg_perf_xml";
-    private static final String BITMAP = "frameworkfg_perf_bitmap";
-    private static final String FILE = "frameworkfg_perf_file";
-    private static final String OTHER = "frameworkfg_perf_other";
-    private static final String MAP = "frameworkfg_perf_map";
-    private static final ImmutableMap<String, String> TEST_TAG_MAP =
-            new ImmutableMap.Builder<String, String>()
-            .put("ReadFile",FILE)
-            .put("CreateWriteFile",FILE)
-            .put("CreateWriteSyncFile",FILE)
-            .put("WriteFile",FILE)
-            .put("CreateFile",FILE)
-
-            .put("CreateRecycleBitmap",BITMAP)
-            .put("LoadLargeScaledBitmap",BITMAP)
-            .put("LoadSmallScaledBitmap",BITMAP)
-            .put("LoadRecycleSmallBitmap",BITMAP)
-            .put("LoadLargeBitmap",BITMAP)
-            .put("CreateBitmap",BITMAP)
-            .put("LoadSmallBitmap",BITMAP)
-
-            .put("LayoutInflaterButton",LAYOUT)
-            .put("LayoutInflaterImageButton",LAYOUT)
-            .put("LayoutInflaterLarge",LAYOUT)
-            .put("LayoutInflaterView",LAYOUT)
-            .put("LayoutInflater",LAYOUT)
-
-            .put("Gc",GC)
-            .put("PaintGc",GC)
-            .put("ObjectGc",GC)
-            .put("FinalizingGc",GC)
-
-            .put("OpenXmlRes",XML)
-            .put("ParseXmlRes",XML)
-            .put("ReadXmlAttrs",XML)
-            .put("ParseLargeXmlRes",XML)
-
-            .put("Sched",OTHER)
-            .put("CPU",OTHER)
-            .put("MethodCall",OTHER)
-            .put("Ipc",OTHER)
-
-            .put("GrowLargeArrayMap",MAP)
-            .put("GrowLargeHashMap",MAP)
-            .put("LookupSmallHashMap",MAP)
-            .put("LookupSmallArrayMap",MAP)
-            .put("LookupTinyHashMap",MAP)
-            .put("GrowTinyHashMap",MAP)
-            .put("LookupLargeHashMap",MAP)
-            .put("LookupTinyArrayMap",MAP)
-            .put("LookupLargeArrayMap",MAP)
-            .put("GrowTinyArrayMap",MAP)
-            .put("GrowSmallHashMap",MAP)
-            .put("GrowSmallArrayMap",MAP)
-            .build();
-
-    private ITestDevice mTestDevice = null;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-
-        getDevice().reboot();
-        getRunUtil().sleep(PRE_TEST_SLEEP_MS);
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(TEST_PACKAGE_NAME,
-                TEST_RUNNER_NAME, mTestDevice.getIDevice());
-        runner.setMaxTimeToOutputResponse(PERF_TIMEOUT, TimeUnit.MILLISECONDS);
-
-        CollectingTestListener collectingListener = new CollectingTestListener();
-        Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, collectingListener));
-
-        Collection<TestResult> testResultsCollection =
-                collectingListener.getCurrentRunResults().getTestResults().values();
-
-        List<TestResult> testResults =
-                new ArrayList<TestResult>(testResultsCollection);
-
-        if (!testResults.isEmpty()) {
-            Map<String, String> testMetrics = testResults.get(0).getMetrics();
-            if (testMetrics != null) {
-                reportMetrics(listener, testMetrics);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in.
-     * @param listener The {@link ITestInvocationListener} of test results
-     * @param metrics The {@link Map} that contains metrics for the given test
-     */
-    private void reportMetrics(ITestInvocationListener listener, Map<String, String> metrics) {
-        // Parse out only averages
-        Map<String, Map<String, String>> allMetrics = new HashMap<String, Map<String, String>>();
-        for (String key : metrics.keySet()) {
-            String testLabel = TEST_TAG_MAP.get(key);
-            if (testLabel == null) {
-                testLabel = OTHER;
-            }
-            if (!allMetrics.containsKey(testLabel)) {
-                allMetrics.put(testLabel, new HashMap<String, String>());
-            }
-            allMetrics.get(testLabel).put(key, metrics.get(key));
-        }
-
-        for (String section : allMetrics.keySet()) {
-            Map<String, String> sectionMetrics = allMetrics.get(section);
-            if (sectionMetrics != null && !sectionMetrics.isEmpty()) {
-                for (String section2 : sectionMetrics.keySet()) {
-                    CLog.i("%s ::'%s' : %s", section, section2, sectionMetrics.get(section2));
-                }
-                listener.testRunStarted(section, 0);
-                listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(sectionMetrics));
-            }
-        }
-    }
-
-    IRunUtil getRunUtil() {
-        return RunUtil.getDefault();
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/FrameworkStressTest.java b/prod-tests/src/com/android/framework/tests/FrameworkStressTest.java
deleted file mode 100644
index e987db3..0000000
--- a/prod-tests/src/com/android/framework/tests/FrameworkStressTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.LogcatItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Test that instruments a stress test package, gathers iterations metrics, and posts the results.
- */
-public class FrameworkStressTest implements IDeviceTest, IRemoteTest {
-    public static final String BUGREPORT_LOG_NAME = "bugreport_stress.txt";
-
-    ITestDevice mTestDevice = null;
-
-    @Option(name = "test-package-name", description = "Android test package name.")
-    private String mTestPackageName;
-
-    @Option(name = "test-class-name", description = "Test class name.")
-    private String mTestClassName;
-
-    @Option(name = "dashboard-test-label",
-            description = "Test label to use when posting to dashboard.")
-    private String mDashboardTestLabel;
-
-    @Option(name = "setup-shell-command",
-            description = "Setup shell command to run before the test, if any.")
-    private String mSetupShellCommand;
-
-    private static final String CURRENT_ITERATION_LABEL= "currentiterations";
-    private static final String ANR_COUNT_LABEL = "anrs";
-    private static final String JAVA_CRASH_COUNT_LABEL = "java_crashes";
-    private static final String NATIVE_CRASH_COUNT_LABEL = "native_crashes";
-    private static final String ITERATION_COUNT_LABEL = "iterations";
-
-    private int mNumAnrsTotal = 0;
-    private int mNumJavaCrashesTotal = 0;
-    private int mNumNativeCrashesTotal = 0;
-
-    @Override
-    public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        if (mSetupShellCommand != null) {
-            mTestDevice.executeShellCommand(mSetupShellCommand);
-        }
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName,
-                mTestDevice.getIDevice());
-        runner.setClassName(mTestClassName);
-        CollectingTestListener collectingListener = new CollectingMetricsTestListener(listener);
-        mTestDevice.runInstrumentationTests(runner, collectingListener, listener);
-
-        Map<TestDescription, TestResult> testResults =
-                collectingListener.getCurrentRunResults().getTestResults();
-        if (testResults != null) {
-            for (Entry<TestDescription, TestResult> e : testResults.entrySet()) {
-                TestResult res = e.getValue();
-                Map<String, String> testMetrics = res.getMetrics();
-                if (testMetrics != null) {
-                    CLog.d(testMetrics.toString());
-                    // Post everything to the dashboard.
-                    String label = String.format("%s#%s", mDashboardTestLabel,
-                            e.getKey().getTestName());
-                    reportMetrics(listener, label, testMetrics);
-                }
-            }
-        }
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in.
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @param runName the test name
-     * @param metrics the {@link Map} that contains metrics for the given test
-     */
-    void reportMetrics(ITestInvocationListener listener, String runName,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics: %s with label: %s", metrics, runName);
-        listener.testRunStarted(runName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    /**
-     * Helper class to collect the Framework metrics at the end of each test.
-     */
-    private class CollectingMetricsTestListener extends CollectingTestListener {
-
-        private ITestInvocationListener mListener;
-
-        public CollectingMetricsTestListener(ITestInvocationListener listener) {
-            mListener = listener;
-        }
-
-        @Override
-        public void testEnded(TestDescription test, Map<String, String> testMetrics) {
-            // Retrieve bugreport
-            BugreportParser parser = new BugreportParser();
-            BugreportItem bugreport = null;
-            try (InputStreamSource bugSource = mTestDevice.getBugreport()) {
-                mListener.testLog(BUGREPORT_LOG_NAME, LogDataType.BUGREPORT, bugSource);
-                bugreport = parser.parse(new BufferedReader(new InputStreamReader(
-                        bugSource.createInputStream())));
-                Assert.assertNotNull(bugreport);
-                Assert.assertNotNull(bugreport.getSystemLog());
-            } catch (IOException e) {
-                Assert.fail(String.format("Failed to fetch and parse bugreport for device %s: "
-                        + "%s", mTestDevice.getSerialNumber(), e));
-            }
-            LogcatItem systemLog = bugreport.getSystemLog();
-            // We only add errors found since last test run.
-            Integer numArns = systemLog.getAnrs().size() - mNumAnrsTotal;
-            mNumAnrsTotal = systemLog.getAnrs().size();
-            testMetrics.put(ANR_COUNT_LABEL, numArns.toString());
-
-            Integer numJavaCrashes = systemLog.getJavaCrashes().size() - mNumJavaCrashesTotal;
-            mNumJavaCrashesTotal = systemLog.getJavaCrashes().size();
-            testMetrics.put(JAVA_CRASH_COUNT_LABEL, numJavaCrashes.toString());
-
-            Integer numNativeCrashes = systemLog.getNativeCrashes().size() - mNumNativeCrashesTotal;
-            mNumNativeCrashesTotal = systemLog.getNativeCrashes().size();
-            testMetrics.put(NATIVE_CRASH_COUNT_LABEL, numNativeCrashes.toString());
-
-            Integer numSuccessfulIterations =
-                    Integer.parseInt(testMetrics.get(CURRENT_ITERATION_LABEL))
-                    - numArns - numJavaCrashes - numNativeCrashes;
-            testMetrics.put(ITERATION_COUNT_LABEL, numSuccessfulIterations.toString());
-
-            super.testEnded(test, testMetrics);
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerHostTestUtils.java b/prod-tests/src/com/android/framework/tests/PackageManagerHostTestUtils.java
deleted file mode 100644
index 0734140..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerHostTestUtils.java
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Set of tests that verify host side install cases
- */
-public class PackageManagerHostTestUtils extends Assert {
-    private ITestDevice mDevice = null;
-    private boolean mEmulatedExternalStorage = false;
-
-    // TODO: get this value from Android Environment instead of hard coding
-    public static final String JB_APP_PRIVATE_PATH = "/mnt/asec/";
-    public static final String DEVICE_APP_PATH = "/data/app/";
-    public static final String SDCARD_APP_PATH = "/mnt/asec/";
-
-    private static String mAppPrivatePath = JB_APP_PRIVATE_PATH;
-
-    private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
-
-    // Install preference on the device-side
-    public static enum InstallLocPreference {
-        AUTO,
-        INTERNAL,
-        EXTERNAL
-    }
-
-    // Actual install location
-    public static enum InstallLocation {
-        DEVICE,
-        SDCARD
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param device the {@link ITestDevice} to use when performing operations.
-     * @throws DeviceNotAvailableException
-     */
-    public PackageManagerHostTestUtils(ITestDevice device)
-            throws DeviceNotAvailableException {
-        mDevice = device;
-        determineExternalStorageEmulation();
-    }
-
-    /**
-     * Returns the path on the device of forward-locked apps.
-     *
-     * @return path of forward-locked apps on the device
-     */
-    public static String getAppPrivatePath() {
-        return mAppPrivatePath;
-    }
-
-    public static void setAppPrivatePath(String path) {
-        mAppPrivatePath = path;
-    }
-
-    /**
-     * Returns the path on the device of normal apps.
-     *
-     * @return path of forward-locked apps on the device
-     */
-    public static String getDeviceAppPath() {
-        return DEVICE_APP_PATH;
-    }
-
-    /**
-     * Returns the path of apps installed on the SD card.
-     *
-     * @return path of forward-locked apps on the device
-     */
-    public static String getSDCardAppPath() {
-        return SDCARD_APP_PATH;
-    }
-
-    /**
-     * Helper method to run tests and return the listener that collected the
-     * results. For the optional params, pass null to use the default values.
-     *
-     * @param pkgName Android application package for tests
-     * @param className (optional) The class containing the method to test
-     * @param methodName (optional) The method in the class of which to test
-     * @param runnerName (optional) The name of the TestRunner of the test on
-     *            the device to be run
-     * @param params (optional) Any additional parameters to pass into the Test
-     *            Runner
-     * @return the {@link CollectingTestListener}
-     * @throws DeviceNotAvailableException
-     */
-    private CollectingTestListener doRunTests(String pkgName, String className,
-            String methodName, String runnerName, Map<String, String> params)
-            throws DeviceNotAvailableException {
-        IRemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(pkgName, runnerName,
-                mDevice.getIDevice());
-
-        if (className != null && methodName != null) {
-            testRunner.setMethodName(className, methodName);
-        }
-
-        // Add in any additional args to pass into the test
-        if (params != null) {
-            for (Entry<String, String> argPair : params.entrySet()) {
-                testRunner.addInstrumentationArg(argPair.getKey(), argPair.getValue());
-            }
-        }
-
-        CollectingTestListener listener = new CollectingTestListener();
-        mDevice.runInstrumentationTests(testRunner, listener);
-        return listener;
-    }
-
-    /**
-     * Runs the specified packages tests, and returns whether all tests passed
-     * or not.
-     *
-     * @param pkgName Android application package for tests
-     * @param className The class containing the method to test
-     * @param methodName The method in the class of which to test
-     * @param runnerName The name of the TestRunner of the test on the device to
-     *            be run
-     * @param params Any additional parameters to pass into the Test Runner
-     * @return true if test passed, false otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean runDeviceTestsDidAllTestsPass(String pkgName, String className,
-            String methodName, String runnerName, Map<String, String> params)
-            throws DeviceNotAvailableException {
-        CollectingTestListener listener = doRunTests(pkgName, className, methodName,
-                runnerName, params);
-        return !listener.hasFailedTests();
-    }
-
-    /**
-     * Runs the specified packages tests, and returns whether all tests passed
-     * or not.
-     *
-     * @param pkgName Android application package for tests
-     * @return true if every test passed, false otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean runDeviceTestsDidAllTestsPass(String pkgName)
-            throws DeviceNotAvailableException {
-        CollectingTestListener listener = doRunTests(pkgName, null, null, null, null);
-        return !listener.hasFailedTests();
-    }
-
-    /**
-     * Helper method to install a file
-     *
-     * @param localFile the {@link File} to install
-     * @param replace set to <code>true</code> if re-install of app should be
-     *            performed
-     * @throws DeviceNotAvailableException
-     */
-    public void installFile(final File localFile, final boolean replace)
-            throws DeviceNotAvailableException {
-        String result = mDevice.installPackage(localFile, replace);
-        assertEquals(null, result);
-    }
-
-    /**
-     * Helper method to install a file to device as forward locked.
-     *
-     * @param apkFile the {@link File} to install
-     * @param replace set to <code>true</code> if re-install of app should be
-     *            performed
-     * @throws DeviceNotAvailableException if communication with device is lost
-     */
-    public String installFileForwardLocked(final File apkFile, final boolean replace)
-            throws DeviceNotAvailableException {
-        return mDevice.installPackage(apkFile, replace, "-l");
-    }
-
-    /**
-     * Helper method to determine if file exists on the device containing a
-     * given string.
-     *
-     * @param destPath the absolute path of the file
-     * @return <code>true</code> if file exists containing given string,
-     *         <code>false</code> otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean doesRemoteFileExistContainingString(String destPath, String searchString)
-            throws DeviceNotAvailableException {
-        String lsResult = mDevice.executeShellCommand(String.format("ls %s", destPath));
-        return lsResult.contains(searchString);
-    }
-
-    /**
-     * Helper method to determine if package on device exists.
-     *
-     * @param packageName the Android manifest package to check.
-     * @return <code>true</code> if package exists, <code>false</code> otherwise
-     * @throws DeviceNotAvailableException
-     */
-    public boolean doesPackageExist(String packageName) throws DeviceNotAvailableException {
-        String pkgGrep = mDevice.executeShellCommand(String.format("pm path %s", packageName));
-        return pkgGrep.contains("package:");
-    }
-
-    /**
-     * Determines if app was installed on device.
-     *
-     * @param packageName package name to check for
-     * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean doesAppExistOnDevice(String packageName) throws DeviceNotAvailableException {
-        return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
-    }
-
-    /**
-     * Determines if app was installed on SD card.
-     *
-     * @param packageName package name to check for
-     * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean doesAppExistOnSDCard(String packageName) throws DeviceNotAvailableException {
-
-        // if we're using emulated storage, the SDcard path is actually the
-        // device's normal app path
-        if (getIsExternalStorageEmulated()) {
-            return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
-        }
-        else {
-            return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
-        }
-    }
-
-    /**
-     * Helper method to determine if app was installed as forward locked.
-     *
-     * @param packageName package name to check for
-     * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean doesAppExistAsForwardLocked(String packageName)
-            throws DeviceNotAvailableException {
-        return doesRemoteFileExistContainingString(mAppPrivatePath, packageName);
-    }
-
-    /**
-     * Waits for device's package manager to respond.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void waitForPackageManager() throws DeviceNotAvailableException {
-        CLog.i("waiting for device");
-        mDevice.waitForDeviceAvailable(MAX_WAIT_FOR_DEVICE_TIME);
-    }
-
-    /**
-     * Helper method for installing an app to wherever is specified in its
-     * manifest, and then verifying the app was installed onto SD Card.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param apkPath the path of the apk to install
-     * @param pkgName the name of the package
-     * @param overwrite <code>true</code> if the app should be overwritten,
-     *        <code>false</code> otherwise
-     * @throws DeviceNotAvailableException
-     */
-    public void installAppAndVerifyExistsOnSDCard(File apkPath, String pkgName, boolean overwrite)
-            throws DeviceNotAvailableException {
-        // Start with a clean slate if we're not overwriting
-        if (!overwrite) {
-            // cleanup test app just in case it already exists
-            mDevice.uninstallPackage(pkgName);
-            // grep for package to make sure its not installed
-            assertFalse(doesPackageExist(pkgName));
-        }
-
-        installFile(apkPath, overwrite);
-        assertTrue(doesAppExistOnSDCard(pkgName));
-        // TODO: is this necessary?
-        waitForPackageManager();
-
-        // grep for package to make sure it is installed
-        assertTrue(doesPackageExist(pkgName));
-    }
-
-    /**
-     * Helper method for installing an app to wherever is specified in its
-     * manifest, and then verifying the app was installed onto device.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param apkFile the {@link File} of the apk to install
-     * @param pkgName the name of the package
-     * @param overwrite <code>true</code> if the app should be overwritten,
-     *        <code>false</code> otherwise
-     * @throws DeviceNotAvailableException
-     */
-    public void installAppAndVerifyExistsOnDevice(File apkFile, String pkgName, boolean overwrite)
-            throws DeviceNotAvailableException {
-        // Start with a clean slate if we're not overwriting
-        if (!overwrite) {
-            // cleanup test app just in case it already exists
-            mDevice.uninstallPackage(pkgName);
-            // grep for package to make sure its not installed
-            assertFalse(doesPackageExist(pkgName));
-        }
-
-        installFile(apkFile, overwrite);
-        assertTrue(doesAppExistOnDevice(pkgName));
-        // TODO: is this necessary?
-        waitForPackageManager();
-
-        // grep for package to make sure it is installed
-        assertTrue(doesPackageExist(pkgName));
-    }
-
-    /**
-     * Helper method for installing an app as forward-locked, and then verifying
-     * the app was installed in the proper forward-locked location.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param apkFile the {@link File} of the apk to install
-     * @param pkgName the name of the package
-     * @param overwrite <code>true</code> if the app should be overwritten,
-     *            <code>false</code> otherwise
-     * @throws Exception if failed to install app
-     */
-    public void installFwdLockedAppAndVerifyExists(File apkFile,
-            String pkgName, boolean overwrite) throws Exception {
-        // Start with a clean slate if we're not overwriting
-        if (!overwrite) {
-            // cleanup test app just in case it already exists
-            mDevice.uninstallPackage(pkgName);
-            // grep for package to make sure its not installed
-            assertFalse(doesPackageExist(pkgName));
-        }
-
-        String result = installFileForwardLocked(apkFile, overwrite);
-        assertEquals(null, result);
-        assertTrue(doesAppExistAsForwardLocked(pkgName));
-        waitForPackageManager();
-
-        // grep for package to make sure it is installed
-        assertTrue(doesPackageExist(pkgName));
-    }
-
-    /**
-     * Helper method for uninstalling an app.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param pkgName package name to uninstall
-     * @throws DeviceNotAvailableException
-     */
-    public void uninstallApp(String pkgName) throws DeviceNotAvailableException {
-        mDevice.uninstallPackage(pkgName);
-        waitForPackageManager();
-        // make sure its not installed anymore
-        assertFalse(doesPackageExist(pkgName));
-    }
-
-    /**
-     * Sets the device's install location preference.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void setDevicePreferredInstallLocation(InstallLocPreference pref)
-            throws DeviceNotAvailableException {
-        String command = "pm set-install-location %d";
-        int locValue = 0;
-        switch (pref) {
-            case INTERNAL:
-                locValue = 1;
-                break;
-            case EXTERNAL:
-                locValue = 2;
-                break;
-            default: // AUTO
-                locValue = 0;
-                break;
-        }
-        mDevice.executeShellCommand(String.format(command, locValue));
-    }
-
-    /**
-     * Gets the device's install location preference.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public InstallLocPreference getDevicePreferredInstallLocation()
-            throws DeviceNotAvailableException {
-        String result = mDevice.executeShellCommand("pm get-install-location");
-        if (result.indexOf('0') != -1) {
-            return InstallLocPreference.AUTO;
-        }
-        else if (result.indexOf('1') != -1) {
-            return InstallLocPreference.INTERNAL;
-        }
-        else {
-            return InstallLocPreference.EXTERNAL;
-        }
-    }
-    
-    /**
-     * Determines whether the device is using emulated external storage.
-     * <p/>
-     * Sets mEmulatedExternalStorage based on the result Assumes adb is running
-     * as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    private void determineExternalStorageEmulation()
-            throws DeviceNotAvailableException {
-        String result = mDevice.executeShellCommand("sm get-primary-storage-uuid");
-        if (result.trim().equalsIgnoreCase("null")) {
-            CLog.i("Device is using emulated external storage.");
-            mEmulatedExternalStorage = true;
-        }
-        else if (result.equals("primary_physical")) {
-            CLog.i("Device is using actual external storage.");
-            mEmulatedExternalStorage = false;
-        }
-        else {
-            // older devices will not have mEmulated flag in the output
-            CLog.i("Unable to precisely determine external storage emulation; assuming false.");
-            mEmulatedExternalStorage = false;
-        }
-    }
-
-    /**
-     * Determine the location of the app private path.
-     *
-     * @param apkFile the {@link File} of test apk to determine packages'
-     *            install path.
-     * @param pkgName the {@link String} pkgName of the test apk.
-     * @throws DeviceNotAvailableException
-     */
-    public void determinePrivateAppPath(File apkFile, String pkgName)
-            throws DeviceNotAvailableException {
-        setAppPrivatePath(JB_APP_PRIVATE_PATH);
-    }
-
-    /**
-     * Returns whether the external storage is emulated or not.
-     *
-     * @return <code>true</code> if external storage is emulated,
-     *         <code>false</code> otherwise.
-     */
-    public boolean getIsExternalStorageEmulated() {
-        return mEmulatedExternalStorage;
-    }
-
-    /**
-     * Connect device to wifi.
-     *
-     * @param device
-     * @param wifiNetwork
-     * @param wifiPsk
-     * @param connectionAttempts
-     * @return true if able to connect to wifi.
-     * @throws DeviceNotAvailableException
-     */
-    public static boolean connectToWifi(ITestDevice device, String wifiNetwork, String wifiPsk,
-            int connectionAttempts) throws DeviceNotAvailableException {
-        if (wifiNetwork != null) {
-            for (int i = 0; i < connectionAttempts; i++) {
-                device.disconnectFromWifi();
-                if (device.connectToWifiNetwork(wifiNetwork, wifiPsk)) {
-                    CLog.i("Connected to wifi network %s", wifiNetwork);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Ensure that the file's permissions matches expectation.
-     *
-     * @param remoteFilePath {@link String} the remote path for the file to check.
-     * @param expectedPerms {@link String} expected permissions.
-     * @return true if the permissions for a given file matches, false otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean checkFilePermissions(String remoteFilePath, String expectedPerms)
-            throws DeviceNotAvailableException {
-        IFileEntry file = mDevice.getFileEntry(remoteFilePath);
-        return file.getPermissions().equals(expectedPerms);
-    }
-
-    /**
-     * Ensure that the file's owner matches expectation.
-     *
-     * @param remoteFilePath {@link String} the remote path for the file to check.
-     * @param expectedOwner {@link String} the expected owner.
-     * @return true if the owner for a given file matches, false otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean checkFileOwnerName(String remoteFilePath, String expectedOwner)
-            throws DeviceNotAvailableException {
-        //TODO: uncomment this, when we have support from ddmlib.
-        //IFileEntry file = mDevice.getFileEntry(remoteFilePath);
-        // return file.getOwner().equals(expectedOwner)
-        return true;
-    }
-
-    /**
-     * Ensure that the file's group matches expectation
-     *
-     * @param remoteFilePath {@link String} the remote path for the file to check.
-     * @param expectedGroup {@link String} the expected group.
-     * @return true if the group for a given file matches, false otherwise.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean checkFileGroupName(String remoteFilePath, String expectedGroup)
-            throws DeviceNotAvailableException {
-        //TODO: uncomment this, when we have support from ddmlib.
-        //IFileEntry file = mDevice.getFileEntry(remoteFilePath);
-        // return file.getGroup().equals(expectedOwner)
-        return true;
-    }
-
-    /**
-     * Returns the uid of the installed package.
-     * @param pkgName package name of the test apk.
-     * @return uid of the installed package
-     * @throws DeviceNotAvailableException
-     */
-    public Integer getUid(String pkgName) throws DeviceNotAvailableException {
-        String out = mDevice.executeShellCommand(String.format("dumpsys package %s", pkgName));
-        Matcher m = Pattern.compile("userId=(\\d+)").matcher(out);
-        assertTrue(m.find());
-
-        Integer uid = Integer.parseInt(m.group(1));
-        CLog.v("package %s has uid %d", pkgName, uid);
-        return uid;
-    }
-
-    public String getAbi(String pkgName) throws DeviceNotAvailableException {
-        String out = mDevice.executeShellCommand(String.format("dumpsys package %s", pkgName));
-        Matcher m = Pattern.compile("primaryCpuAbi=(.+)").matcher(out);
-        assertTrue(m.find());
-
-        String abi = m.group(1);
-        CLog.i("package %s has abi %s", pkgName, abi);
-        return abi;
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerHostTests.java b/prod-tests/src/com/android/framework/tests/PackageManagerHostTests.java
deleted file mode 100644
index 61c5987..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerHostTests.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.framework.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-/**
- * Set of tests that verify host side install cases
- */
-public class PackageManagerHostTests extends DeviceTestCase {
-
-    private static final String ABI_PROPERTY = "ro.product.cpu.abi";
-    private static final String ARM64_V8A = "arm64-v8a";
-    private static final String ARMEABI_V7A = "armeabi-v7a";
-    private static final String LOG_TAG = "PackageManagerHostTests";
-    private PackageManagerHostTestUtils mPMHostUtils = null;
-
-    // Various test files and their corresponding package names...
-
-    // testPushAppPrivate constants
-    // these constants must match values defined in test-apps/SimpleTestApp
-    private static final String SIMPLE_APK = "SimpleTestApp.apk";
-    private static final String SIMPLE_PKG = "com.android.framework.simpletestapp";
-
-    // Apk with install location set to auto
-    private static final String AUTO_LOC_APK = "AutoLocTestApp.apk";
-    private static final String AUTO_LOC_PKG = "com.android.framework.autoloctestapp";
-    // Apk with install location set to internalOnly
-    private static final String INTERNAL_LOC_APK = "InternalLocTestApp.apk";
-    private static final String INTERNAL_LOC_PKG = "com.android.framework.internalloctestapp";
-    // Apk with install location set to preferExternal
-    private static final String EXTERNAL_LOC_APK = "ExternalLocTestApp.apk";
-    private static final String EXTERNAL_LOC_PKG = "com.android.framework.externalloctestapp";
-    // Apk with install location set to auto (2 versions, for update testing)
-    @SuppressWarnings("unused")
-    private static final String AUTO_LOC_VERSION_V1_APK = "AutoLocVersionedTestApp_v1.apk";
-    @SuppressWarnings("unused")
-    private static final String AUTO_LOC_VERSION_V2_APK = "AutoLocVersionedTestApp_v2.apk";
-    @SuppressWarnings("unused")
-    private static final String AUTO_LOC_VERSION_PKG =
-            "com.android.framework.autolocversionedtestapp";
-    // Apk with install location set to preferExternal (2 versions, for update
-    // testing)
-    private static final String EXTERNAL_LOC_VERSION_V1_APK = "ExternalLocVersionedTestApp_v1.apk";
-    private static final String EXTERNAL_LOC_VERSION_V2_APK = "ExternalLocVersionedTestApp_v2.apk";
-    private static final String EXTERNAL_LOC_VERSION_PKG =
-            "com.android.framework.externallocversionedtestapp";
-    // Apk with install location set to auto (2 versions, for update testing)
-    private static final String NO_LOC_VERSION_V1_APK = "NoLocVersionedTestApp_v1.apk";
-    private static final String NO_LOC_VERSION_V2_APK = "NoLocVersionedTestApp_v2.apk";
-    private static final String NO_LOC_VERSION_PKG =
-            "com.android.framework.nolocversionedtestapp";
-    // Apk with no install location set
-    private static final String NO_LOC_APK = "NoLocTestApp.apk";
-    private static final String NO_LOC_PKG = "com.android.framework.noloctestapp";
-    // Apk with 2 different versions - v1 is set to external, v2 has no location
-    // setting
-    private static final String UPDATE_EXTERNAL_LOC_V1_EXT_APK = "UpdateExternalLocTestApp_v1_ext.apk";
-    private static final String UPDATE_EXTERNAL_LOC_V2_NONE_APK = "UpdateExternalLocTestApp_v2_none.apk";
-    private static final String UPDATE_EXTERNAL_LOC_PKG = "com.android.framework.updateexternalloctestapp";
-    // Apk with 2 different versions - v1 is set to external, v2 is set to
-    // internalOnly
-    private static final String UPDATE_EXT_TO_INT_LOC_V1_EXT_APK = "UpdateExtToIntLocTestApp_v1_ext.apk";
-    private static final String UPDATE_EXT_TO_INT_LOC_V2_INT_APK = "UpdateExtToIntLocTestApp_v2_int.apk";
-    private static final String UPDATE_EXT_TO_INT_LOC_PKG = "com.android.framework.updateexttointloctestapp";
-    // Apk set to preferExternal, with Access Fine Location permissions set in
-    // its manifest
-    @SuppressWarnings("unused")
-    private static final String FL_PERMS_APK = "ExternalLocPermsFLTestApp.apk";
-    @SuppressWarnings("unused")
-    private static final String FL_PERMS_PKG = "com.android.framework.externallocpermsfltestapp";
-    // Apk set to preferExternal, with all permissions set in manifest
-    private static final String ALL_PERMS_APK = "ExternalLocAllPermsTestApp.apk";
-    private static final String ALL_PERMS_PKG = "com.android.framework.externallocallpermstestapp";
-    // Apks with the same package name, but install location set to
-    // one of: Internal, External, Auto, or None
-    private static final String VERSATILE_LOC_PKG = "com.android.framework.versatiletestapp";
-    private static final String VERSATILE_LOC_INTERNAL_APK = "VersatileTestApp_Internal.apk";
-    private static final String VERSATILE_LOC_EXTERNAL_APK = "VersatileTestApp_External.apk";
-    @SuppressWarnings("unused")
-    private static final String VERSATILE_LOC_AUTO_APK = "VersatileTestApp_Auto.apk";
-    @SuppressWarnings("unused")
-    private static final String VERSATILE_LOC_NONE_APK = "VersatileTestApp_None.apk";
-    // Apks with shared UserID
-    private static final String SHARED_PERMS_APK = "ExternalSharedPermsTestApp.apk";
-    private static final String SHARED_PERMS_PKG = "com.android.framework.externalsharedpermstestapp";
-    private static final String SHARED_PERMS_FL_APK = "ExternalSharedPermsFLTestApp.apk";
-    private static final String SHARED_PERMS_FL_PKG = "com.android.framework.externalsharedpermsfltestapp";
-    private static final String SHARED_PERMS_BT_APK = "ExternalSharedPermsBTTestApp.apk";
-    private static final String SHARED_PERMS_BT_PKG = "com.android.framework.externalsharedpermsbttestapp";
-    // Apk with shared UserID, but signed with a different cert (the media cert)
-    @SuppressWarnings("unused")
-    private static final String SHARED_PERMS_DIFF_KEY_APK = "ExternalSharedPermsDiffKeyTestApp.apk";
-    @SuppressWarnings("unused")
-    private static final String SHARED_PERMS_DIFF_KEY_PKG = "com.android.framework.externalsharedpermsdiffkeytestapp";
-
-    // Shared uid apks
-    private static final String SHARED_UID_APK = "PMTest_Java.apk";
-    private static final String SHARED_UID_PKG = "com.framework.shareduid.java";
-    private static final String SHARED_UID_APK_32 = "PMTest_Java32.apk";
-    private static final String SHARED_UID_PKG_32 = "com.framework.shareduid.bit32";
-    private static final String SHARED_UID_APK_64 = "PMTest_Java64.apk";
-    private static final String SHARED_UID_PKG_64 = "com.framework.shareduid.bit64";
-    private static final String SHARED_UID_APK_DUAL = "PMTest_Java_dual.apk";
-    private static final String SHARED_UID_PKG_DUAL = "com.framework.shareduid.dual";
-
-    // TODO: consider fetching these files from build server instead.
-    @Option(name = "app-repository-path", description =
-            "path to the app repository containing large apks", importance = Importance.IF_UNSET)
-    private File mAppRepositoryPath = null;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // ensure apk path has been set before test is run
-        assertNotNull("Missing --app-repository-path option", mAppRepositoryPath);
-
-        // setup the PackageManager host tests utilities class, and get various
-        // paths we'll need...
-        mPMHostUtils = new PackageManagerHostTestUtils(getDevice());
-    }
-
-    /**
-     * Get the absolute file system location of test app with given filename
-     *
-     * @param fileName the file name of the test app apk
-     * @return {@link String} of absolute file path
-     */
-    public File getTestAppFilePath(String fileName) {
-        return FileUtil.getFileForPath(mAppRepositoryPath, fileName);
-    }
-
-    /**
-     * Regression test to verify that pushing an apk to the private app
-     * directory doesn't install the app, and otherwise cause the system to blow
-     * up.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testPushAppPrivate() throws DeviceNotAvailableException {
-        Log.i(LOG_TAG, "testing pushing an apk to /data/app-private");
-        final String apkAppPrivatePath = PackageManagerHostTestUtils.getAppPrivatePath()
-                + SIMPLE_APK;
-
-        // cleanup test app just in case it was accidently installed
-        getDevice().uninstallPackage(SIMPLE_PKG);
-        getDevice().executeShellCommand("stop");
-        getDevice().pushFile(getTestAppFilePath(SIMPLE_APK), apkAppPrivatePath);
-
-        // sanity check to make sure file is there
-        assertTrue(getDevice().doesFileExist(apkAppPrivatePath));
-        getDevice().executeShellCommand("start");
-
-        mPMHostUtils.waitForPackageManager();
-
-        // grep for package to make sure its not installed
-        assertFalse(mPMHostUtils.doesPackageExist(SIMPLE_PKG));
-        // TODO: Is the apk supposed to uninstall itself?
-        // ensure it has been deleted from app-private
-        // assertFalse(getDevice().doesFileExist(apkAppPrivatePath));
-    }
-
-    /**
-     * Helper to do a standard install of an apk and verify it installed to the
-     * correct location.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param apkName the file name of the test app apk
-     * @param pkgName the package name of the test app apk
-     * @param expectedLocation the file name of the test app apk
-     * @throws DeviceNotAvailableException
-     */
-    private void doStandardInstall(String apkName, String pkgName,
-            PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws DeviceNotAvailableException {
-
-        if (expectedLocation == PackageManagerHostTestUtils.InstallLocation.DEVICE) {
-            mPMHostUtils.installAppAndVerifyExistsOnDevice(getTestAppFilePath(apkName), pkgName,
-                    false);
-        } else {
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(apkName), pkgName,
-                    false);
-        }
-    }
-
-    /**
-     * Installs the Auto app and verifies it was installed  at expected loc.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param expectedLocation the expected location of where the apk was
-     *            installed
-     * @throws DeviceNotAvailableException
-     */
-    public void installAppAutoLoc(PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws DeviceNotAvailableException {
-        try {
-            // Auto app should go to storage with more free space when device has adopted storage
-            doStandardInstall(AUTO_LOC_APK, AUTO_LOC_PKG, expectedLocation);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(AUTO_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with its manifest set to
-     * installLocation=auto will install the app to the device
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAppLocPrefIsAuto() throws Exception {
-        Log.i(LOG_TAG, "Test app manifest installLocation=auto gets installed on device");
-        installAppAutoLoc(PackageManagerHostTestUtils.InstallLocation.DEVICE);
-    }
-
-    /**
-     * Installs the Internal app and verifies it was installed at expected loc.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param expectedLocation the expected location of where the apk was
-     *            installed
-     */
-    public void installAppInternalLoc(PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws Exception {
-        try {
-            doStandardInstall(INTERNAL_LOC_APK, INTERNAL_LOC_PKG, expectedLocation);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with its manifest set to
-     * installLocation=internalOnly will install the app to the device when
-     * device's preference is auto.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAppLocPrefIsInternal() throws Exception {
-      Log.i(LOG_TAG, "Test app manifest installLocation=internal gets installed on device");
-        installAppInternalLoc(PackageManagerHostTestUtils.InstallLocation.DEVICE);
-    }
-
-    /**
-     * Regression test to verify that an app with its manifest set to
-     * installLocation=preferExternal will install the app to expected loc.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @param expectedLocation the expected location of where the apk was
-     *            installed
-     */
-    public void installAppExternalLoc(
-            PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws Exception {
-        try {
-            doStandardInstall(EXTERNAL_LOC_APK, EXTERNAL_LOC_PKG, expectedLocation);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with its manifest set to
-     * installLocation=preferExternal will install the app to the appropriate external storage.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAppLocPrefIsExternal() throws Exception {
-        Log.i(LOG_TAG, "Test installLocation=external gets installed on SD Card");
-        installAppExternalLoc(PackageManagerHostTestUtils.InstallLocation.SDCARD);
-    }
-
-    /**
-     * Regression test to verify that an app without installLocation in its
-     * manifest will install the app to the device by default
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAppNoLocPrefIsAuto() throws Exception {
-        Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
-        try {
-            mPMHostUtils.installAppAndVerifyExistsOnDevice(
-                    getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(NO_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with its installLocation set to
-     * internal that is forward-locked will get installed to the correct
-     * location.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallFwdLockedAppInternal() throws Exception {
-        Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
-
-        try {
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(
-                    getTestAppFilePath(INTERNAL_LOC_APK), INTERNAL_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with its installLocation set to
-     * external that is forward-locked will get installed to the correct
-     * location.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallFwdLockedAppExternal() throws Exception {
-        Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
-
-        try {
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(
-                    getTestAppFilePath(EXTERNAL_LOC_APK), EXTERNAL_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with its installLocation set to
-     * external that is forward-locked will get installed to the correct
-     * location.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallFwdLockedAppAuto() throws Exception {
-        Log.i(LOG_TAG, "Test an app with installLoc set to Auto gets installed to app-private");
-
-        try {
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(
-                    getTestAppFilePath(AUTO_LOC_APK), AUTO_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(AUTO_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with no installLocation set and is
-     * forward-locked installed will get installed to the correct location.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallFwdLockedAppNone() throws Exception {
-        Log.i(LOG_TAG, "Test an app with no installLoc set gets installed to app-private");
-
-        try {
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(
-                    getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(NO_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that we can install an app onto the device,
-     * uninstall it, and reinstall it onto the SD card.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    // TODO: This currently relies on the app's manifest to switch from device
-    // to
-    // SD card install locations. We might want to make Device's
-    // installPackage()
-    // accept a installLocation flag so we can install a package to the
-    // destination of our choosing.
-    public void testReinstallInternalToExternal() throws Exception {
-        Log.i(LOG_TAG, "Test installing an app first to the device, then to the SD Card");
-
-        try {
-            mPMHostUtils.installAppAndVerifyExistsOnDevice(
-                    getTestAppFilePath(VERSATILE_LOC_INTERNAL_APK), VERSATILE_LOC_PKG, false);
-            mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(
-                    getTestAppFilePath(VERSATILE_LOC_EXTERNAL_APK), VERSATILE_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that we can install an app onto the SD Card,
-     * uninstall it, and reinstall it onto the device.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    // TODO: This currently relies on the app's manifest to switch from device
-    // to
-    // SD card install locations. We might want to make Device's
-    // installPackage()
-    // accept a installLocation flag so we can install a package to the
-    // destination of our choosing.
-    public void testReinstallExternalToInternal() throws Exception {
-        Log.i(LOG_TAG, "Test installing an app first to the SD Care, then to the device");
-
-        try {
-            // install the app externally
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(
-                    getTestAppFilePath(VERSATILE_LOC_EXTERNAL_APK), VERSATILE_LOC_PKG, false);
-            mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
-            // then replace the app with one marked for internalOnly
-            mPMHostUtils.installAppAndVerifyExistsOnDevice(
-                    getTestAppFilePath(VERSATILE_LOC_INTERNAL_APK), VERSATILE_LOC_PKG, false);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that updating an app on the SD card will
-     * install the update onto the SD card as well when location is set to
-     * external for both versions
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testUpdateBothExternal() throws Exception {
-        Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
-        try {
-            // install the app externally
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    EXTERNAL_LOC_VERSION_V1_APK), EXTERNAL_LOC_VERSION_PKG, false);
-            // now replace the app with one where the location is still set to
-            // preferExternal
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    EXTERNAL_LOC_VERSION_V2_APK), EXTERNAL_LOC_VERSION_PKG, true);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(EXTERNAL_LOC_VERSION_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that updating an app on the SD card will
-     * install the update onto the SD card as well when location is not
-     * explicitly set in the updated apps' manifest file.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testUpdateToSDCard() throws Exception {
-        Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
-        try {
-            // install the app externally
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    UPDATE_EXTERNAL_LOC_V1_EXT_APK), UPDATE_EXTERNAL_LOC_PKG, false);
-            // now replace the app with one where the location is blank (app
-            // should stay external)
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    UPDATE_EXTERNAL_LOC_V2_NONE_APK), UPDATE_EXTERNAL_LOC_PKG, true);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(UPDATE_EXTERNAL_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that updating an app on the SD card will
-     * install the update onto the device if the manifest has changed to
-     * installLocation=internalOnly
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testUpdateSDCardToDevice() throws Exception {
-        Log.i(LOG_TAG, "Test updating an app on the SD card to the Device through manifest change");
-
-        try {
-            // install the app externally
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    UPDATE_EXT_TO_INT_LOC_V1_EXT_APK), UPDATE_EXT_TO_INT_LOC_PKG, false);
-            // now replace the app with an update marked for
-            // internalOnly...(should move internal)
-            mPMHostUtils.installAppAndVerifyExistsOnDevice(getTestAppFilePath(
-                    UPDATE_EXT_TO_INT_LOC_V2_INT_APK), UPDATE_EXT_TO_INT_LOC_PKG, true);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(UPDATE_EXT_TO_INT_LOC_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that installing and updating a forward-locked
-     * app will install the update onto the device's forward-locked location
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndUpdateExternalLocForwardLockedApp() throws Exception {
-        Log.i(LOG_TAG, "Test updating a forward-locked app marked preferExternal");
-
-        try {
-            // first try to install the forward-locked app externally
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
-                    EXTERNAL_LOC_VERSION_V1_APK), EXTERNAL_LOC_VERSION_PKG, false);
-            // now replace the app with an update marked for internalOnly and as
-            // forward locked
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
-                    EXTERNAL_LOC_VERSION_V2_APK), EXTERNAL_LOC_VERSION_PKG, true);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(EXTERNAL_LOC_VERSION_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that updating a forward-locked app will install
-     * the update onto the device's forward-locked location
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndUpdateNoLocForwardLockedApp() throws Exception {
-        Log.i(LOG_TAG, "Test updating a forward-locked app with no installLocation pref set");
-
-        try {
-            // install the app
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
-                    NO_LOC_VERSION_V1_APK), NO_LOC_VERSION_PKG, false);
-            // now replace the app with an update marked for internalOnly...
-            mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
-                    NO_LOC_VERSION_V2_APK), NO_LOC_VERSION_PKG, true);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(NO_LOC_VERSION_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with all permissions set can be
-     * installed on SD card and then launched without crashing.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchAllPermsAppOnSD() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app with all perms set, installed on SD card");
-
-        try {
-            // install the app
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    ALL_PERMS_APK), ALL_PERMS_PKG, false);
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(ALL_PERMS_PKG);
-            assert (testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(ALL_PERMS_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with ACCESS_FINE_LOCATION (GPS)
-     * permissions can run without permissions errors.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchFLPermsAppOnSD() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
-
-        try {
-            // install the app and verify we can launch it without permissions
-            // errors
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
-            assert (testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with BLUE_TOOTH permissions can run
-     * without permissions errors.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchBTPermsAppOnSD() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app with bluetooth perms set, installed on SD card");
-
-        try {
-            // install the app and verify we can launch it without permissions
-            // errors
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_BT_PKG);
-            assert (testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that a shared app with no explicit permissions
-     * throws a SecurityException when launched if its other shared apps are not
-     * installed.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchSharedPermsAppOnSD_NoPerms() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
-
-        try {
-            // Make sure the 2 shared apps with needed permissions are not
-            // installed...
-            mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
-            mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
-
-            // now install the app and see if when we launch it we get a
-            // permissions error
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
-
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
-            assertEquals("Shared perms app should fail to run", false, testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that a shared app with no explicit permissions
-     * can run if its other shared apps are installed.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchSharedPermsAppOnSD_GrantedPerms() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
-
-        try {
-            // install the 2 shared apps with needed permissions first
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-
-            // now install the test app and see if we can launch it without
-            // errors
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
-            assert (testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
-            mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
-            mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that an app with ACCESS_FINE_LOCATION (GPS)
-     * permissions can run without permissions errors even after a reboot
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchFLPermsAppOnSD_Reboot() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
-
-        try {
-            // install the app and verify we can launch it without permissions
-            // errors
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
-            assert (testsPassed);
-
-            getDevice().reboot();
-
-            testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
-            assert (testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
-        }
-    }
-
-    /**
-     * Regression test to verify that a shared app with no explicit permissions
-     * can run if its other shared apps are installed, even after a reboot.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallAndLaunchSharedPermsAppOnSD_Reboot() throws Exception {
-        Log.i(LOG_TAG, "Test launching an app on SD, with no explicit perms set after reboot");
-
-        try {
-            // install the 2 shared apps with needed permissions first
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-
-            // now install the test app and see if we can launch it without
-            // errors
-            mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
-                    SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
-            boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
-            assert (testsPassed);
-
-            // reboot
-            getDevice().reboot();
-
-            // Verify we can still launch the app
-            testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
-            assert (testsPassed);
-        }
-        // cleanup test app
-        finally {
-            mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
-            mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
-            mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
-        }
-    }
-
-    public void testInstallApk32bit() throws DeviceNotAvailableException {
-        try {
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_32), true);
-            assertEquals(ARMEABI_V7A, mPMHostUtils.getAbi(SHARED_UID_PKG_32));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_32);
-        }
-
-    }
-
-    public void testInstallApk64bit() throws DeviceNotAvailableException {
-        try {
-            if (!ARM64_V8A.equals(getDevice().getProperty(ABI_PROPERTY))) {
-                return;
-            }
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_64), true);
-            assertEquals(ARM64_V8A, mPMHostUtils.getAbi(SHARED_UID_PKG_64));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_64);
-        }
-
-    }
-
-    public void testInstallApkDualAbi() throws DeviceNotAvailableException {
-        try {
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
-            assertEquals(getDevice().getProperty(ABI_PROPERTY),
-                    mPMHostUtils.getAbi(SHARED_UID_PKG_DUAL));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
-        }
-    }
-
-    public void testInstallSharedUid32() throws DeviceNotAvailableException {
-        try{
-            if (!ARMEABI_V7A.equals(getDevice().getProperty(ABI_PROPERTY))) {
-                return;
-            }
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK), true);
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_32), true);
-            assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG),
-                    mPMHostUtils.getUid(SHARED_UID_PKG_32));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG);
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_32);
-        }
-    }
-
-    public void testInstallSharedUid64() throws DeviceNotAvailableException {
-        try{
-            if (!ARM64_V8A.equals(getDevice().getProperty(ABI_PROPERTY))) {
-                return;
-            }
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK), true);
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_64), true);
-            assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG),
-                    mPMHostUtils.getUid(SHARED_UID_PKG_64));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG);
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_64);
-        }
-    }
-
-    public void testInstallSharedUidDual64() throws DeviceNotAvailableException {
-        try{
-            if (!ARM64_V8A.equals(getDevice().getProperty(ABI_PROPERTY))) {
-                return;
-            }
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_64), true);
-            assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG_DUAL),
-                    mPMHostUtils.getUid(SHARED_UID_PKG_64));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_64);
-        }
-    }
-
-    public void testInstallSharedUidDual32() throws DeviceNotAvailableException {
-        try{
-            if (!ARMEABI_V7A.equals(getDevice().getProperty(ABI_PROPERTY))) {
-                return;
-            }
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_32), true);
-            assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG_DUAL),
-                    mPMHostUtils.getUid(SHARED_UID_PKG_32));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_32);
-        }
-    }
-
-    public void testInstallSharedUidJavaDual() throws DeviceNotAvailableException {
-        try{
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
-            mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK), true);
-            assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG_DUAL),
-                    mPMHostUtils.getUid(SHARED_UID_PKG));
-        } finally {
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
-            mPMHostUtils.uninstallApp(SHARED_UID_PKG);
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerOTATestUtils.java b/prod-tests/src/com/android/framework/tests/PackageManagerOTATestUtils.java
deleted file mode 100644
index 9de3577..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerOTATestUtils.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.framework.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import org.junit.Assert;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathFactory;
-/**
- * Utility method used for PackageMangerOTATests. Requires adb root.
- */
-public class PackageManagerOTATestUtils {
-    public static final String USERDATA_PARTITION = "userdata";
-    public static final String PACKAGE_XML_FILE = "/data/system/packages.xml";
-
-    private ITestDevice mDevice = null;
-
-    /**
-     * Constructor.
-     *
-     * @param device the {@link ITestDevice} to use when performing operations.
-     * @throws DeviceNotAvailableException
-     */
-    public PackageManagerOTATestUtils(ITestDevice device)
-            throws DeviceNotAvailableException {
-        mDevice = device;
-    }
-
-    /**
-     * Wipe userdata partition on device.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void wipeDevice() throws DeviceNotAvailableException {
-        // Make sure to keep the local.prop file for testing purposes.
-        File prop = mDevice.pullFile("/data/local.prop");
-        mDevice.rebootIntoBootloader();
-        mDevice.fastbootWipePartition(USERDATA_PARTITION);
-        mDevice.rebootUntilOnline();
-        if (prop != null) {
-            mDevice.pushFile(prop, "/data/local.prop");
-            mDevice.executeShellCommand("chmod 644 /data/local.prop");
-            mDevice.reboot();
-        }
-    }
-
-    /**
-     * Remove a system app.
-     * @param systemApp {@link String} name for the application in the /system/app folder
-     * @param reboot set to <code>true</code> to optionally reboot device after app removal
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void removeSystemApp(String systemApp, boolean reboot)
-            throws DeviceNotAvailableException {
-        mDevice.remountSystemWritable();
-        String cmd = String.format("rm %s", systemApp);
-        mDevice.executeShellCommand(cmd);
-        if (reboot) {
-            mDevice.reboot();
-        }
-        mDevice.waitForDeviceAvailable();
-    }
-
-    /**
-     * Remove a system app and wipe the device.
-     * @param systemApp {@link String} name for the application in the /system/app folder
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void removeAndWipe(String systemApp)
-            throws DeviceNotAvailableException {
-        removeSystemApp(systemApp, false);
-        wipeDevice();
-    }
-
-    /**
-     * Expect that a given xpath exists in a given xml file.
-     * @param xmlFile {@link File} xml file to process
-     * @param xPathString {@link String} Xpath to look for
-     *
-     * @return true if the xpath is found
-     */
-    public boolean expectExists(File xmlFile, String xPathString) {
-        Node n = getNodeForXPath(xmlFile, xPathString);
-        if (n != null) {
-            CLog.d("Found node %s for xpath %s", n.getNodeName(), xPathString);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Expect that the value of a given xpath starts with a given string.
-     *
-     * @param xmlFile {@link File} the xml file in question
-     * @param xPathString {@link String} the xpath to look for
-     * @param value {@link String} the expected start string of the xpath
-     *
-     * @return true if the value for the xpath starts with value, false otherwise
-     */
-    public boolean expectStartsWith(File xmlFile, String xPathString, String value) {
-        Node n = getNodeForXPath(xmlFile, xPathString);
-        if ( n==null ) {
-            CLog.d("Failed to find node for xpath %s", xPathString);
-            return false;
-        }
-        CLog.d("Value of node %s: %s", xPathString, n.getNodeValue());
-        return n.getNodeValue().toLowerCase().startsWith(value.toLowerCase());
-    }
-
-    /**
-     * Expect that the value of a given xpath matches.
-     *
-     * @param xmlFile {@link File} the xml file in question
-     * @param xPathString {@link String} the xpath to look for
-     * @param value {@link String} the expected string value
-     *
-     * @return true if the value for the xpath matches, false otherwise
-     */
-    public boolean expectEquals(File xmlFile, String xPathString, String value) {
-        Node n = getNodeForXPath(xmlFile, xPathString);
-        if ( n==null ) {
-            CLog.d("Failed to find node for xpath %s", xPathString);
-            return false;
-        }
-        boolean result = n.getNodeValue().equalsIgnoreCase(value);
-        if (!result) {
-            CLog.v("Value of node %s: \"%s\", expected: \"%s\"",
-                    xPathString, n.getNodeValue(), value);
-        }
-        return result;
-    }
-
-    public Node getNodeForXPath(File xmlFile, String xPathString) {
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        try {
-            DocumentBuilder documentBuilder = factory.newDocumentBuilder();
-            Document doc = documentBuilder.parse(xmlFile);
-            XPathFactory xpFactory = XPathFactory.newInstance();
-            XPath xpath = xpFactory.newXPath();
-            XPathExpression expr = xpath.compile(xPathString);
-            Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
-            return node;
-        } catch (Exception e) {
-            CLog.e(e);
-        }
-        return null;
-    }
-
-    /**
-     * Check if a given package has the said permission.
-     * @param packageName {@link String} the package in question
-     * @param permission {@link String} the permission to look for
-     *
-     * @return true if the permission exists, false otherwise
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public boolean packageHasPermission(String packageName, String permission)
-            throws DeviceNotAvailableException {
-        String cmd = "dumpsys package " + packageName;
-        String res = mDevice.executeShellCommand(cmd);
-        if (res != null) {
-            if (res.contains("grantedPermissions:")) {
-                return res.contains(permission);
-            } else {
-                Pattern perm = Pattern.compile(String.format("^.*%s.*granted=true.*$", permission),
-                        Pattern.MULTILINE);
-                Matcher m = perm.matcher(res);
-                return m.find();
-            }
-        }
-        CLog.d("Failed to execute shell command: %s", cmd);
-        return false;
-    }
-
-    /**
-     * Check if a given package has the said permission.
-     * @param packageName {@link String} the package in question
-     * @param flag {@link String} the permission to look for
-     *
-     * @return true if the permission exists, false otherwise
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public boolean packageHasFlag(String packageName, String flag)
-            throws DeviceNotAvailableException {
-        String cmd = "dumpsys package " + packageName;
-        String res = mDevice.executeShellCommand(cmd);
-        if (res != null) {
-            Pattern flags = Pattern.compile("^.*flags=\\[(.*?)\\]$", Pattern.MULTILINE);
-            Matcher m = flags.matcher(res);
-            if (m.find()) {
-                return m.group(1).contains(flag);
-            } else {
-                CLog.d("Failed to find package flags record in dumpsys package output");
-            }
-        }
-        CLog.d("Failed to execute shell command: %s", cmd);
-        return false;
-    }
-
-    /**
-     * Helper method to install a file
-     *
-     * @param localFile the {@link File} to install
-     * @param replace set to <code>true</code> if re-install of app should be performed
-     * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
-     *            available options.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void installFile(final File localFile, final boolean replace, String... extraArgs)
-            throws DeviceNotAvailableException {
-        String result = mDevice.installPackage(localFile, replace, extraArgs);
-        Assert.assertNull(String.format("Failed to install file %s with result %s",
-                localFile.getAbsolutePath(), result), result);
-    }
-
-    /**
-     * Helper method to stop system shell.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void stopSystem() throws DeviceNotAvailableException {
-        mDevice.executeShellCommand("stop");
-    }
-
-    /**
-     * Helper method to start system shell. It also reset the flag dev.bootcomplete to 0 to ensure
-     * that the package manager had a chance to finish.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void startSystem() throws DeviceNotAvailableException {
-        mDevice.executeShellCommand("setprop dev.bootcomplete 0");
-        mDevice.executeShellCommand("start");
-        mDevice.waitForDeviceAvailable();
-    }
-
-    /**
-     * Convenience method to stop, then start the runtime.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void restartSystem() throws DeviceNotAvailableException {
-        stopSystem();
-        startSystem();
-    }
-
-    /**
-     * Push apk to system app directory on the device.
-     *
-     * @param localFile {@link File} the local file to install
-     * @param deviceFilePath {@link String} the remote device path where to install the application
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void pushSystemApp(final File localFile, final String deviceFilePath)
-            throws DeviceNotAvailableException {
-        mDevice.remountSystemWritable();
-        stopSystem();
-        mDevice.pushFile(localFile, deviceFilePath);
-        startSystem();
-    }
-
-    /**
-     * Pulls packages xml file from the device.
-     * @return {@link File} xml file for all packages on device.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public File pullPackagesXML() throws DeviceNotAvailableException {
-        return mDevice.pullFile(PACKAGE_XML_FILE);
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerOTATests.java b/prod-tests/src/com/android/framework/tests/PackageManagerOTATests.java
deleted file mode 100644
index 4911ba5..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerOTATests.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.framework.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-public class PackageManagerOTATests extends DeviceTestCase {
-
-    @Option(name = "test-app-path", description =
-            "path to the app repository containing test apks", importance = Importance.IF_UNSET)
-    private File mTestAppRepositoryPath = null;
-    @Option(name = "use-priv-path", description =
-            "set to true if the special priviledged app directory should be used; default is false",
-            importance = Importance.IF_UNSET)
-    private boolean mUsePrivAppDirectory = false;
-
-    private PackageManagerOTATestUtils mUtils = null;
-    private String mSystemAppPath = "/system/app/version_test.apk";
-    private String mDiffSystemAppPath = "/system/app/version_test_diff.apk";
-
-    // String constants use for the tests.
-    private static final String PACKAGE_XPATH = "/packages/package[@name=\"" +
-            "com.android.frameworks.coretests.version_test\"]";
-    private static final String UPDATE_PACKAGE_XPATH = "/packages/updated-package[@name=\"" +
-            "com.android.frameworks.coretests.version_test\"]";
-    private static final String VERSION_XPATH = "/packages/package[@name=\"" +
-            "com.android.frameworks.coretests.version_test\"]/@version";
-    private static final String CODE_PATH_XPATH = "/packages/package[@name=\"" +
-            "com.android.frameworks.coretests.version_test\"]/@codePath";
-    private static final String VERSION_1_APK = "FrameworkCoreTests_version_1.apk";
-    private static final String VERSION_2_APK = "FrameworkCoreTests_version_2.apk";
-    private static final String VERSION_3_APK = "FrameworkCoreTests_version_3.apk";
-    private static final String VERSION_1_NO_SYS_PERMISSION_APK =
-            "FrameworkCoreTests_version_1_nosys.apk";
-    private static final String DATA_APP_DIRECTORY = "/data/app/";
-    private static final String PACKAGE_NAME = "com.android.frameworks.coretests.version_test";
-    private static final String VIBRATE_PERMISSION = "android.permission.VIBRATE";
-    private static final String CACHE_PERMISSION = "android.permission.ACCESS_CACHE_FILESYSTEM";
-
-
-    // Temporary file used when examine the packages xml file from the device.
-    private File mPackageXml = null;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mUtils = new PackageManagerOTATestUtils(getDevice());
-
-        if (mUsePrivAppDirectory) {
-            mSystemAppPath = "/system/priv-app/version_test.apk";
-            mDiffSystemAppPath = "/system/priv-app/version_test_diff.apk";
-        }
-
-        // Clean up any potential old files from previous tests.
-        // delete from /system if exists
-        getDevice().enableAdbRoot();
-        mUtils.removeSystemApp(mSystemAppPath, false);
-        mUtils.removeSystemApp(mDiffSystemAppPath, false);
-        mUtils.restartSystem();
-        // delete from /data if there is one
-        getDevice().uninstallPackage(PACKAGE_NAME);
-
-        String res = getDevice().executeShellCommand("pm path " + PACKAGE_NAME).trim();
-        assertTrue("Package should not be installed before test", res.isEmpty());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Clean up.
-        if (mPackageXml != null) {
-            FileUtil.deleteFile(mPackageXml);
-        }
-    }
-
-    /**
-     * Get the absolute file system location of test app with given filename
-     *
-     * @param fileName the file name of the test app apk
-     * @return {@link String} of absolute file path
-     */
-    public File getTestAppFilePath(String fileName) {
-        // need to check both data/app/apkFileName and
-        // data/app/apkFileName/apkFileName
-        File file = FileUtil.getFileForPath(mTestAppRepositoryPath, fileName);
-        if (file.exists()) {
-            return file;
-        }
-
-        int index = fileName.lastIndexOf('.');
-        String dir = fileName.substring(0, index);
-        file = FileUtil.getFileForPath(mTestAppRepositoryPath, dir, fileName);
-        CLog.d("Test path : %s", file.getAbsolutePath());
-        return file;
-    }
-
-    /**
-     * Test case when system app added is newer than update.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppAddedNewerThanUpdate() throws DeviceNotAvailableException {
-        mUtils.installFile(getTestAppFilePath(VERSION_1_APK), true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertNotNull("Failed to pull packages xml file from device", mPackageXml);
-        assertTrue("Initial package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package version should be 1",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "1"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertFalse("Package should not have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("After system app push, package should still be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("After system app push, system app should be visible",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-    }
-
-    /**
-     * Test case when system app added is older than update.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppAddedOlderThanUpdate() throws DeviceNotAvailableException {
-        mUtils.installFile(getTestAppFilePath(VERSION_2_APK), true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertNotNull("Failed to pull packages xml file from device", mPackageXml);
-        assertTrue("Initial package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertFalse("Package should not have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("After system app push, package should still be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("After system app push, system app should be visible",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-    }
-
-    /**
-     * Test when system app gets removed.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppRemoved() throws DeviceNotAvailableException {
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("Initial package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        mUtils.removeSystemApp(mSystemAppPath, true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("Package should not be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-    }
-
-    /**
-     * Test when update has a newer version.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppUpdatedNewerVersion() throws DeviceNotAvailableException {
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("The package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.installFile(getTestAppFilePath(VERSION_3_APK), true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After system app upgrade, the path should be the upgraded app on /data",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 3",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After system app upgrade, the path should be the upgraded app on /data",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 3",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After system app upgrade, the path should be the upgraded app on /data",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 3",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-    }
-
-    /**
-     * Test when update has an older version.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppUpdatedOlderVersion() throws DeviceNotAvailableException {
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("After system app push, the package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        // The "-d" command forces a downgrade.
-        mUtils.installFile(getTestAppFilePath(VERSION_1_APK), true, "-d");
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("After system app upgrade, the path should be the upgraded app on /data",
-                mUtils.expectStartsWith(mPackageXml, CODE_PATH_XPATH,
-                DATA_APP_DIRECTORY + PACKAGE_NAME));
-        assertTrue("Package version should be 1",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "1"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("After reboot, the path should be the be installed",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should NOT be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("After reboot, the path should be the be installed",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should NOT be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-    }
-
-    /**
-     * Test when updated system app has the same version. Package manager is expected to use
-     * the newly installed upgrade.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppUpdatedSameVersion_PreferUpdatedApk()
-            throws DeviceNotAvailableException {
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("The package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.installFile(getTestAppFilePath(VERSION_2_APK), true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After system app upgrade, the path should be the upgraded app in /data",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After reboot, the path should be the upgraded app in /data",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 2",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-    }
-
-    /**
-     * Test when update has system app removed.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testUpdatedSystemAppRemoved() throws DeviceNotAvailableException {
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_APK), mSystemAppPath);
-        mUtils.installFile(getTestAppFilePath(VERSION_2_APK), true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("Package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.removeSystemApp(mSystemAppPath, true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("Package should still be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertFalse("Updated-package entry should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertFalse("Package should not have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-    }
-
-    /**
-     * Test when system app is updated with a new permission. Specifically:
-     * <ol>
-     * <li>system app FOO is present, does not declare system permission</li>
-     * <li>FOO is overlain by an installed update that declares new permission</li>
-     * <li>FOO is replaced during an OTA, but installed update still has higher version number</li>
-     * <li>Verify permission is granted</li>
-     * </ol>
-     *
-     * @throws DeviceNotAvailableException
-     */
-    public void testSystemAppUpdatedNewPermission() throws DeviceNotAvailableException {
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_NO_SYS_PERMISSION_APK), mSystemAppPath);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertTrue("The package should be installed",
-                mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
-        assertTrue("Package version should be 1",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "1"));
-        assertFalse("Updated-package should not be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.installFile(getTestAppFilePath(VERSION_3_APK), true);
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After system app upgrade, the path should be the upgraded app on /data",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 3",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After reboot, the path should be the data app",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 3",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
-        mUtils.restartSystem();
-        mPackageXml = mUtils.pullPackagesXML();
-        assertFalse("After reboot, the path should be the data app",
-                mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
-        assertTrue("Package version should be 3",
-                mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
-        assertTrue("Updated-package should be present",
-                mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
-        assertTrue("Package should have FLAG_SYSTEM",
-                mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
-        assertTrue("VIBRATE permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
-        assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
-                mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerStressHostTests.java b/prod-tests/src/com/android/framework/tests/PackageManagerStressHostTests.java
deleted file mode 100644
index b02663b..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerStressHostTests.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.framework.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-/**
- * Set of tests that verify host side stress scenarios (large apps, multiple upgrades, etc.)
- */
-public class PackageManagerStressHostTests extends DeviceTestCase {
-
-    private PackageManagerHostTestUtils mPMHostUtils = null;
-
-    // Path to the app repository and various subdirectories of it
-    // Note: These stress tests require large apks that cannot be checked into the tree.
-    // These variables define static locations that point to existing APKs (not built from
-    // the tree) which can be used by the stress tests in this file.
-    private static final String LARGE_APPS_DIRECTORY_NAME = "largeApps";
-    private static final String MISC_APPS_DIRECTORY_NAME = "miscApps";
-    private static final String VERSIONED_APPS_DIRECTORY_NAME = "versionedApps";
-    private static final String MANY_APPS_DIRECTORY_NAME = "manyApps";
-
-    // Large apps (>1mb) - filenames and their corresponding package names:
-    private static enum APK {
-        FILENAME,
-        PACKAGENAME;
-    }
-    private static final String[][] LARGE_APPS = {
-        {"External1mb.apk", "com.appsonsd.mytests.External1mb"},
-        {"External2mb.apk", "com.appsonsd.mytests.External2mb"},
-        {"External3mb.apk", "com.appsonsd.mytests.External3mb"},
-        {"External4mb.apk", "com.appsonsd.mytests.External4mb"},
-        {"External5mb.apk", "com.appsonsd.mytests.External5mb"},
-        {"External6mb.apk", "com.appsonsd.mytests.External6mb"},
-        {"External7mb.apk", "com.appsonsd.mytests.External7mb"},
-        {"External8mb.apk", "com.appsonsd.mytests.External8mb"},
-        {"External9mb.apk", "com.appsonsd.mytests.External9mb"},
-        {"External10mb.apk", "com.appsonsd.mytests.External10mb"},
-        {"External16mb.apk", "com.appsonsd.mytests.External16mb"},
-        {"External28mb.apk", "com.appsonsd.mytests.External28mb"},
-        {"External34mb.apk", "com.appsonsd.mytests.External34mb"},
-        {"External46mb.apk", "com.appsonsd.mytests.External46mb"},
-        {"External58mb.apk", "com.appsonsd.mytests.External58mb"},
-        {"External65mb.apk", "com.appsonsd.mytests.External65mb"},
-        {"External72mb.apk", "com.appsonsd.mytests.External72mb"},
-        {"External79mb.apk", "com.appsonsd.mytests.External79mb"},
-        {"External86mb.apk", "com.appsonsd.mytests.External86mb"},
-        {"External93mb.apk", "com.appsonsd.mytests.External93mb"}};
-
-    // Various test files and their corresponding package names
-    private static final String EXTERNAL_LOC_APK = "External931kb.apk";
-    private static final String EXTERNAL_LOC_PKG = "com.appsonsd.mytests.External931kb";
-
-    // Versioned test apps
-    private static final String VERSIONED_APPS_FILENAME_PREFIX = "External455kb_v";
-    private static final String VERSIONED_APPS_PKG = "com.appsonsd.mytests.External455kb";
-    private static final int VERSIONED_APPS_START_VERSION = 1;  // inclusive
-    private static final int VERSIONED_APPS_END_VERSION = 250;  // inclusive
-
-    // Large number of app installs
-    // @TODO: increase the max when we can install more apps
-    private static final int MANY_APPS_START = 1;
-    private static final int MANY_APPS_END = 100;
-    private static final String MANY_APPS_PKG_PREFIX = "com.appsonsd.mytests.External49kb_";
-    private static final String MANY_APPS_APK_PREFIX = "External49kb_";
-    private static final int DEFAULT_ITERATION_COUNT = 100;
-
-    @Option(name = "app-repository-path", description =
-            "path to the app repository containing large apks.", importance = Importance.IF_UNSET)
-    private File mAppRepositoryPath = null;
-
-    @Option(name = "stress-iteration-count", description =
-            "Number of iterations to run the package manager stress test for.",
-            importance = Importance.IF_UNSET)
-    private int mIterationCount = DEFAULT_ITERATION_COUNT;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // setup the PackageManager host tests utilities class, and get various paths we'll need...
-        mPMHostUtils = new PackageManagerHostTestUtils(getDevice());
-        // ensure apk path has been set before test is run
-        assertNotNull("Missing --app-repository-path option", mAppRepositoryPath);
-    }
-
-    /**
-     * Get the {@link File} of repository test app with given filename
-     * @param fileName the file name of the test app apk
-     * @return {@link File}
-     */
-    private File getRepositoryTestAppFilePath(String fileDirectory, String fileName) {
-        return FileUtil.getFileForPath(mAppRepositoryPath, fileDirectory, fileName);
-    }
-
-    /**
-     * Stress test to verify that we can update an app multiple times on the SD card.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testUpdateAppManyTimesOnSD() throws Exception {
-        CLog.i("Test updating an app on SD numerous times");
-        // cleanup test app just in case it already exists
-        mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG);
-        try {
-            for (int i = VERSIONED_APPS_START_VERSION; i <= VERSIONED_APPS_END_VERSION; ++i) {
-                String currentApkName = String.format("%s%d.apk",
-                        VERSIONED_APPS_FILENAME_PREFIX, i);
-                CLog.i("Installing app " + currentApkName);
-                mPMHostUtils.installFile(getRepositoryTestAppFilePath(VERSIONED_APPS_DIRECTORY_NAME,
-                        currentApkName), true);
-                mPMHostUtils.waitForPackageManager();
-                assertTrue(mPMHostUtils.doesAppExistOnSDCard(VERSIONED_APPS_PKG));
-                assertTrue(mPMHostUtils.doesPackageExist(VERSIONED_APPS_PKG));
-            }
-        }
-        finally {
-            // cleanup test app
-            mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG);
-        }
-    }
-
-    /**
-     * Stress test to verify that an app can be installed, uninstalled, and
-     * reinstalled on SD many times.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testUninstallReinstallAppOnSDManyTimes() throws Exception {
-        CLog.i("Test updating an app on the SD card stays on the SD card");
-        // cleanup test app just in case it was already exists
-        mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
-        for (int i = 0; i < mIterationCount; ++i) {
-            CLog.i("Installing app %s (%d)", EXTERNAL_LOC_PKG, i);
-            try {
-                // install the app
-                mPMHostUtils.installFile(getRepositoryTestAppFilePath(MISC_APPS_DIRECTORY_NAME,
-                        EXTERNAL_LOC_APK), false);
-                mPMHostUtils.waitForPackageManager();
-                assertTrue(mPMHostUtils.doesAppExistOnSDCard(EXTERNAL_LOC_PKG));
-                assertTrue(mPMHostUtils.doesPackageExist(EXTERNAL_LOC_PKG));
-            }
-            finally {
-                // now uninstall the app
-                CLog.i("Uninstalling app %s (%d)", EXTERNAL_LOC_PKG, i);
-                mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
-            }
-        }
-    }
-
-    /**
-     * Stress test to verify that we can install, 20 large apps (>1mb each)
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallManyLargeAppsOnSD() throws Exception {
-        CLog.i("Test installing %d large apps onto the sd card", LARGE_APPS.length);
-        try {
-            // Install all the large apps
-            for (int i = 0; i < LARGE_APPS.length; ++i) {
-                String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()];
-                String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()];
-                // cleanup test app just in case it already exists
-                mPMHostUtils.uninstallApp(pkgName);
-                CLog.i("Installing app " + apkName);
-                // install the app
-                mPMHostUtils.installFile(getRepositoryTestAppFilePath(LARGE_APPS_DIRECTORY_NAME,
-                        apkName), false);
-                mPMHostUtils.waitForPackageManager();
-                assertTrue(mPMHostUtils.doesAppExistOnSDCard(pkgName));
-                assertTrue(mPMHostUtils.doesPackageExist(pkgName));
-            }
-        }
-        finally {
-            // Cleanup - ensure we uninstall all large apps if they were installed
-            for (int i = 0; i < LARGE_APPS.length; ++i) {
-                String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()];
-                String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()];
-                CLog.i("Uninstalling app " + apkName);
-                // cleanup test app just in case it was accidently installed
-                mPMHostUtils.uninstallApp(pkgName);
-                assertFalse(mPMHostUtils.doesAppExistOnSDCard(pkgName));
-            }
-        }
-    }
-
-    /**
-     * Stress test to verify that we can install many small apps onto SD.
-     * <p/>
-     * Assumes adb is running as root in device under test.
-     */
-    public void testInstallManyAppsOnSD() throws Exception {
-        CLog.i("Test installing %d small apps onto SD", MANY_APPS_END);
-        try {
-            for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) {
-                String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i);
-                // cleanup test app just in case it already exists
-                mPMHostUtils.uninstallApp(currentPkgName);
-                String currentApkName = String.format("%s%d.apk", MANY_APPS_APK_PREFIX, i);
-                CLog.i("Installing app " + currentApkName);
-                mPMHostUtils.installFile(getRepositoryTestAppFilePath(MANY_APPS_DIRECTORY_NAME,
-                        currentApkName), true);
-                mPMHostUtils.waitForPackageManager();
-                assertTrue(mPMHostUtils.doesAppExistOnSDCard(currentPkgName));
-                assertTrue(mPMHostUtils.doesPackageExist(currentPkgName));
-            }
-        }
-        finally {
-            for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) {
-                String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i);
-                // cleanup test app
-                mPMHostUtils.uninstallApp(currentPkgName);
-            }
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PreloadedClassesTest.java b/prod-tests/src/com/android/framework/tests/PreloadedClassesTest.java
deleted file mode 100644
index 04ab7b7..0000000
--- a/prod-tests/src/com/android/framework/tests/PreloadedClassesTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Runs a series of automated use cases and collects loaded class information in order to generate
- * a list of preloaded classes based on the input thresholds.
- */
-public class PreloadedClassesTest implements IRemoteTest, IDeviceTest, IBuildReceiver {
-    private static final String JUNIT_RUNNER = "android.support.test.runner.AndroidJUnitRunner";
-    // Preload tool commands
-    private static final String TOOL_CMD = "java -cp %s com.android.preload.Main --seq %s %s";
-    private static final String SCAN_ALL_CMD = "scan-all";
-    private static final String COMPUTE_CMD = "comp %d %s";
-    private static final String EXPORT_CMD = "export %s";
-    private static final String IMPORT_CMD = "import %s";
-    // Large, common timeouts
-    private static final long SCAN_TIMEOUT_MS = 5 * 60 * 1000;
-    private static final long COMPUTE_TIMEOUT_MS = 60 * 1000;
-
-    @Option(name = "package",
-            description = "Instrumentation package for use case automation.",
-            mandatory = true)
-    private String mPackage = null;
-
-    @Option(name = "test-case",
-            description = "List of use cases to exercise from the package.",
-            mandatory = true)
-    private List<String> mTestCases = new ArrayList<>();
-
-    @Option(name = "preload-tool", description = "Overridden location of the preload JAR file.")
-    private String mPreloadToolJarPath = null;
-
-    @Option(name = "threshold",
-            description = "List of thresholds for computing preloaded classes.",
-            mandatory = true)
-    private List<String> mThresholds = new ArrayList<>();
-
-    @Option(name = "quit-on-error",
-            description = "Quits if errors are encountered anywhere in the process.",
-            mandatory = false)
-    private boolean mQuitOnError = false;
-
-    private ITestDevice mDevice;
-    private IBuildInfo mBuildInfo;
-    private List<File> mExportFiles = new ArrayList<>();
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // Download preload tool, if not supplied
-        if (mPreloadToolJarPath == null) {
-            File preload = mBuildInfo.getFile("preload2.jar");
-            if (preload != null && preload.exists()) {
-                mPreloadToolJarPath = preload.getAbsolutePath();
-            } else {
-                CLog.e("Unable to find the preload tool.");
-            }
-        } else {
-            CLog.v("Using alternative preload tool path, %s", mPreloadToolJarPath);
-        }
-
-        IRemoteAndroidTestRunner runner =
-                new RemoteAndroidTestRunner(mPackage, JUNIT_RUNNER, getDevice().getIDevice());
-
-        for (String testCaseIdentifier : mTestCases) {
-            // Run an individual use case
-            runner.addInstrumentationArg("class", testCaseIdentifier);
-            getDevice().runInstrumentationTests(runner, listener);
-            // Scan loaded classes and export
-            File outfile = scanAndExportClasses();
-            if (outfile != null) {
-                mExportFiles.add(outfile);
-            } else {
-                String msg = String.format("Failed to find outfile after %s", testCaseIdentifier);
-                if (mQuitOnError) {
-                    throw new RuntimeException(msg);
-                } else {
-                    CLog.e(msg + ". Continuing anyway...");
-                }
-            }
-        }
-
-        try {
-            // Consider each threshold input
-            for (String thresholdStr : mThresholds) {
-                int threshold = 0;
-                try {
-                    threshold = Integer.parseInt(thresholdStr);
-                } catch (NumberFormatException e) {
-                    if (mQuitOnError) {
-                        throw e;
-                    } else {
-                        CLog.e("Failed to parse threshold: %s", thresholdStr);
-                        CLog.e(e);
-                        continue;
-                    }
-                }
-                // Generate the corresponding preloaded classes
-                File classes = writePreloadedClasses(threshold);
-                if (classes != null) {
-                    try (FileInputStreamSource stream = new FileInputStreamSource(classes)) {
-                        String name = String.format("preloaded-classes-threshold-%s", thresholdStr);
-                        listener.testLog(name, LogDataType.TEXT, stream);
-                    }
-                    // Clean up after uploading
-                    FileUtil.deleteFile(classes);
-                } else {
-                    String msg = String.format(
-                            "Failed to generate classes file for threshold, %s", thresholdStr);
-                    if (mQuitOnError) {
-                        throw new RuntimeException(msg);
-                    } else {
-                        CLog.e(msg + ". Continuing anyway...");
-                    }
-                }
-            }
-        } finally {
-            // Clean up temporary export files.
-            for (File f : mExportFiles) {
-                FileUtil.deleteFile(f);
-            }
-        }
-    }
-
-    /**
-     * Calls the preload tool to pull and scan heap profiles and to generate and export the list of
-     * loaded Java classes.
-     * @return {@link File} containing the loaded Java classes
-     */
-    private File scanAndExportClasses() {
-        File temp = null;
-        try {
-            temp = FileUtil.createTempFile("scanned", ".txt");
-        } catch (IOException e) {
-            CLog.e("Failed while creating temp file.");
-            CLog.e(e);
-            return null;
-        }
-        // Construct the command
-        String exportCmd = String.format(EXPORT_CMD, temp.getAbsolutePath());
-        String actionCmd = String.format("%s %s", SCAN_ALL_CMD, exportCmd);
-        String[] fullCmd = constructPreloadCommand(actionCmd);
-        CommandResult result = RunUtil.getDefault().runTimedCmd(SCAN_TIMEOUT_MS, fullCmd);
-        if (CommandStatus.SUCCESS.equals(result.getStatus())) {
-            return temp;
-        } else {
-            // Clean up the temp file
-            FileUtil.deleteFile(temp);
-            // Log and return the failure
-            CLog.e("Error scanning: %s", result.getStderr());
-            return null;
-        }
-    }
-
-    /**
-     * Calls the preload tool to import the previously exported files and to generate the list of
-     * preloaded classes based on the threshold input.
-     * @return {@link File} containing the generated list of preloaded classes
-     */
-    private File writePreloadedClasses(int threshold) {
-        File temp = null;
-        try {
-            temp = FileUtil.createTempFile("preloaded-classes", ".txt");
-        } catch (IOException e) {
-            CLog.e("Failed while creating temp file.");
-            CLog.e(e);
-            return null;
-        }
-        // Construct the command
-        String actionCmd = "";
-        for (File f : mExportFiles) {
-            String importCmd = String.format(IMPORT_CMD, f.getAbsolutePath());
-            actionCmd += importCmd + " ";
-        }
-        actionCmd += String.format(COMPUTE_CMD, threshold, temp.getAbsolutePath());
-        String[] fullCmd = constructPreloadCommand(actionCmd);
-        CommandResult result = RunUtil.getDefault().runTimedCmd(COMPUTE_TIMEOUT_MS, fullCmd);
-        if (CommandStatus.SUCCESS.equals(result.getStatus())) {
-            return temp;
-        } else {
-            // Clean up the temp file
-            FileUtil.deleteFile(temp);
-            // Log and return the failure
-            CLog.e("Error computing classes: %s", result.getStderr());
-            return null;
-        }
-    }
-
-    private String[] constructPreloadCommand(String command) {
-        return String.format(TOOL_CMD, mPreloadToolJarPath, getDevice().getSerialNumber(), command)
-                .split(" ");
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuildInfo = buildInfo;
-    }
-}
diff --git a/prod-tests/src/com/android/framework/tests/TestDirForwarder.java b/prod-tests/src/com/android/framework/tests/TestDirForwarder.java
deleted file mode 100644
index 379969a..0000000
--- a/prod-tests/src/com/android/framework/tests/TestDirForwarder.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.framework.tests;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-/**
- * A ITargetPreparer that forwards the location of the tests/data/app dir from the {@link
- * IDeviceBuildInfo} as an {@link Option}.
- */
-public class TestDirForwarder extends BaseTargetPreparer implements IConfigurationReceiver {
-
-    private IConfiguration mConfig = null;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
-            BuildError, DeviceNotAvailableException {
-        if (!(buildInfo instanceof IDeviceBuildInfo)) {
-            throw new IllegalArgumentException("buildInfo is not a IDeviceBuildInfo");
-        }
-        if (mConfig == null) {
-            // should never happen
-            throw new IllegalArgumentException("missing config");
-        }
-        IDeviceBuildInfo deviceBuild = (IDeviceBuildInfo)buildInfo;
-        File testAppDir = FileUtil.getFileForPath(deviceBuild.getTestsDir(), "DATA", "app");
-        // option with name test-app-path must exist!
-        try {
-            mConfig.injectOptionValue("test-app-path", testAppDir.getAbsolutePath());
-        } catch (ConfigurationException e) {
-            throw new TargetSetupError("Mis-configuration: no object which consumes test-app-path "
-                    + "option", e, device.getDeviceDescriptor());
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setConfiguration(IConfiguration config) {
-        mConfig = config;
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/FlatlandTest.java b/prod-tests/src/com/android/graphics/tests/FlatlandTest.java
deleted file mode 100644
index 5baa9e6..0000000
--- a/prod-tests/src/com/android/graphics/tests/FlatlandTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.graphics.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.CollectingOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.AbiFormatter;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test Runner for graphics Flatland Benchmark test.
- * <p>
- * Flatland test is a benchmark for measuring GPU performance in various 2D UI rendering and
- * window composition scenarios.
- * <p>
- * Since it is measuring the hardware performance, the test should be executed in
- * as consistent and static an environment as possible.
- * <ul>
- * <li>The display should be turned off and background service should be stopped before
- * running the benchmark. Running 'adb shell stop' is probably sufficient for this,
- * but if there are device specific background services that consume
- * much CPU cycles, memory bandwidth, or might otherwise interfere with GPU rendering,
- * those should be stopped as well
- * <li>All relevant hardware clocks should be locked at particular frequency when running the test.
- * </ul>
- * <p>
- * If running the benchmark with clocks locked causes thermal throttling, set option "--sleep-time"
- * to 10 to 50 (ms) to insert sleep between each benchmark sample run.
- * <p>
- * Output interpretation:
- * For each test case, the expected time in milliseconds that a single frame of the scenario
- * takes to complete will be printed out. Four types of values could displayed:
- * <ul>
- * <li>fast - frames of the scenarios are completed too fast to be reliably benchmarked. This
- * corresponds to frame time less than 3 ms. The scenario was skipped. "0" will be posted into
- * the dashboard.
- * <li>slow - frame time is too long, normally orver 50 ms. The scenario was skipped. "1000" will
- * be posted into the dashboard.
- * <li>varies - frame time was not stable. rerun the test to get a stable results. If that results
- * show repeatedly, something is wrong with the environment, signal to file a bug.
- * <li>decimal number - frame time for the scenarios are measured.
- * </ul>
- */
-public class FlatlandTest implements IDeviceTest, IRemoteTest {
-
-    private static final long SHELL_TIMEOUT = 30*60*1000;
-    private static final String COMMAND = "flatland|#ABI32#|";
-    private static final String FIRST_LINE = "cmdline:";
-    private static final String TITLE = "Scenario";
-    private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-    private static final String RESULT_FAST = "fast";
-    private static final String RESULT_SLOW = "slow";
-    private static final String RESULT_VARIES = "varies";
-
-    private ITestDevice mTestDevice = null;
-    // HashMap to store results for
-    public Map<String, String> mResultMap = new HashMap<String, String>();
-
-    @Option(name = "ru-key", description = "Reporting unit key to use when posting results")
-    private String mRuKey = "flatland";
-
-    @Option(name = "run-path",
-            description = "path for the binary")
-    private String mRunPath = "/data/local/tmp/";
-
-    @Option(name = "sleep-time",
-            description = "sleep for N ms between samples, set to 10 - 50 ms if the locked CPU"
-                    + " frequency causes thermal throttle.")
-    private int mSleepTime = 50;
-
-    @Option(name = "schema-map",
-            description = "map a test case name to a schema key")
-    private Map<String, String> mSchemaMap = new HashMap<String, String>();
-
-    @Option(name = AbiFormatter.FORCE_ABI_STRING,
-            description = AbiFormatter.FORCE_ABI_DESCRIPTION,
-            importance = Importance.IF_UNSET)
-    private String mForceAbi = null;
-
-    @Override
-    public void setDevice(ITestDevice testDevice) {
-        mTestDevice = testDevice;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    @Override
-    public void run(ITestInvocationListener standardListener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mRunPath);
-        RunUtil.getDefault().sleep(START_TIMER);
-
-        // execute test
-        StringBuilder cmd = new StringBuilder();
-        cmd.append(mRunPath);
-        cmd.append(COMMAND);
-        if (mSleepTime > 0) {
-            cmd.append(" -s ");
-            cmd.append(mSleepTime);
-        }
-        standardListener.testRunStarted(mRuKey, 1);
-        long start = System.currentTimeMillis();
-        CollectingOutputReceiver receiver = new CollectingOutputReceiver();
-        mTestDevice.executeShellCommand(AbiFormatter.formatCmdForAbi(cmd.toString(), mForceAbi),
-                receiver, SHELL_TIMEOUT, TimeUnit.MILLISECONDS, 2);
-        String result = receiver.getOutput();
-        if (result == null) {
-            CLog.v("no test results returned. Test failed?");
-            return;
-        }
-        // parse results and report metrics
-        parseResult(result);
-        standardListener.testRunEnded(
-                (System.currentTimeMillis() - start), TfMetricProtoUtil.upgradeConvert(mResultMap));
-    }
-
-    /**
-     * Parse results returned from running the benchmark
-     */
-    public void parseResult(String result) {
-        String[] lines = result.split(System.getProperty("line.separator"));
-        if (lines.length <= 0) {
-            return;
-        }
-        for (int i = 0; i < lines.length; i++) {
-            if (!lines[i].contains(FIRST_LINE) && !(lines[i].contains(TITLE))) {
-                // skip the first two lines
-                String[] items = lines[i].trim().split("\\|");
-                if (items.length == 3) {
-                    String schemaKey = String.format("%s %s", items[0].trim(), items[1].trim());
-                    if (mSchemaMap.get(schemaKey) != null) {
-                        // get the mapped schema key if there is any
-                        schemaKey = mSchemaMap.get(schemaKey);
-                    }
-                    String renderTime = items[2].trim();
-                    if (renderTime != null) {
-                        if (renderTime.equals(RESULT_FAST)) {
-                            mResultMap.put(schemaKey, "0");
-                        } else if (renderTime.equals(RESULT_SLOW)) {
-                            mResultMap.put(schemaKey, "1000");
-                        } else if (renderTime.equals(RESULT_VARIES)){
-                            mResultMap.put(schemaKey, "-1");
-                        } else {
-                            mResultMap.put(schemaKey, renderTime);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/FlatlandTestFuncTest.java b/prod-tests/src/com/android/graphics/tests/FlatlandTestFuncTest.java
deleted file mode 100644
index bd3c08d..0000000
--- a/prod-tests/src/com/android/graphics/tests/FlatlandTestFuncTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.graphics.tests;
-
-import com.android.tradefed.log.LogUtil.CLog;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.util.Map;
-
-public class FlatlandTestFuncTest extends TestCase {
-
-    private final String output = " cmdline: /data/local/tmp/flatland\n" +
-            "               Scenario               | Resolution  | Time (ms)\n" +
-            " 16:10 Single Static Window           | 1280 x  800 |   fast\n" +
-            " 16:10 Single Static Window           | 1920 x 1200 |  3.136\n" +
-            " 16:10 Single Static Window           | 2560 x 1600 |  5.524\n" +
-            " 16:10 Single Static Window           | 3840 x 2400 | 11.841\n" +
-            " 4:3 Single Static Window             | 2048 x 1536 |  4.292\n" +
-            " 16:10 App -> Home Transition         | 1280 x  800 |  varies\n" +
-            " 16:10 App -> Home Transition         | 1920 x 1200 |  5.724\n" +
-            " 16:10 App -> Home Transition         | 2560 x 1600 | 10.033\n" +
-            " 16:10 App -> Home Transition         | 3840 x 2400 | 22.034\n" +
-            " 4:3 App -> Home Transition           | 2048 x 1536 |  8.003\n" +
-            " 16:10 SurfaceView -> Home Transition | 1280 x  800 |   slow\n" +
-            " 16:10 SurfaceView -> Home Transition | 1920 x 1200 |  7.023\n" +
-            " 16:10 SurfaceView -> Home Transition | 2560 x 1600 | 12.337\n" +
-            " 16:10 SurfaceView -> Home Transition | 3840 x 2400 | 27.283\n" +
-            " 4:3 SurfaceView -> Home Transition   | 2048 x 1536 |  9.918\n";
-
-    public void testPraseResults() throws Exception {
-        FlatlandTest ft = new FlatlandTest();
-        ft.parseResult(output);
-        // "0" represents a "fast" result
-        String t = ft.mResultMap.get("16:10 Single Static Window 1280 x  800");
-        Assert.assertTrue(t.equals("0"));
-
-        t = ft.mResultMap.get("16:10 Single Static Window 1920 x 1200");
-        Assert.assertTrue(t.equals("3.136"));
-
-        t = ft.mResultMap.get("16:10 App -> Home Transition 1280 x  800");
-        Assert.assertTrue(t.equals("-1"));
-
-        t = ft.mResultMap.get("16:10 SurfaceView -> Home Transition 1280 x  800");
-        Assert.assertTrue(t.equals("1000"));
-
-        for(Map.Entry<String, String> entry: ft.mResultMap.entrySet()) {
-            CLog.e("key:%s, value:%s", entry.getKey(), entry.getValue());
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/ImageProcessingTest.java b/prod-tests/src/com/android/graphics/tests/ImageProcessingTest.java
deleted file mode 100644
index 58e2ad7..0000000
--- a/prod-tests/src/com/android/graphics/tests/ImageProcessingTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.graphics.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Run the ImageProcessing test. The test provides benchmark for image processing
- * in Android System.
- */
-public class ImageProcessingTest implements IDeviceTest, IRemoteTest {
-
-    private ITestDevice mTestDevice = null;
-
-    // Define instrumentation test package and runner.
-    private static final String TEST_PACKAGE_NAME = "com.android.rs.image";
-    private static final String TEST_RUNNER_NAME = ".ImageProcessingTestRunner";
-    private static final String TEST_CLASS = "com.android.rs.image.ImageProcessingTest";
-    private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
-    // Define keys for data posting
-    private static final String TEST_RUN_NAME = "graphics_image_processing";
-    private static final String BENCHMARK_KEY = "Benchmark";
-    private static final String TEST_NAME_KEY = "Testname";
-
-    //Max test timeout - 30 mins
-    private static final int MAX_TEST_TIMEOUT = 30 * 60 * 1000;
-
-    /**
-     * Run the ImageProcessing benchmark test, parse test results.
-     */
-    @Override
-    public void run(ITestInvocationListener standardListener)
-            throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        // Start the test after device is fully booted and stable
-        // FIXME: add option in TF to wait until device is booted and stable
-        RunUtil.getDefault().sleep(START_TIMER);
-
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
-                TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
-        runner.setClassName(TEST_CLASS);
-        runner.setMaxTimeToOutputResponse(MAX_TEST_TIMEOUT, TimeUnit.MILLISECONDS);
-        // Add bugreport listener for failed test
-        BugreportCollector bugListener = new
-            BugreportCollector(standardListener, mTestDevice);
-        bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
-        bugListener.setDescriptiveName(TEST_CLASS);
-
-        // Add collecting listener for test results collecting
-        CollectingTestListener collectListener = new CollectingTestListener();
-        mTestDevice.runInstrumentationTests(runner, collectListener, bugListener, standardListener);
-
-        // Capture a bugreport after the test
-        try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
-            standardListener.testLog("bugreport.txt", LogDataType.BUGREPORT, bugreport);
-        }
-
-        // Collect test metrics from the instrumentation test output.
-        Map<String, String> resultMetrics = new HashMap<String, String>();
-        Collection<TestResult> testRunResults =
-                collectListener.getCurrentRunResults().getTestResults().values();
-
-        if (testRunResults != null) {
-            for (TestResult testCaseResult: testRunResults) {
-                Map<String, String> testMetrics = testCaseResult.getMetrics();
-                // Each test metrics includes the following:
-                // Testname=LEVELS_VEC3_FULL
-                // Benchmark=50.171757
-                // Iterations=5
-                if (testMetrics != null) {
-                    String schemaKey = null;
-                    String schemaValue = null;
-                    for (Map.Entry<String, String> entry : testMetrics.entrySet()) {
-                        String entryKey = entry.getKey();
-                        String entryValue = entry.getValue();
-                        if (TEST_NAME_KEY.equals(entryKey)) {
-                            schemaKey = entryValue;
-                        } else if (BENCHMARK_KEY.equals(entryKey)) {
-                            schemaValue = entryValue;
-                        }
-                    }
-                    if (schemaKey != null && schemaValue != null) {
-                        CLog.v(String.format("%s: %s", schemaKey, schemaValue));
-                        resultMetrics.put(schemaKey, schemaValue);
-                    }
-                }
-            }
-            // Post results to the dashboard.
-            reportMetrics(TEST_RUN_NAME, standardListener, resultMetrics);
-        }
-    }
-
-    /**
-     * Report metrics by creating an empty test run to stick them in
-     */
-    private void reportMetrics(String metricsName, ITestInvocationListener listener,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics to %s: %s", metricsName, metrics);
-        listener.testRunStarted(metricsName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    @Override
-    public void setDevice(ITestDevice testDevice) {
-        mTestDevice = testDevice;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/OpenGlPerformanceTest.java b/prod-tests/src/com/android/graphics/tests/OpenGlPerformanceTest.java
deleted file mode 100644
index f847736..0000000
--- a/prod-tests/src/com/android/graphics/tests/OpenGlPerformanceTest.java
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.graphics.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RegexTrie;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.SimpleStats;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Run the OpenGl performance test. The OpenGl performance test benchmarks the performance
- * of RenderScript in Android System.
- */
-public class OpenGlPerformanceTest implements IDeviceTest, IRemoteTest {
-
-    private ITestDevice mTestDevice = null;
-
-    // Define instrumentation test package and runner.
-    private static final String TEST_PACKAGE_NAME = "com.android.perftest";
-    private static final String TEST_RUNNER_NAME = ".RsPerfTestRunner";
-    private static final String TEST_CLASS = "com.android.perftest.RsBenchTest";
-    private static final String OUTPUT_FILE = "rsbench_result";
-    private static final int TEST_TIMER = 60 * 60 *1000; // test running timer 1 hour
-    private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
-    private final RegexTrie<String> mPatternMap = new RegexTrie<>();
-    private Map<String, String[]> mKeyMap = new HashMap<>();
-    private Map<String, Double[]> mTestResults = new HashMap<>();
-
-    @Option(name="iterations",
-            description="The number of iterations to run benchmark tests.")
-    private int mIterations = 5;
-
-    public OpenGlPerformanceTest() {
-        // 3 tests, RenderScript Text Rendering
-        mPatternMap.put("text1", "Fill screen with text 1 time, (\\d+.\\d+),");
-        mPatternMap.put("text2", "Fill screen with text 3 times, (\\d+.\\d+),");
-        mPatternMap.put("text3", "Fill screen with text 5 times, (\\d+.\\d+),");
-        // 6 tests, RenderScript Texture Blending
-        mPatternMap.put("10xSingleTexture", "Fill screen 10x singletexture, (\\d+.\\d+),");
-        mPatternMap.put("Multitexture", "Fill screen 10x 3tex multitexture, (\\d+.\\d+),");
-        mPatternMap.put("BlendedSingleTexture", "Fill screen 10x blended singletexture, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("BlendedMultiTexture", "Fill screen 10x blended 3tex multitexture, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("3xModulatedBlendedSingletexture",
-                "Fill screen 3x modulate blended singletexture, (\\d+.\\d+),");
-        mPatternMap.put("1xModulatedBlendedSingletexture",
-                "Fill screen 1x modulate blended singletexture, (\\d+.\\d+),");
-        // 3 tests, RenderScript Mesh
-        mPatternMap.put("FullScreenMesh10", "Full screen mesh 10 by 10, (\\d+.\\d+),");
-        mPatternMap.put("FullScrennMesh100", "Full screen mesh 100 by 100, (\\d+.\\d+),");
-        mPatternMap.put("FullScreenMeshW4", "Full screen mesh W / 4 by H / 4, (\\d+.\\d+),");
-        // 6 tests, RenderScript Geo Test (light)
-        mPatternMap.put("GeoTestFlatColor1", "Geo test 25.6k flat color, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestFlatColor2", "Geo test 51.2k flat color, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestFlatColor3", "Geo test 204.8k small tries flat color, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("GeoTestSingleTexture1", "Geo test 25.6k single texture, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestSingleTexture2", "Geo test 51.2k single texture, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestSingleTexture3", "Geo test 204.8k small tries single texture, " +
-                "(\\d+.\\d+),");
-        // 9 tests, RenderScript Geo Test (heavy)
-        mPatternMap.put("GeoTestHeavyVertex1","Geo test 25.6k geo heavy vertex, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyVertex2","Geo test 51.2k geo heavy vertex, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyVertex3", "Geo test 204.8k geo raster load heavy vertex, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyFrag1", "Geo test 25.6k heavy fragment, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyFrag2", "Geo test 51.2k heavy fragment, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyFrag3", "Geo test 204.8k small tries heavy fragment, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyFragHeavyVertex1",
-                "Geo test 25.6k heavy fragment heavy vertex, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyFragHeavyVertex2",
-                "Geo test 51.2k heavy fragment heavy vertex, (\\d+.\\d+),");
-        mPatternMap.put("GeoTestHeavyFragHeavyVertex3",
-                "Geo test 204.8k small tries heavy fragment heavy vertex, (\\d+.\\d+),");
-        // 6 tests, RenerScript UI Test
-        mPatternMap.put("UITestWithIcon10by10", "UI test with icon display 10 by 10, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("UITestWithIcon100by100", "UI test with icon display 100 by 100, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("UITestWithImageText3", "UI test with image and text display 3 pages, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("UITestWithImageText5", "UI test with image and text display 5 pages, " +
-                "(\\d+.\\d+),");
-        mPatternMap.put("UITestListView", "UI test with list view, (\\d+.\\d+),");
-        mPatternMap.put("UITestLiveWallPaper", "UI test with live wallpaper, (\\d+.\\d+),");
-
-        mKeyMap.put("graphics_text", (new String[]{"text1", "text2", "text3"}));
-        mKeyMap.put("graphics_geo_light", (new String[]{"GeoTestFlatColor1", "GeoTestFlatColor2",
-                "GeoTestFlatColor3", "GeoTestSingleTexture1", "GeoTestSingleTexture2",
-                "GeoTestSingleTexture3"}));
-        mKeyMap.put("graphics_mesh", (new String[]{"FullScreenMesh10","FullScrennMesh100",
-                "FullScreenMeshW4"}));
-        mKeyMap.put("graphics_geo_heavy", (new String[]{"GeoTestHeavyVertex1",
-                "GeoTestHeavyVertex2", "GeoTestHeavyVertex3", "GeoTestHeavyFrag1",
-                "GeoTestHeavyFrag2", "GeoTestHeavyFrag3", "GeoTestHeavyFragHeavyVertex1",
-                "GeoTestHeavyFragHeavyVertex2", "GeoTestHeavyFragHeavyVertex3"}));
-        mKeyMap.put("graphics_texture", (new String[]{"10xSingleTexture", "Multitexture",
-                "BlendedSingleTexture", "BlendedMultiTexture", "3xModulatedBlendedSingletexture",
-                "1xModulatedBlendedSingletexture"}));
-        mKeyMap.put("graphics_ui", (new String[]{"UITestWithIcon10by10", "UITestWithIcon100by100",
-                "UITestWithImageText3", "UITestWithImageText5",
-                "UITestListView", "UITestLiveWallPaper"}));
-    }
-
-    /**
-     * Run the OpenGl benchmark tests
-     * Collect results and post results to test listener.
-     */
-    @Override
-    public void run(ITestInvocationListener standardListener)
-            throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        CLog.d("option values: mIterations(%d)", mIterations);
-
-        // Start the test after device is fully booted and stable
-        // FIXME: add option in TF to wait until device is booted and stable
-        RunUtil.getDefault().sleep(START_TIMER);
-
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
-                TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
-        runner.addInstrumentationArg("iterations", Integer.toString(mIterations));
-        runner.setClassName(TEST_CLASS);
-        runner.setMaxTimeToOutputResponse(TEST_TIMER, TimeUnit.MILLISECONDS);
-        // Add bugreport listener for failed test
-        BugreportCollector bugListener = new
-            BugreportCollector(standardListener, mTestDevice);
-        bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
-        bugListener.setDescriptiveName(TEST_CLASS);
-        mTestDevice.runInstrumentationTests(runner, bugListener);
-        logOutputFile(bugListener);
-        cleanOutputFiles();
-    }
-
-    /**
-     * Collect test results, report test results to test listener.
-     *
-     * @param listener
-     */
-    private void logOutputFile(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        // take a bug report, it is possible the system crashed
-        try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
-            listener.testLog("bugreport.txt", LogDataType.BUGREPORT, bugreport);
-        }
-        File resFile = null;
-        InputStreamSource outputSource = null;
-
-        for (int i = 0; i < mIterations; i++) {
-            // In each iteration, the test result is saved in a file rsbench_result*.csv
-            // e.g. for 10 iterations, results are in rsbench_result0.csv - rsbench_result9.csv
-            String outputFileName = String.format("%s%d.csv", OUTPUT_FILE, i);
-            CLog.d("pull result %s", outputFileName);
-
-            try {
-                resFile = mTestDevice.pullFileFromExternal(outputFileName);
-                if (resFile != null) {
-                    // Save a copy of the output file
-                    CLog.d("Sending %d byte file %s into the logosphere!",
-                            resFile.length(), resFile);
-                    outputSource = new FileInputStreamSource(resFile);
-                    listener.testLog(outputFileName, LogDataType.TEXT,
-                            outputSource);
-
-                    // Parse the results file and report results to dash board
-                    parseOutputFile(new FileInputStream(resFile), i);
-                } else {
-                    CLog.v("File %s doesn't exist or pulling the file failed", outputFileName);
-                }
-            } catch (IOException e) {
-                CLog.e("IOException while reading outputfile %s", outputFileName);
-            } finally {
-                FileUtil.deleteFile(resFile);
-                StreamUtil.cancel(outputSource);
-            }
-        }
-
-        printTestResults();
-        printKeyMap();
-
-        Map<String, String> runMetrics = new HashMap<>();
-
-        // After processing the output file, calculate average data and report data
-        // Find the RU-ITEM keys mapping for data posting
-        for (Map.Entry<String, String[]> entry: mKeyMap.entrySet()) {
-            String[] itemKeys = entry.getValue();
-
-            CLog.v("ru key: %s", entry.getKey());
-
-            for (String key: itemKeys) {
-                CLog.v("item key: %s", key);
-                if (mTestResults.get(key) == null) {
-                    continue;
-                }
-                SimpleStats simpleStats = new SimpleStats();
-                simpleStats.addAll(Arrays.asList(mTestResults.get(key)));
-                double averageFps = simpleStats.mean();
-                runMetrics.put(key, String.valueOf(averageFps));
-            }
-            reportMetrics(entry.getKey(), runMetrics, listener);
-            runMetrics.clear();
-        }
-    }
-
-    // Parse one result file and save test name and fps value
-    private void parseOutputFile(InputStream dataInputStream, int iterationId) {
-        try {
-            BufferedReader br= new BufferedReader(new InputStreamReader(dataInputStream));
-            String line = null;
-            while ((line = br.readLine()) != null) {
-                List<List<String>> capture = new ArrayList<>(1);
-                String key = mPatternMap.retrieve(capture, line);
-
-                if (key != null) {
-                    for (int i = 0; i < capture.size(); i++) {
-                        CLog.v("caputre.get[%d]: %s", i, capture.get(i).toString());
-                    }
-
-                    CLog.v("Retrieve key: %s, catpure: %s",
-                            key, capture.toString());
-
-                    // for value into the corresponding
-                    Double[] fps = mTestResults.get(key);
-                    if (fps == null) {
-                        fps = new Double[mIterations];
-                        CLog.v("initialize fps array");
-                    }
-                    fps[iterationId] = Double.parseDouble(capture.get(0).get(0));
-                    mTestResults.put(key, fps);
-                }
-            }
-        } catch (IOException e) {
-            CLog.e("IOException while reading from data stream");
-            CLog.e(e);
-            return;
-        }
-    }
-
-    private void printKeyMap() {
-        for (Map.Entry<String, String[]> entry:mKeyMap.entrySet()) {
-            CLog.v("ru key: %s", entry.getKey());
-            for (String itemKey: entry.getValue()) {
-                CLog.v("item key: %s", itemKey);
-            }
-        }
-    }
-
-    private void printTestResults() {
-        for (Map.Entry<String, Double[]> entry: mTestResults.entrySet()) {
-            CLog.v("key %s:", entry.getKey());
-            for (Double d: entry.getValue()) {
-                CLog.v("value: %f", d.doubleValue());
-            }
-        }
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in
-     * <p />
-     * Exposed for unit testing
-     */
-    protected void reportMetrics(String metricsName, Map<String, String> metrics,
-            ITestInvocationListener listener) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics to %s: %s", metricsName, metrics);
-        listener.testRunStarted(metricsName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    /**
-     * Clean up output files from the last test run
-     */
-    private void cleanOutputFiles() throws DeviceNotAvailableException {
-        for (int i = 0; i < mIterations; i++) {
-            String outputFileName = String.format("%s%d.csv", OUTPUT_FILE, i);
-            String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-            mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, outputFileName));
-        }
-    }
-
-    @Override
-    public void setDevice(ITestDevice testDevice) {
-        mTestDevice = testDevice;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    /**
-     * A meta-test to ensure the parsing working properly
-     * To run the meta test, run command
-     * tradefed.sh run singleCommand host -n --class
-     * 'com.android.graphics.tests.OpenGlPerformanceTest$MetaTest'
-     */
-    public static class MetaTest extends TestCase {
-        private OpenGlPerformanceTest mTestInstance = null;
-
-        private static String join(String... subStrings) {
-            StringBuilder sb = new StringBuilder();
-            for (String subString : subStrings) {
-                sb.append(subString);
-                sb.append("\n");
-            }
-            return sb.toString();
-        }
-
-        @Override
-        public void setUp() throws Exception {
-            mTestInstance = new OpenGlPerformanceTest() {};
-        }
-
-        // Make sure that parsing works
-        public void testParseOutputFile() throws Exception {
-            String output = join(
-                    "Fill screen with text 1 time, 97.65624,",
-                    "Fill screen with text 3 times, 36.576443,",
-                    "Fill screen with text 5 times, 12.382367,",
-                    "Fill screen 10x singletexture, 40.617382,",
-                    "Fill screen 10x 3tex multitexture, 28.32861,",
-                    "Fill screen 10x blended singletexture, 18.389112,",
-                    "Fill screen 10x blended 3tex multitexture, 5.4448433,",
-                    "Fill screen 3x modulate blended singletexture, 27.754648,",
-                    "Fill screen 1x modulate blended singletexture, 58.207214,",
-                    "Full screen mesh 10 by 10, 12.727504,",
-                    "Full screen mesh 100 by 100, 4.489136,",
-                    "Full screen mesh W / 4 by H / 4, 2.688967,",
-                    "Geo test 25.6k flat color, 31.259768,",
-                    "Geo test 51.2k flat color, 17.985611,",
-                    "Geo test 204.8k small tries flat color, 3.6580455,",
-                    "Geo test 25.6k single texture, 30.03905,",
-                    "Geo test 51.2k single texture, 14.622021,",
-                    "Geo test 204.8k small tries single texture, 3.7195458,",
-                    "Geo test 25.6k geo heavy vertex, 20.104542,",
-                    "Geo test 51.2k geo heavy vertex, 8.982305,",
-                    "Geo test 204.8k geo raster load heavy vertex, 2.9978714,",
-                    "Geo test 25.6k heavy fragment, 30.788176,",
-                    "Geo test 51.2k heavy fragment, 6.938662,",
-                    "Geo test 204.8k small tries heavy fragment, 2.9441204,",
-                    "Geo test 25.6k heavy fragment heavy vertex, 16.331863,",
-                    "Geo test 51.2k heavy fragment heavy vertex, 4.531243,",
-                    "Geo test 204.8k small tries heavy fragment heavy vertex, 1.6915321,",
-                    "UI test with icon display 10 by 10, 93.370674,",
-                    "UI test with icon display 100 by 100, 1.2948335,",
-                    "UI test with image and text display 3 pages, 99.50249,",
-                    "UI test with image and text display 5 pages, 77.57951,",
-                    "UI test with list view, 117.78562,",
-                    "UI test with live wallpaper, 38.197098,");
-
-            InputStream inputStream = new ByteArrayInputStream(output.getBytes());
-            mTestInstance.parseOutputFile(inputStream, 0);
-            assertNotNull(mTestInstance.mTestResults);
-
-            // 3 tests, RenderScript Text Rendering
-            assertEquals("97.65624", mTestInstance.mTestResults.get("text1")[0].toString());
-            assertEquals("36.576443", mTestInstance.mTestResults.get("text2")[0].toString());
-            assertEquals("12.382367", mTestInstance.mTestResults.get("text3")[0].toString());
-
-            // 6 tests, RenderScript Texture Blending
-            assertEquals("40.617382",
-                    mTestInstance.mTestResults.get("10xSingleTexture")[0].toString());
-            assertEquals("28.32861",
-                    mTestInstance.mTestResults.get("Multitexture")[0].toString());
-            assertEquals("18.389112",
-                    mTestInstance.mTestResults.get("BlendedSingleTexture")[0].toString());
-            assertEquals("5.4448433",
-                    mTestInstance.mTestResults.get("BlendedMultiTexture")[0].toString());
-            assertEquals("27.754648",
-                    mTestInstance.mTestResults.get(
-                            "3xModulatedBlendedSingletexture")[0].toString());
-            assertEquals("58.207214",
-                    mTestInstance.mTestResults.get(
-                            "1xModulatedBlendedSingletexture")[0].toString());
-
-            // 3 tests, RenderScript Mesh
-            assertEquals("12.727504",
-                    mTestInstance.mTestResults.get("FullScreenMesh10")[0].toString());
-            assertEquals("4.489136",
-                    mTestInstance.mTestResults.get("FullScrennMesh100")[0].toString());
-            assertEquals("2.688967",
-                    mTestInstance.mTestResults.get("FullScreenMeshW4")[0].toString());
-
-            // 6 tests, RenderScript Geo Test (light)
-            assertEquals("31.259768",
-                    mTestInstance.mTestResults.get("GeoTestFlatColor1")[0].toString());
-            assertEquals("17.985611",
-                    mTestInstance.mTestResults.get("GeoTestFlatColor2")[0].toString());
-            assertEquals("3.6580455",
-                    mTestInstance.mTestResults.get("GeoTestFlatColor3")[0].toString());
-            assertEquals("30.03905",
-                    mTestInstance.mTestResults.get("GeoTestSingleTexture1")[0].toString());
-            assertEquals("14.622021",
-                    mTestInstance.mTestResults.get("GeoTestSingleTexture2")[0].toString());
-            assertEquals("3.7195458",
-                    mTestInstance.mTestResults.get("GeoTestSingleTexture3")[0].toString());
-
-            // 9 tests, RenderScript Geo Test (heavy)
-            assertEquals("20.104542",
-                    mTestInstance.mTestResults.get("GeoTestHeavyVertex1")[0].toString());
-            assertEquals("8.982305",
-                    mTestInstance.mTestResults.get("GeoTestHeavyVertex2")[0].toString());
-            assertEquals("2.9978714",
-                    mTestInstance.mTestResults.get("GeoTestHeavyVertex3")[0].toString());
-            assertEquals("30.788176",
-                    mTestInstance.mTestResults.get("GeoTestHeavyFrag1")[0].toString());
-            assertEquals("6.938662",
-                    mTestInstance.mTestResults.get("GeoTestHeavyFrag2")[0].toString());
-            assertEquals("2.9441204",
-                    mTestInstance.mTestResults.get("GeoTestHeavyFrag3")[0].toString());
-            assertEquals("16.331863",
-                    mTestInstance.mTestResults.get("GeoTestHeavyFragHeavyVertex1")[0].toString());
-            assertEquals("4.531243",
-                    mTestInstance.mTestResults.get("GeoTestHeavyFragHeavyVertex2")[0].toString());
-            assertEquals("1.6915321",
-                    mTestInstance.mTestResults.get("GeoTestHeavyFragHeavyVertex3")[0].toString());
-
-            // 6 tests, RenerScript UI Test
-            assertEquals("93.370674",
-                    mTestInstance.mTestResults.get("UITestWithIcon10by10")[0].toString());
-            assertEquals("1.2948335",
-                    mTestInstance.mTestResults.get("UITestWithIcon100by100")[0].toString());
-            assertEquals("99.50249",
-                    mTestInstance.mTestResults.get("UITestWithImageText3")[0].toString());
-            assertEquals("77.57951",
-                    mTestInstance.mTestResults.get("UITestWithImageText5")[0].toString());
-            assertEquals("117.78562",
-                    mTestInstance.mTestResults.get("UITestListView")[0].toString());
-            assertEquals("38.197098",
-                    mTestInstance.mTestResults.get("UITestLiveWallPaper")[0].toString());
-        }
-
-        // Verify parsing two iterations
-        public void testParseTwoInputs() throws Exception {
-            String output1 = join(
-                    "Fill screen with text 1 time, 97.65624,",
-                    "Fill screen with text 3 times, 36.576443,",
-                    "UI test with live wallpaper, 38.197098,");
-            String output2 = join(
-                    "Fill screen with text 1 time, 97.56097,",
-                    "Fill screen with text 3 times, 36.75119,",
-                    "UI test with live wallpaper, 38.05175,");
-
-            InputStream inputStream = new ByteArrayInputStream(output1.getBytes());
-            mTestInstance.parseOutputFile(inputStream, 0);
-            //mTestInstance.printTestResults();
-            inputStream = new ByteArrayInputStream(output2.getBytes());
-            mTestInstance.parseOutputFile(inputStream, 1);
-            assertNotNull(mTestInstance.mTestResults);
-
-            assertEquals("97.65624", mTestInstance.mTestResults.get("text1")[0].toString());
-            assertEquals("36.576443", mTestInstance.mTestResults.get("text2")[0].toString());
-            assertEquals("38.197098",
-                    mTestInstance.mTestResults.get("UITestLiveWallPaper")[0].toString());
-
-            assertEquals("97.56097", mTestInstance.mTestResults.get("text1")[1].toString());
-            assertEquals("36.75119", mTestInstance.mTestResults.get("text2")[1].toString());
-            assertEquals("38.05175",
-                    mTestInstance.mTestResults.get("UITestLiveWallPaper")[1].toString());
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/SkiaTest.java b/prod-tests/src/com/android/graphics/tests/SkiaTest.java
deleted file mode 100644
index 9b647dd..0000000
--- a/prod-tests/src/com/android/graphics/tests/SkiaTest.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.graphics.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-
-import java.io.File;
-import java.util.HashMap;
-
-/**
- *  Test for running Skia native tests.
- *
- *  The test is not necessarily Skia specific, but it provides
- *  functionality that allows native Skia tests to be run.
- *
- *  Includes options to specify the Skia test app to run (inside
- *  nativetest directory), flags to pass to the test app, and a file
- *  to retrieve off the device after the test completes. (Skia test
- *  apps record their results to a json file, so retrieving this file
- *  allows us to view the results so long as the app completed.)
- */
-@OptionClass(alias = "skia_native_tests")
-public class SkiaTest implements IRemoteTest, IDeviceTest {
-    private ITestDevice mDevice;
-
-    static final String DEFAULT_NATIVETEST_PATH = "/data/nativetest";
-
-    @Option(name = "native-test-device-path",
-      description = "The path on the device where native tests are located.")
-    private String mNativeTestDevicePath = DEFAULT_NATIVETEST_PATH;
-
-    @Option(name = "skia-flags",
-        description = "Flags to pass to the skia program.")
-    private String mFlags = "";
-
-    @Option(name = "skia-app",
-        description = "Skia program to run.",
-        mandatory = true)
-    private String mSkiaApp = "";
-
-    @Option(name = "skia-json",
-        description = "Full path on device for json output file.")
-    private File mOutputFile = null;
-
-    @Option(name = "skia-pngs",
-        description = "Directory on device for holding png results for retrieval.")
-    private File mPngDir = null;
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        if (mDevice == null) {
-            throw new IllegalArgumentException("Device has not been set");
-        }
-
-        listener.testRunStarted(mSkiaApp, 1);
-        long start = System.currentTimeMillis();
-
-        // Native Skia tests are in nativeTestDirectory/mSkiaApp/mSkiaApp.
-        String fullPath = mNativeTestDevicePath + "/"
-                + mSkiaApp + "/" + mSkiaApp;
-        IFileEntry app = mDevice.getFileEntry(fullPath);
-        TestDescription testId = new TestDescription(mSkiaApp, "testFileExists");
-        listener.testStarted(testId);
-        if (app == null) {
-            CLog.w("Could not find test %s in %s!", fullPath, mDevice.getSerialNumber());
-            listener.testFailed(testId, "Device does not have " + fullPath);
-            listener.testEnded(testId, new HashMap<String, Metric>());
-        } else {
-            // The test for detecting the file has ended.
-            listener.testEnded(testId, new HashMap<String, Metric>());
-            prepareDevice();
-            runTest(app);
-            retrieveFiles(mSkiaApp, listener);
-        }
-
-        listener.testRunEnded(System.currentTimeMillis() - start, new HashMap<String, Metric>());
-    }
-
-    /**
-     *  Emulates running mkdirs on an ITestDevice.
-     *
-     *  Creates the directory named by dir *on device*, recursively creating missing parent
-     *  directories if necessary.
-     *
-     *  @param dir Directory to create.
-     */
-    private void mkdirs(File dir) throws DeviceNotAvailableException {
-        if (dir == null || mDevice.doesFileExist(dir.getPath())) {
-            return;
-        }
-
-        String dirName = dir.getPath();
-        CLog.v("creating folder '%s'", dirName);
-        mDevice.executeShellCommand("mkdir -p " + dirName);
-    }
-
-    /**
-     *  Do pre-test setup on the device.
-     *
-     *  Setup involves ensuring necessary directories exist and removing old
-     *  test result files.
-     */
-    private void prepareDevice() throws DeviceNotAvailableException {
-        if (mOutputFile != null) {
-            String path = mOutputFile.getPath();
-            if (mDevice.doesFileExist(path)) {
-                // Delete the file. We don't want to think this file from an
-                // earlier run represents this one.
-                CLog.v("Removing old file " + path);
-                mDevice.executeShellCommand("rm " + path);
-            } else {
-                // Ensure its containing folder exists.
-                mkdirs(mOutputFile.getParentFile());
-            }
-        }
-
-        if (mPngDir != null) {
-            String pngPath = mPngDir.getPath();
-            if (mDevice.doesFileExist(pngPath)) {
-                // Empty the old directory
-                mDevice.executeShellCommand("rm -rf " + pngPath + "/*");
-            } else {
-                mkdirs(mPngDir);
-            }
-        }
-    }
-
-    /**
-     * Retrieve a file from the device and upload it to the listener.
-     *
-     * <p>Each file for uploading is considered its own test, so we can track whether or not
-     * uploading succeeded.
-     *
-     * @param remoteFile File on the device.
-     * @param testIdClass String to be passed to TestDescription's constructor as className.
-     * @param testIdMethod String passed to TestDescription's constructor as testName.
-     * @param listener Listener for reporting test failure/success and uploading files.
-     * @param type LogDataType of the file being uploaded.
-     */
-    private void retrieveAndUploadFile(
-            File remoteFile,
-            String testIdClass,
-            String testIdMethod,
-            ITestInvocationListener listener,
-            LogDataType type)
-            throws DeviceNotAvailableException {
-        String remotePath = remoteFile.getPath();
-        CLog.v("adb pull %s (using pullFile)", remotePath);
-        File localFile = mDevice.pullFile(remotePath);
-
-        TestDescription testId = new TestDescription(testIdClass, testIdMethod);
-        listener.testStarted(testId);
-        if (localFile == null) {
-            listener.testFailed(testId, "Failed to pull " + remotePath);
-        } else {
-            CLog.v("pulled result file to " + localFile.getPath());
-            try (FileInputStreamSource source = new FileInputStreamSource(localFile)) {
-                // Use the original name, for clarity.
-                listener.testLog(remoteFile.getName(), type, source);
-            }
-            if (!localFile.delete()) {
-                CLog.w("Failed to delete temporary file %s", localFile.getPath());
-            }
-        }
-        listener.testEnded(testId, new HashMap<String, Metric>());
-    }
-
-    /**
-     *  Retrieve files from the device.
-     *
-     *  Report to the listener whether retrieving the files succeeded.
-     *
-     *  @param appName Name of the app.
-     *  @param listener Listener for reporting results of file retrieval.
-     */
-    private void retrieveFiles(String appName,
-            ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // FIXME: This could be achieved with DeviceFileReporter. Blocked on b/18408206.
-        if (mOutputFile != null) {
-            retrieveAndUploadFile(mOutputFile, appName, "outputJson", listener, LogDataType.TEXT);
-        }
-
-        if (mPngDir != null) {
-            String pngDir = mPngDir.getPath();
-            IFileEntry remotePngDir = mDevice.getFileEntry(pngDir);
-            for (IFileEntry pngFile : remotePngDir.getChildren(false)) {
-                if (pngFile.getName().endsWith("png")) {
-                    retrieveAndUploadFile(new File(pngFile.getFullPath()),
-                            "PngRetrieval", pngFile.getName(), listener, LogDataType.PNG);
-                }
-            }
-        }
-    }
-
-    /**
-     *  Run a test on a device.
-     *
-     *  @param app Test app to run.
-     */
-    private void runTest(IFileEntry app) throws DeviceNotAvailableException {
-        String fullPath = app.getFullEscapedPath();
-        // force file to be executable
-        mDevice.executeShellCommand(String.format("chmod 755 %s", fullPath));
-
-        // The device will not immediately capture logs in response to
-        // startLogcat. Instead, it delays 5 * 1000ms. See TestDevice.java
-        // mLogStartDelay. To ensure we see all the logs, sleep by the same
-        // amount.
-        mDevice.startLogcat();
-        RunUtil.getDefault().sleep(5 * 1000);
-
-        String cmd = fullPath + " " + mFlags;
-        CLog.v("Running '%s' on %s", cmd, mDevice.getSerialNumber());
-
-        mDevice.executeShellCommand("stop");
-        mDevice.executeShellCommand(cmd);
-        mDevice.executeShellCommand("start");
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/UiPerformanceTest.java b/prod-tests/src/com/android/graphics/tests/UiPerformanceTest.java
deleted file mode 100644
index 5ac9c83..0000000
--- a/prod-tests/src/com/android/graphics/tests/UiPerformanceTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.graphics.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Run UiPerformanceTest suite which measures the performance of
- * system operations and majors applications.
- */
-public class UiPerformanceTest implements IDeviceTest, IRemoteTest {
-    private ITestDevice mTestDevice = null;
-    // Define instrumentation test package and runner.
-    private static final String TEST_PACKAGE_NAME =
-            "com.android.testing.uiautomation.platform.uiperformance";
-    // TODO: Add TEST_CLASS_NAME later when different tests requiring
-    //       different configurations.
-    private static final String TEST_RUNNER_NAME =
-            "com.android.testing.uiautomation.UiAutomationTestRunner";
-    private static final String OUTPUT_FILE_NAME = "UiPerfTestsOutput.txt"; // output file
-    private static final String RAW_DATA_DIRECTORY = "UiPerformanceRawData"; // raw data directory
-
-    private static final String TEST_CASE_PREFIX = "test";
-    private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
-    private static final Pattern JANKINESS_PATTERN =
-            Pattern.compile("^number of jankiness: (\\d+)");
-    private static final Pattern MEDIAN_FRAME_LATENCY_PATTERN =
-            Pattern.compile("^median of frame latency: (\\d+)");
-    private static final Pattern FRAME_RATE_PATTERN =
-            Pattern.compile("^average frame rate: (\\d+\\.\\d+)");
-    private static final Pattern[] mPatterns = {
-        JANKINESS_PATTERN, FRAME_RATE_PATTERN, MEDIAN_FRAME_LATENCY_PATTERN
-    };
-    private static final String[] ITEM_KEYS = {"number_jankiness", "frame_rate", "frame_latency"};
-
-    @Override
-    public void setDevice(ITestDevice testDevice) {
-        mTestDevice = testDevice;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    private void setupDevice() throws DeviceNotAvailableException {
-        cleanOutputFiles();
-        String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        String rawFileDir = String.format("%s/%s", extStore, RAW_DATA_DIRECTORY);
-
-        if (!mTestDevice.doesFileExist(rawFileDir)) {
-            CLog.v(String.format("The raw directory %s doesn't exist.", RAW_DATA_DIRECTORY));
-            mTestDevice.executeShellCommand(String.format("mkdir \"%s\"", rawFileDir));
-        } else {
-            // remove files
-            mTestDevice.executeShellCommand(String.format("rm %s/*", rawFileDir));
-            CLog.v("remove files under the raw data directory");
-        }
-    }
-
-    /**
-     * Run UiPerformanceTests and parsing results from test output.
-     */
-    @Override
-    public void run(ITestInvocationListener standardListener)
-            throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        setupDevice();
-        // start the test until device is fully booted and stable
-        RunUtil.getDefault().sleep(START_TIMER);
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
-                TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
-
-        // Add bugreport listener for failed test
-        BugreportCollector bugListener = new
-            BugreportCollector(standardListener, mTestDevice);
-        bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
-        bugListener.setDescriptiveName(this.getClass().getName());
-        mTestDevice.runInstrumentationTests(runner, bugListener);
-        logOutputFile(bugListener);
-        pullRawDataFile(bugListener);
-        cleanOutputFiles();
-    }
-
-    private void pullRawDataFile(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        String rawFileDir = String.format("%s/%s", extStore, RAW_DATA_DIRECTORY);
-
-        String rawFileList =
-                mTestDevice.executeShellCommand(String.format("ls \"%s\"", rawFileDir));
-        String[] rawFileString = rawFileList.split("\r?\n");
-        File resFile = null;
-        InputStreamSource outputSource = null;
-        for (int i = 0; i < rawFileString.length; i++) {
-            CLog.v("file %d is:  \"%s\"", i, rawFileString[i]);
-            try {
-                resFile = mTestDevice.pullFileFromExternal(
-                        String.format("%s/%s", RAW_DATA_DIRECTORY, rawFileString[i]));
-                outputSource = new FileInputStreamSource(resFile, true /* delete */);
-                listener.testLog(rawFileString[i], LogDataType.TEXT, outputSource);
-            } finally {
-                StreamUtil.cancel(outputSource);
-            }
-        }
-    }
-
-
-    // Parse the output file
-    private void logOutputFile(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        // catch a bugreport after the test
-        try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
-            listener.testLog("bugreport", LogDataType.BUGREPORT, bugreport);
-        }
-
-        File resFile = null;
-        InputStreamSource outputSource = null;
-        Map<String, String> runMetrics = new HashMap<>();
-        BufferedReader br = null;
-        try {
-            resFile = mTestDevice.pullFileFromExternal(OUTPUT_FILE_NAME);
-            if (resFile == null) {
-                CLog.v("File %s doesn't exist or pulling the file failed");
-                return;
-            }
-            CLog.d("output file: %s", resFile.getPath());
-            // Save a copy of the output file
-            CLog.d("Sending %d byte file %s into the logosphere!",
-                    resFile.length(), resFile);
-            outputSource = new FileInputStreamSource(resFile);
-            listener.testLog(OUTPUT_FILE_NAME, LogDataType.TEXT, outputSource);
-
-            // Parse the results file
-            br = new BufferedReader(new FileReader(resFile));
-            String line = null;
-            String unitKey = null;
-            int size = mPatterns.length;
-            while ((line = br.readLine()) != null) {
-                if (line.startsWith(TEST_CASE_PREFIX)) {
-                    // report the previous test case results
-                    if (unitKey != null) {
-                        reportMetrics(unitKey, listener, runMetrics);
-                    }
-                    runMetrics.clear();
-                    // processing the next test case
-                    unitKey = line.trim();
-                    continue;
-                } else {
-                    for (int i = 0; i < size; i++) {
-                        Matcher match = mPatterns[i].matcher(line);
-                        if (match.matches()) {
-                            String value = match.group(1);
-                            runMetrics.put(ITEM_KEYS[i], value);
-                            break;
-                        }
-                    }
-                }
-            }
-            reportMetrics(unitKey, listener, runMetrics);
-        } catch (IOException e) {
-            CLog.e("IOException while reading outputfile %s", OUTPUT_FILE_NAME);
-        } finally {
-            FileUtil.deleteFile(resFile);
-            StreamUtil.cancel(outputSource);
-            StreamUtil.close(br);
-        }
-    }
-
-    // Report run metrics by creating an empty test run to stick them in
-    private void reportMetrics(String metricsName, ITestInvocationListener listener,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics to %s: %s", metricsName, metrics);
-        listener.testRunStarted(metricsName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    // clean up output file
-    private void cleanOutputFiles() throws DeviceNotAvailableException {
-        String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, OUTPUT_FILE_NAME));
-    }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/UserActionBenchmark.java b/prod-tests/src/com/android/graphics/tests/UserActionBenchmark.java
deleted file mode 100644
index 9448d99..0000000
--- a/prod-tests/src/com/android/graphics/tests/UserActionBenchmark.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.graphics.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.NullOutputReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Runs the user action framerate benchmark test. This test capture
- * use the scripted monkey to inject the keyevent to mimic the real
- * user action, capture the average framerate and save the result
- * file to the sdcard.
- * <p/>
- * Note that this test will not run properly unless /sdcard is mounted and
- * writable.
- */
-public class UserActionBenchmark implements IDeviceTest, IRemoteTest {
-    private static final String LOG_TAG = "UserActionBenchmark";
-
-    ITestDevice mTestDevice = null;
-
-    private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
-    @Option(name = "test-output-filename", description = "The test output filename.")
-    private String mDeviceTestOutputFilename = "avgFrameRateOut.txt";
-
-    // The time in ms to wait the scripted monkey finish.
-    private static final int CMD_TIMEOUT = 60 * 60 * 1000;
-
-    private static final Pattern AVERAGE_FPS = Pattern.compile("(.*):(\\d+.\\d+)");
-
-    @Option(name = "test-case", description = "The name of test-cases  to run. May be repeated.")
-    private Collection<String> mTestCases = new ArrayList<>();
-
-    @Option(name = "iteration", description = "Test run iteration")
-    private int mIteration = 1;
-
-    @Option(name = "throttle", description = "Scripted monkey throttle time")
-    private int mThrottle = 500; // in milliseconds
-
-    @Option(name = "script-path", description = "Test script path")
-    private String mScriptPath = "userActionFPSScript";
-
-    @Option(name = "test-label", description = "Test label")
-    private String mTestLabel = "UserActionFramerateBenchmark";
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-
-        // Start the test after device is fully booted and stable
-        // FIXME: add option in TF to wait until device is booted and stable
-        RunUtil.getDefault().sleep(START_TIMER);
-
-        String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        String scriptFullPath =
-            String.format("%s/%s/%s", extStore, mScriptPath, mTestDevice.getProductType());
-        for (String testCase : mTestCases) {
-            // Start the scripted monkey command
-            mTestDevice.executeShellCommand(String.format(
-                "monkey -f /%s/%s.txt --throttle %d %d", scriptFullPath,
-                testCase, mThrottle, mIteration), new NullOutputReceiver(),
-                CMD_TIMEOUT, TimeUnit.MILLISECONDS, 2);
-            logOutputFiles(listener);
-            cleanResultFile();
-        }
-    }
-
-    /**
-     * Clean up the test result file from test run
-     */
-    private void cleanResultFile() throws DeviceNotAvailableException {
-        String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore,
-                mDeviceTestOutputFilename));
-    }
-
-    /**
-     * Pull the output files from the device, add it to the logs, and also parse
-     * out the relevant test metrics and report them.
-     */
-    private void logOutputFiles(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        File outputFile = null;
-        InputStreamSource outputSource = null;
-        try {
-            outputFile = mTestDevice.pullFileFromExternal(mDeviceTestOutputFilename);
-
-            if (outputFile == null) {
-                return;
-            }
-
-            // Upload a verbatim copy of the output file
-            Log.d(LOG_TAG, String.format("Sending %d byte file %s into the logosphere!",
-                    outputFile.length(), outputFile));
-            outputSource = new FileInputStreamSource(outputFile);
-            listener.testLog(mDeviceTestOutputFilename, LogDataType.TEXT, outputSource);
-
-            // Parse the output file to upload aggregated metrics
-            parseOutputFile(new FileInputStream(outputFile), listener);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, String.format(
-                            "IOException while reading or parsing output file: %s", e));
-        } finally {
-            FileUtil.deleteFile(outputFile);
-            StreamUtil.cancel(outputSource);
-        }
-    }
-
-    /**
-     * Parse the test result, calculate the average and parse the metrics
-     * from the scripted monkey test output file
-     */
-    private void parseOutputFile(InputStream dataStream,
-            ITestInvocationListener listener) {
-
-        Map<String, String> runMetrics = new HashMap<>();
-
-        // try to parse it
-        String contents;
-        try {
-            contents = StreamUtil.getStringFromStream(dataStream);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, String.format(
-                    "Got IOException during test processing: %s", e));
-            return;
-        }
-
-        List<String> lines = Arrays.asList(contents.split("\n"));
-        String key = null;
-        float averageResult;
-        float totalResult = 0;
-        int counter = 0;
-
-        // collect the result and calculate the average
-        for (String line: lines) {
-            Matcher m = AVERAGE_FPS.matcher(line);
-            if (m.matches()) {
-                key = m.group(1);
-                totalResult += Float.parseFloat(m.group(2));
-                counter++;
-            }
-        }
-        averageResult = totalResult / counter;
-        Log.i(LOG_TAG, String.format("averageResult = %s\n", averageResult));
-        runMetrics.put(key, Float.toString(averageResult));
-        reportMetrics(listener, runMetrics);
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in
-     * <p />
-     * Exposed for unit testing
-     */
-    void reportMetrics(ITestInvocationListener listener, Map<String, String> metrics) {
-        Log.d(LOG_TAG, String.format("About to report metrics: %s", metrics));
-        listener.testRunStarted(mTestLabel, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-}
diff --git a/prod-tests/src/com/android/monkey/AnrReportGenerator.java b/prod-tests/src/com/android/monkey/AnrReportGenerator.java
deleted file mode 100644
index 68525c0..0000000
--- a/prod-tests/src/com/android/monkey/AnrReportGenerator.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.monkey;
-
-import com.android.tradefed.log.ITestLogger;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * A utility class that encapsulates details of calling post-processing scripts to generate monkey
- * ANR reports.
- */
-public class AnrReportGenerator {
-
-    private static final long REPORT_GENERATION_TIMEOUT = 30 * 1000; // 30s
-
-    private File mCachedMonkeyLog = null;
-    private File mCachedBugreport = null;
-
-    private final String mReportScriptPath;
-    private final String mReportBasePath;
-    private final String mReportUrlPrefix;
-    private final String mReportPath;
-    private final String mDeviceSerial;
-
-    private String mBuildId = null;
-    private String mBuildFlavor = null;
-
-    /**
-     * Constructs the instance with details of report script and output location information. See
-     * matching options on {@link MonkeyBase} for more info.
-     */
-    public AnrReportGenerator(String reportScriptPath, String reportBasePath,
-            String reportUrlPrefix, String reportPath,
-            String buildId, String buildFlavor, String deviceSerial) {
-        mReportScriptPath = reportScriptPath;
-        mReportBasePath = reportBasePath;
-        mReportUrlPrefix = reportUrlPrefix;
-        mReportPath = reportPath;
-        mBuildId = buildId;
-        mBuildFlavor = buildFlavor;
-        mDeviceSerial = deviceSerial;
-
-        if (mReportBasePath == null || mReportPath == null || mReportScriptPath == null
-                || mReportUrlPrefix == null) {
-            throw new IllegalArgumentException("ANR post-processing enabled but missing "
-                    + "required parameters!");
-        }
-    }
-
-    /**
-     * Return the storage sub path based on build info. The path will not include trailing path
-     * separator.
-     */
-    private String getPerBuildStoragePath() {
-        if (mBuildId == null) {
-            mBuildId = "-1";
-        }
-        if (mBuildFlavor == null) {
-            mBuildFlavor = "unknown_flavor";
-        }
-        return String.format("%s/%s", mBuildId, mBuildFlavor);
-    }
-
-    /**
-     * Sets bugreport information for ANR post-processing script
-     * @param bugreportStream
-     */
-    public void setBugReportInfo(InputStreamSource bugreportStream) throws IOException {
-        if (mCachedBugreport != null) {
-            CLog.w("A bugreport for this invocation already existed at %s, overriding anyways",
-                    mCachedBugreport.getAbsolutePath());
-        }
-        mCachedBugreport = FileUtil.createTempFile("monkey-anr-report-bugreport", ".txt");
-        FileUtil.writeToFile(bugreportStream.createInputStream(), mCachedBugreport);
-    }
-
-    /**
-     * Sets monkey log information for ANR post-processing script
-     * @param monkeyLogStream
-     */
-    public void setMonkeyLogInfo(InputStreamSource monkeyLogStream) throws IOException {
-        if (mCachedMonkeyLog != null) {
-            CLog.w("A monkey log for this invocation already existed at %s, overriding anyways",
-                    mCachedMonkeyLog.getAbsolutePath());
-        }
-        mCachedMonkeyLog = FileUtil.createTempFile("monkey-anr-report-monkey-log", ".txt");
-        FileUtil.writeToFile(monkeyLogStream.createInputStream(), mCachedMonkeyLog);
-    }
-
-    public boolean genereateAnrReport(ITestLogger logger) {
-        if (mCachedMonkeyLog == null || mCachedBugreport == null) {
-            CLog.w("Cannot generate report: bugreport or monkey log not populated yet.");
-            return false;
-        }
-        // generate monkey report and log it
-        File reportPath = new File(mReportBasePath,
-                String.format("%s/%s", mReportPath, getPerBuildStoragePath()));
-        if (reportPath.exists()) {
-            if (!reportPath.isDirectory()) {
-                CLog.w("The expected report storage path is not a directory: %s",
-                        reportPath.getAbsolutePath());
-                return false;
-            }
-        } else {
-            if (!reportPath.mkdirs()) {
-                CLog.w("Failed to create report storage directory: %s",
-                        reportPath.getAbsolutePath());
-                return false;
-            }
-        }
-        // now we should have the storage path, calculate the HTML report path
-        // HTML report file should be named as:
-        // monkey-anr-report-<device serial>-<random string>.html
-        // under the pre-constructed base report storage path
-        File htmlReport = null;
-        try {
-            htmlReport = FileUtil.createTempFile(
-                    String.format("monkey-anr-report-%s-", mDeviceSerial), ".html",
-                    reportPath);
-        } catch (IOException ioe) {
-            CLog.e("Error getting place holder file for HTML report.");
-            CLog.e(ioe);
-            return false;
-        }
-        // now ready to call the script
-        String htmlReportPath = htmlReport.getAbsolutePath();
-        String command[] = {
-                mReportScriptPath, "--monkey", mCachedMonkeyLog.getAbsolutePath(), "--html",
-                htmlReportPath, mCachedBugreport.getAbsolutePath()
-        };
-        CommandResult cr = RunUtil.getDefault().runTimedCmdSilently(REPORT_GENERATION_TIMEOUT,
-                command);
-        if (cr.getStatus() == CommandStatus.SUCCESS) {
-            // Test log the generated HTML report
-            try (InputStreamSource source = new FileInputStreamSource(htmlReport)) {
-                logger.testLog("monkey-anr-report", LogDataType.HTML, source);
-            }
-            // Clean up and declare success!
-            FileUtil.deleteFile(htmlReport);
-            return true;
-        } else {
-            CLog.w(cr.getStderr());
-            return false;
-        }
-    }
-
-    public void cleanTempFiles() {
-        FileUtil.deleteFile(mCachedBugreport);
-        FileUtil.deleteFile(mCachedMonkeyLog);
-    }
-}
diff --git a/prod-tests/src/com/android/monkey/AppPkgInjector.java b/prod-tests/src/com/android/monkey/AppPkgInjector.java
deleted file mode 100644
index 8250bc2..0000000
--- a/prod-tests/src/com/android/monkey/AppPkgInjector.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.monkey;
-
-import com.android.tradefed.build.IAppBuildInfo;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.VersionedFile;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.util.AaptParser;
-
-import org.junit.Assert;
-
-/**
- * A {@link ITargetPreparer} for {@link IAppBuildInfo}, that dynamically determines the app package
- * name given its apk file. This saves the user from having to manually specify the --package arg
- * when running monkey.
- *
- * <p>Requires that aapt is on current path.
- */
-public class AppPkgInjector extends BaseTargetPreparer implements IConfigurationReceiver {
-
-    @Option(name = "skip-injector", description = "Set to true if we should skip automatically " +
-            "adding all package names of installed packages. Default is false.")
-    private boolean mSkipInjecting = false;
-
-    private IConfiguration mConfig;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setConfiguration(IConfiguration configuration) {
-        mConfig = configuration;
-
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
-            BuildError, DeviceNotAvailableException {
-        if (mSkipInjecting) {
-            return;
-        }
-        Assert.assertNotNull(mConfig);
-        Assert.assertTrue("provided build is not a IAppBuildInfo",
-                buildInfo instanceof IAppBuildInfo);
-        IAppBuildInfo appBuild = (IAppBuildInfo)buildInfo;
-        for (VersionedFile apkFile : appBuild.getAppPackageFiles()) {
-            AaptParser aapt = AaptParser.parse(apkFile.getFile());
-            if (aapt == null) {
-                // throw a build error because typically aapt parse errors are issues with the apk
-                throw new BuildError(String.format("aapt parse of %s failed",
-                        apkFile.getFile().getAbsolutePath()), device.getDeviceDescriptor());
-            }
-            String pkgName = aapt.getPackageName();
-            if (pkgName == null) {
-                // this should never happen
-                throw new TargetSetupError(String.format("Failed to parse package name from %s",
-                        apkFile.getFile().getAbsolutePath()), device.getDeviceDescriptor());
-            }
-            try {
-                mConfig.injectOptionValue("package", pkgName);
-            } catch (ConfigurationException e) {
-                throw new TargetSetupError("Failed to inject --package option.", e,
-                        device.getDeviceDescriptor());
-            }
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyBase.java b/prod-tests/src/com/android/monkey/MonkeyBase.java
deleted file mode 100644
index 6b27bda..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyBase.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.monkey;
-
-import com.android.ddmlib.CollectingOutputReceiver;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.loganalysis.item.AnrItem;
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.MiscKernelLogItem;
-import com.android.loganalysis.item.MonkeyLogItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.loganalysis.parser.KernelLogParser;
-import com.android.loganalysis.parser.MonkeyLogParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.DeviceFileReporter;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IRetriableTest;
-import com.android.tradefed.util.ArrayUtil;
-import com.android.tradefed.util.Bugreport;
-import com.android.tradefed.util.CircularAtraceUtil;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Runner for stress tests which use the monkey command.
- */
-public class MonkeyBase implements IDeviceTest, IRemoteTest, IRetriableTest {
-
-    public static final String MONKEY_LOG_NAME = "monkey_log";
-    public static final String BUGREPORT_NAME = "bugreport";
-
-    /**
-     * Allow a 15 second buffer between the monkey run time and the delta uptime.
-     */
-    public static final long UPTIME_BUFFER = 15 * 1000;
-
-    private static final String DEVICE_WHITELIST_PATH = "/data/local/tmp/monkey_whitelist.txt";
-
-    /**
-     * am command template to launch app intent with same action, category and task flags as if user
-     * started it from the app's launcher icon
-     */
-    private static final String LAUNCH_APP_CMD = "am start -W -n '%s' " +
-            "-a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000";
-
-    private static final String NULL_UPTIME = "0.00";
-
-    /**
-     * Helper to run a monkey command with an absolute timeout.
-     * <p>
-     * This is used so that the command can be stopped after a set timeout, since the timeout that
-     * {@link ITestDevice#executeShellCommand(String, IShellOutputReceiver, long, TimeUnit, int)}
-     * takes applies to the time between output, not the overall time of the command.
-     * </p>
-     */
-    private class CommandHelper {
-        private DeviceNotAvailableException mException = null;
-        private String mOutput = null;
-
-        public void runCommand(final ITestDevice device, final String command, long timeout)
-                throws DeviceNotAvailableException {
-            final CollectingOutputReceiver receiver = new CollectingOutputReceiver();
-            Thread t = new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        device.executeShellCommand(command, receiver);
-                    } catch (DeviceNotAvailableException e) {
-                        mException = e;
-                    }
-                }
-            };
-
-            t.start();
-
-            try {
-                t.join(timeout);
-            } catch (InterruptedException e) {
-                // Ignore and log.  The thread should terminate once receiver.cancel() is called.
-                CLog.e("Thread was interrupted while running %s", command);
-            }
-
-            mOutput = receiver.getOutput();
-            receiver.cancel();
-
-            if (mException != null) {
-                throw mException;
-            }
-        }
-
-        public String getOutput() {
-            return mOutput;
-        }
-    }
-
-    @Option(name = "package", description = "Package name to send events to.  May be repeated.")
-    private Collection<String> mPackages = new LinkedList<>();
-
-    @Option(name = "exclude-package", description = "Substring of package names to exclude from " +
-            "the package list. May be repeated.", importance = Importance.IF_UNSET)
-    private Collection<String> mExcludePackages = new HashSet<>();
-
-    @Option(name = "category", description = "App Category. May be repeated.")
-    private Collection<String> mCategories = new LinkedList<>();
-
-    @Option(name = "option", description = "Option to pass to monkey command. May be repeated.")
-    private Collection<String> mOptions = new LinkedList<>();
-
-    @Option(name = "launch-extras-int", description = "Launch int extras. May be repeated. " +
-            "Format: --launch-extras-i key value. Note: this will be applied to all components.")
-    private Map<String, Integer> mIntegerExtras = new HashMap<>();
-
-    @Option(name = "launch-extras-str", description = "Launch string extras. May be repeated. " +
-            "Format: --launch-extras-s key value. Note: this will be applied to all components.")
-    private Map<String, String> mStringExtras = new HashMap<>();
-
-    @Option(name = "target-count", description = "Target number of events to send.",
-            importance = Importance.ALWAYS)
-    private int mTargetCount = 125000;
-
-    @Option(name = "random-seed", description = "Random seed to use for the monkey.")
-    private Long mRandomSeed = null;
-
-    @Option(name = "throttle", description = "How much time to wait between sending successive " +
-            "events, in msecs.  Default is 0ms.")
-    private int mThrottle = 0;
-
-    @Option(name = "ignore-crashes", description = "Monkey should keep going after encountering " +
-            "an app crash")
-    private boolean mIgnoreCrashes = false;
-
-    @Option(name = "ignore-timeout", description = "Monkey should keep going after encountering " +
-            "an app timeout (ANR)")
-    private boolean mIgnoreTimeouts = false;
-
-    @Option(name = "reboot-device", description = "Reboot device before running monkey. Defaults " +
-            "to true.")
-    private boolean mRebootDevice = true;
-
-    @Option(name = "idle-time", description = "How long to sleep before running monkey, in secs")
-    private int mIdleTimeSecs = 5 * 60;
-
-    @Option(name = "monkey-arg", description = "Extra parameters to pass onto monkey. Key/value " +
-            "pairs should be passed as key:value. May be repeated.")
-    private Collection<String> mMonkeyArgs = new LinkedList<>();
-
-    @Option(name = "use-pkg-whitelist-file", description = "Whether to use the monkey " +
-            "--pkg-whitelist-file option to work around cmdline length limits")
-    private boolean mUseWhitelistFile = false;
-
-    @Option(name = "monkey-timeout", description = "How long to wait for the monkey to " +
-            "complete, in minutes. Default is 4 hours.")
-    private int mMonkeyTimeout = 4 * 60;
-
-    @Option(name = "warmup-component", description = "Component name of app to launch for " +
-            "\"warming up\" before monkey test, will be used in an intent together with standard " +
-            "flags and parameters as launched from Launcher. May be repeated")
-    private List<String> mLaunchComponents = new ArrayList<>();
-
-    @Option(name = "retry-on-failure", description = "Retry the test on failure")
-    private boolean mRetryOnFailure = false;
-
-    // FIXME: Remove this once traces.txt is no longer needed.
-    @Option(name = "upload-file-pattern", description = "File glob of on-device files to upload " +
-            "if found. Takes two arguments: the glob, and the file type " +
-            "(text/xml/zip/gzip/png/unknown).  May be repeated.")
-    private Map<String, LogDataType> mUploadFilePatterns = new LinkedHashMap<>();
-
-    @Option(name = "screenshot", description = "Take a device screenshot on monkey completion")
-    private boolean mScreenshot = false;
-
-    @Option(name = "ignore-security-exceptions",
-            description = "Ignore SecurityExceptions while injecting events")
-    private boolean mIgnoreSecurityExceptions = true;
-
-    @Option(name = "collect-atrace",
-            description = "Enable a continuous circular buffer to collect atrace information")
-    private boolean mAtraceEnabled = false;
-
-    // options for generating ANR report via post processing script
-    @Option(name = "generate-anr-report", description = "Generate ANR report via post-processing")
-    private boolean mGenerateAnrReport = false;
-
-    @Option(name = "anr-report-script", description = "Path to the script for monkey ANR "
-            + "report generation.")
-    private String mAnrReportScriptPath = null;
-
-    @Option(name = "anr-report-storage-backend-base-path", description = "Base path to the storage "
-            + "backend used for saving the reports")
-    private String mAnrReportBasePath = null;
-
-    @Option(name = "anr-report-storage-backend-url-prefix", description = "URL prefix for the "
-            + "storage backend that would enable web acess to the stored reports.")
-    private String mAnrReportUrlPrefix = null;
-
-    @Option(name = "anr-report-storage-path", description = "Sub path under the base storage "
-            + "location for generated monkey ANR reports.")
-    private String mAnrReportPath = null;
-
-    private ITestDevice mTestDevice = null;
-    private MonkeyLogItem mMonkeyLog = null;
-    private BugreportItem mBugreport = null;
-    private AnrReportGenerator mAnrGen = null;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(getDevice());
-
-        TestDescription id = new TestDescription(getClass().getCanonicalName(), "monkey");
-        long startTime = System.currentTimeMillis();
-
-        listener.testRunStarted(getClass().getCanonicalName(), 1);
-        listener.testStarted(id);
-
-        try {
-            runMonkey(listener);
-        } finally {
-            listener.testEnded(id, new HashMap<String, Metric>());
-            listener.testRunEnded(
-                    System.currentTimeMillis() - startTime, new HashMap<String, Metric>());
-        }
-    }
-
-    /**
-     * Returns the command that should be used to launch the app,
-     */
-    private String getAppCmdWithExtras() {
-        String extras = "";
-        for (Map.Entry<String, String> sEntry : mStringExtras.entrySet()) {
-            extras += String.format(" -e %s %s", sEntry.getKey(), sEntry.getValue());
-        }
-        for (Map.Entry<String, Integer> sEntry : mIntegerExtras.entrySet()) {
-            extras += String.format(" --ei %s %d", sEntry.getKey(), sEntry.getValue());
-        }
-        return LAUNCH_APP_CMD + extras;
-    }
-
-    /**
-     * Run the monkey one time and return a {@link MonkeyLogItem} for the run.
-     */
-    protected void runMonkey(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        ITestDevice device = getDevice();
-        if (mRebootDevice) {
-            CLog.v("Rebooting device prior to running Monkey");
-            device.reboot();
-        } else {
-            CLog.v("Pre-run reboot disabled; skipping...");
-        }
-
-        if (mIdleTimeSecs > 0) {
-            CLog.i("Sleeping for %d seconds to allow device to settle...", mIdleTimeSecs);
-            getRunUtil().sleep(mIdleTimeSecs * 1000);
-            CLog.i("Done sleeping.");
-        }
-
-        // launch the list of apps that needs warm-up
-        for (String componentName : mLaunchComponents) {
-            getDevice().executeShellCommand(String.format(getAppCmdWithExtras(), componentName));
-            // give it some more time to settle down
-            getRunUtil().sleep(5000);
-        }
-
-        if (mUseWhitelistFile) {
-            // Use \r\n for new lines on the device.
-            String whitelist = ArrayUtil.join("\r\n", setSubtract(mPackages, mExcludePackages));
-            device.pushString(whitelist.toString(), DEVICE_WHITELIST_PATH);
-        }
-
-        // Generate the monkey command to run, given the options
-        String command = buildMonkeyCommand();
-        CLog.i("About to run monkey with at %d minute timeout: %s", mMonkeyTimeout, command);
-
-        StringBuilder outputBuilder = new StringBuilder();
-        CommandHelper commandHelper = new CommandHelper();
-
-        long start = System.currentTimeMillis();
-        long duration = 0;
-        Date dateAfter = null;
-        String uptimeAfter = NULL_UPTIME;
-        FileInputStreamSource atraceStream = null;
-
-        // Generate the monkey log prefix, which includes the device uptime
-        outputBuilder.append(String.format("# %s - device uptime = %s: Monkey command used " +
-                "for this test:\nadb shell %s\n\n", new Date().toString(), getUptime(), command));
-
-        // Start atrace before running the monkey command, but after reboot
-        if (mAtraceEnabled) {
-            CircularAtraceUtil.startTrace(getDevice(), null, 10);
-        }
-
-        if (mGenerateAnrReport) {
-            mAnrGen = new AnrReportGenerator(mAnrReportScriptPath, mAnrReportBasePath,
-                    mAnrReportUrlPrefix, mAnrReportPath, mTestDevice.getBuildId(),
-                    mTestDevice.getBuildFlavor(), mTestDevice.getSerialNumber());
-        }
-
-        try {
-            onMonkeyStart();
-            commandHelper.runCommand(mTestDevice, command, getMonkeyTimeoutMs());
-        } finally {
-            // Wait for device to recover if it's not online.  If it hasn't recovered, ignore.
-            try {
-                mTestDevice.waitForDeviceOnline(2 * 60 * 1000);
-                duration = System.currentTimeMillis() - start;
-                dateAfter = new Date();
-                uptimeAfter = getUptime();
-                onMonkeyFinish();
-                takeScreenshot(listener, "screenshot");
-
-                if (mAtraceEnabled) {
-                    atraceStream = CircularAtraceUtil.endTrace(getDevice());
-                }
-
-                mBugreport = takeBugreport(listener, BUGREPORT_NAME);
-                // FIXME: Remove this once traces.txt is no longer needed.
-                takeTraces(listener);
-            } finally {
-                // @@@ DO NOT add anything that requires device interaction into this block     @@@
-                // @@@ logging that no longer requires device interaction MUST be in this block @@@
-                outputBuilder.append(commandHelper.getOutput());
-                if (dateAfter == null) {
-                    dateAfter = new Date();
-                }
-
-                // Generate the monkey log suffix, which includes the device uptime.
-                outputBuilder.append(String.format("\n# %s - device uptime = %s: Monkey command "
-                        + "ran for: %d:%02d (mm:ss)\n", dateAfter.toString(), uptimeAfter,
-                        duration / 1000 / 60, duration / 1000 % 60));
-                mMonkeyLog = createMonkeyLog(listener, MONKEY_LOG_NAME, outputBuilder.toString());
-
-                boolean isAnr = mMonkeyLog.getCrash() instanceof AnrItem;
-                if (mAtraceEnabled && isAnr) {
-                    // This was identified as an ANR; post atrace data
-                    listener.testLog("circular-atrace", LogDataType.TEXT, atraceStream);
-                }
-                if (mAnrGen != null) {
-                    if (isAnr) {
-                        if (!mAnrGen.genereateAnrReport(listener)) {
-                            CLog.w("Failed to post-process ANR.");
-                        } else {
-                            CLog.i("Successfully post-processed ANR.");
-                        }
-                        mAnrGen.cleanTempFiles();
-                    } else {
-                        CLog.d("ANR post-processing enabled but no ANR detected.");
-                    }
-                }
-                StreamUtil.cancel(atraceStream);
-            }
-        }
-
-        // Extra logs for what was found
-        if (mBugreport != null && mBugreport.getLastKmsg() != null) {
-            List<MiscKernelLogItem> kernelErrors = mBugreport.getLastKmsg().getMiscEvents(
-                    KernelLogParser.KERNEL_ERROR);
-            List<MiscKernelLogItem> kernelResets = mBugreport.getLastKmsg().getMiscEvents(
-                    KernelLogParser.KERNEL_ERROR);
-            CLog.d("Found %d kernel errors and %d kernel resets in last kmsg",
-                    kernelErrors.size(), kernelResets.size());
-            for (int i = 0; i < kernelErrors.size(); i++) {
-                String stack = kernelErrors.get(i).getStack();
-                if (stack != null) {
-                    CLog.d("Kernel Error #%d: %s", i + 1, stack.split("\n")[0].trim());
-                }
-            }
-            for (int i = 0; i < kernelResets.size(); i++) {
-                String stack = kernelResets.get(i).getStack();
-                if (stack != null) {
-                    CLog.d("Kernel Reset #%d: %s", i + 1, stack.split("\n")[0].trim());
-                }
-            }
-        }
-
-        checkResults();
-    }
-
-    /**
-     * A hook to allow subclasses to perform actions just before the monkey starts.
-     */
-    protected void onMonkeyStart() {
-       // empty
-    }
-
-    /**
-     * A hook to allow sublaccess to perform actions just after the monkey finished.
-     */
-    protected void onMonkeyFinish() {
-        // empty
-    }
-
-    /**
-     * If enabled, capture a screenshot and send it to a listener.
-     * @throws DeviceNotAvailableException
-     */
-    protected void takeScreenshot(ITestInvocationListener listener, String screenshotName)
-            throws DeviceNotAvailableException {
-        if (mScreenshot) {
-            try (InputStreamSource screenshot = mTestDevice.getScreenshot("JPEG")) {
-                listener.testLog(screenshotName, LogDataType.JPEG, screenshot);
-            }
-        }
-    }
-
-    /**
-     * Capture a bugreport and send it to a listener.
-     */
-    protected BugreportItem takeBugreport(ITestInvocationListener listener, String bugreportName) {
-        Bugreport bugreport = mTestDevice.takeBugreport();
-        if (bugreport == null) {
-            CLog.e("Could not take bugreport");
-            return null;
-        }
-        bugreport.log(bugreportName, listener);
-        File main = null;
-        InputStreamSource is = null;
-        try {
-            main = bugreport.getMainFile();
-            if (main == null) {
-                CLog.e("Bugreport has no main file");
-                return null;
-            }
-            if (mAnrGen != null) {
-                is = new FileInputStreamSource(main);
-                mAnrGen.setBugReportInfo(is);
-            }
-            return new BugreportParser().parse(new BufferedReader(new FileReader(main)));
-        } catch (IOException e) {
-            CLog.e("Could not process bugreport");
-            CLog.e(e);
-            return null;
-        } finally {
-            StreamUtil.close(bugreport);
-            StreamUtil.cancel(is);
-            FileUtil.deleteFile(main);
-        }
-    }
-
-    protected void takeTraces(ITestInvocationListener listener) {
-        DeviceFileReporter dfr = new DeviceFileReporter(mTestDevice, listener);
-        dfr.addPatterns(mUploadFilePatterns);
-        try {
-            dfr.run();
-        } catch (DeviceNotAvailableException e) {
-            // Log but don't throw
-            CLog.e("Device %s became unresponsive while pulling files",
-                    mTestDevice.getSerialNumber());
-        }
-    }
-
-    /**
-     * Create the monkey log, parse it, and send it to a listener.
-     */
-    protected MonkeyLogItem createMonkeyLog(ITestInvocationListener listener, String monkeyLogName,
-            String log) {
-        try (InputStreamSource source = new ByteArrayInputStreamSource(log.getBytes())) {
-            if (mAnrGen != null) {
-                mAnrGen.setMonkeyLogInfo(source);
-            }
-            listener.testLog(monkeyLogName, LogDataType.MONKEY_LOG, source);
-            return new MonkeyLogParser().parse(new BufferedReader(new InputStreamReader(
-                    source.createInputStream())));
-        } catch (IOException e) {
-            CLog.e("Could not process monkey log.");
-            CLog.e(e);
-            return null;
-        }
-    }
-
-    /**
-     * A helper method to build a monkey command given the specified arguments.
-     * <p>
-     * Actual output argument order is:
-     * {@code monkey [-p PACKAGE]... [-c CATEGORY]... [--OPTION]... -s SEED -v -v -v COUNT}
-     * </p>
-     *
-     * @return a {@link String} containing the command with the arguments assembled in the proper
-     *         order.
-     */
-    protected String buildMonkeyCommand() {
-        List<String> cmdList = new LinkedList<>();
-        cmdList.add("monkey");
-
-        if (!mUseWhitelistFile) {
-            for (String pkg : setSubtract(mPackages, mExcludePackages)) {
-                cmdList.add("-p");
-                cmdList.add(pkg);
-            }
-        }
-
-        for (String cat : mCategories) {
-            cmdList.add("-c");
-            cmdList.add(cat);
-        }
-
-        if (mIgnoreSecurityExceptions) {
-            cmdList.add("--ignore-security-exceptions");
-        }
-
-        if (mThrottle >= 1) {
-            cmdList.add("--throttle");
-            cmdList.add(Integer.toString(mThrottle));
-        }
-        if (mIgnoreCrashes) {
-            cmdList.add("--ignore-crashes");
-        }
-        if (mIgnoreTimeouts) {
-            cmdList.add("--ignore-timeouts");
-        }
-
-        if (mUseWhitelistFile) {
-            cmdList.add("--pkg-whitelist-file");
-            cmdList.add(DEVICE_WHITELIST_PATH);
-        }
-
-        for (String arg : mMonkeyArgs) {
-            String[] args = arg.split(":");
-            cmdList.add(String.format("--%s", args[0]));
-            if (args.length > 1) {
-                cmdList.add(args[1]);
-            }
-        }
-
-        cmdList.addAll(mOptions);
-
-        cmdList.add("-s");
-        if (mRandomSeed == null) {
-            // Pick a number that is random, but in a small enough range that some seeds are likely
-            // to be repeated
-            cmdList.add(Long.toString(new Random().nextInt(1000)));
-        } else {
-            cmdList.add(Long.toString(mRandomSeed));
-        }
-
-        // verbose
-        cmdList.add("-v");
-        cmdList.add("-v");
-        cmdList.add("-v");
-        cmdList.add(Integer.toString(mTargetCount));
-
-        return ArrayUtil.join(" ", cmdList);
-    }
-
-    /**
-     * Get a {@link String} containing the number seconds since the device was booted.
-     * <p>
-     * {@code NULL_UPTIME} is returned if the device becomes unresponsive. Used in the monkey log
-     * prefix and suffix.
-     * </p>
-     */
-    protected String getUptime() {
-        try {
-            // make two attempts to get valid uptime
-            for (int i = 0; i < 2; i++) {
-                // uptime will typically have a format like "5278.73 1866.80".  Use the first one
-                // (which is wall-time)
-                String uptime = mTestDevice.executeShellCommand("cat /proc/uptime").split(" ")[0];
-                try {
-                    Float.parseFloat(uptime);
-                    // if this parsed, its a valid uptime
-                    return uptime;
-                } catch (NumberFormatException e) {
-                    CLog.w("failed to get valid uptime from %s. Received: '%s'",
-                            mTestDevice.getSerialNumber(), uptime);
-                }
-            }
-        } catch (DeviceNotAvailableException e) {
-            CLog.e("Device %s became unresponsive while getting the uptime.",
-                    mTestDevice.getSerialNumber());
-        }
-        return NULL_UPTIME;
-    }
-
-    /**
-     * Perform set subtraction between two {@link Collection} objects.
-     * <p>
-     * The return value will consist of all of the elements of {@code keep}, excluding the elements
-     * that are also in {@code exclude}. Exposed for unit testing.
-     * </p>
-     *
-     * @param keep the minuend in the subtraction
-     * @param exclude the subtrahend
-     * @return the collection of elements in {@code keep} that are not also in {@code exclude}. If
-     * {@code keep} is an ordered {@link Collection}, the remaining elements in the return value
-     * will remain in their original order.
-     */
-    static Collection<String> setSubtract(Collection<String> keep, Collection<String> exclude) {
-        if (exclude.isEmpty()) {
-            return keep;
-        }
-
-        Collection<String> output = new ArrayList<>(keep);
-        output.removeAll(exclude);
-        return output;
-    }
-
-    /**
-     * Get {@link IRunUtil} to use. Exposed for unit testing.
-     */
-    IRunUtil getRunUtil() {
-        return RunUtil.getDefault();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @return {@code false} if retry-on-failure is not set, if the monkey ran to completion,
-     * crashed in an understood way, or if there were no packages to run, {@code true} otherwise.
-     */
-    @Override
-    public boolean isRetriable() {
-        return mRetryOnFailure;
-    }
-
-    /**
-     * Check the results and return if valid or throw an assertion error if not valid.
-     */
-    private void checkResults() {
-        Assert.assertNotNull("Monkey log is null", mMonkeyLog);
-        Assert.assertNotNull("Bugreport is null", mBugreport);
-        Assert.assertNotNull("Bugreport is empty", mBugreport.getTime());
-
-        // If there are no activities, retrying the test won't matter.
-        if (mMonkeyLog.getNoActivities()) {
-            return;
-        }
-
-        Assert.assertNotNull("Start uptime is missing", mMonkeyLog.getStartUptimeDuration());
-        Assert.assertNotNull("Stop uptime is missing", mMonkeyLog.getStopUptimeDuration());
-        Assert.assertNotNull("Total duration is missing", mMonkeyLog.getTotalDuration());
-
-        long startUptime = mMonkeyLog.getStartUptimeDuration();
-        long stopUptime = mMonkeyLog.getStopUptimeDuration();
-        long totalDuration = mMonkeyLog.getTotalDuration();
-
-        Assert.assertTrue("Uptime failure",
-                stopUptime - startUptime > totalDuration - UPTIME_BUFFER);
-
-        // False count
-        Assert.assertFalse("False count", mMonkeyLog.getIsFinished() &&
-                mMonkeyLog.getTargetCount() - mMonkeyLog.getIntermediateCount() > 100);
-
-        // Monkey finished or crashed, so don't fail
-        if (mMonkeyLog.getIsFinished() || mMonkeyLog.getFinalCount() != null) {
-            return;
-        }
-
-        // Missing count
-        Assert.fail("Missing count");
-    }
-
-    /**
-     * Get the monkey timeout in milliseconds
-     */
-    protected long getMonkeyTimeoutMs() {
-        return mMonkeyTimeout * 60 * 1000;
-    }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyBrillopadForwarder.java b/prod-tests/src/com/android/monkey/MonkeyBrillopadForwarder.java
deleted file mode 100644
index a3314ea..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyBrillopadForwarder.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.monkey;
-
-import com.android.loganalysis.item.AnrItem;
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.IItem;
-import com.android.loganalysis.item.JavaCrashItem;
-import com.android.loganalysis.item.LogcatItem;
-import com.android.loganalysis.item.MonkeyLogItem;
-import com.android.loganalysis.item.NativeCrashItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.loganalysis.parser.MonkeyLogParser;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.ResultForwarder;
-import com.android.tradefed.result.TestDescription;
-
-import com.google.common.base.Throwables;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A {@link ResultForwarder} that intercepts monkey and bug report logs, extracts relevant metrics
- * from them using brillopad, and forwards the results to the specified
- * {@link ITestInvocationListener}.
- */
-public class MonkeyBrillopadForwarder extends ResultForwarder {
-
-    private enum MonkeyStatus {
-        FINISHED("Money completed without errors."),
-        CRASHED("Monkey run stopped because of a crash."),
-        MISSING_COUNT("Monkey run failed to complete due to an unknown reason. " +
-                "Check logs for details."),
-        FALSE_COUNT("Monkey run reported an invalid count. " +
-                "Check logs for details."),
-        UPTIME_FAILURE("Monkey output is indicating an invalid uptime. " +
-                "Device may have reset during run."),
-        TIMEOUT("Monkey did not complete within the specified time");
-
-        private String mDescription;
-
-        MonkeyStatus(String desc) {
-            mDescription = desc;
-        }
-
-        /** Returns a User friendly description of the status. */
-        String getDescription() {
-            return mDescription;
-        }
-    }
-
-    private BugreportItem mBugreport = null;
-    private MonkeyLogItem mMonkeyLog = null;
-    private final long mMonkeyTimeoutMs;
-
-    public MonkeyBrillopadForwarder(ITestInvocationListener listener, long monkeyTimeoutMs) {
-        super(listener);
-        mMonkeyTimeoutMs = monkeyTimeoutMs;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void testLog(String dataName, LogDataType dataType, InputStreamSource dataStream) {
-        try {
-            // just parse the logs for now. Forwarding of results will happen on test completion
-            if (LogDataType.BUGREPORT.equals(dataType)) {
-                CLog.i("Parsing %s", dataName);
-                mBugreport = new BugreportParser().parse(new BufferedReader(new InputStreamReader(
-                        dataStream.createInputStream())));
-            }
-            if (LogDataType.MONKEY_LOG.equals(dataType)) {
-                CLog.i("Parsing %s", dataName);
-                mMonkeyLog = new MonkeyLogParser().parse(new BufferedReader(new InputStreamReader(
-                        dataStream.createInputStream())));
-            }
-        } catch (IOException e) {
-            CLog.e("Could not parse file %s", dataName);
-        }
-        super.testLog(dataName, dataType, dataStream);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void testEnded(TestDescription monkeyTest, Map<String, String> metrics) {
-        Map<String, String> monkeyMetrics = new HashMap<String, String>();
-        try {
-            Assert.assertNotNull("Failed to parse or retrieve bug report", mBugreport);
-            Assert.assertNotNull("Cannot report run to brillopad, monkey log does not exist",
-                mMonkeyLog);
-            Assert.assertNotNull("monkey log is missing start time info",
-                    mMonkeyLog.getStartUptimeDuration());
-            Assert.assertNotNull("monkey log is missing stop time info",
-                    mMonkeyLog.getStopUptimeDuration());
-            LogcatItem systemLog = mBugreport.getSystemLog();
-
-            MonkeyStatus status = reportMonkeyStats(mMonkeyLog, monkeyMetrics);
-            StringBuilder crashTrace = new StringBuilder();
-            reportAnrs(mMonkeyLog, monkeyMetrics, crashTrace);
-            reportJavaCrashes(mMonkeyLog, monkeyMetrics, crashTrace);
-            if (systemLog != null) {
-                reportNativeCrashes(systemLog, monkeyMetrics, crashTrace);
-            } else {
-                CLog.w("Failed to get system log from bugreport");
-            }
-
-            if (!status.equals(MonkeyStatus.FINISHED)) {
-                String failure = String.format("%s.\n%s", status.getDescription(),
-                        crashTrace.toString());
-                super.testFailed(monkeyTest, failure);
-            }
-        } catch (AssertionError e) {
-            super.testFailed(monkeyTest, Throwables.getStackTraceAsString(e));
-        } catch (RuntimeException e) {
-            super.testFailed(monkeyTest, Throwables.getStackTraceAsString(e));
-        } finally {
-            super.testEnded(monkeyTest, monkeyMetrics);
-        }
-    }
-
-    /**
-     * Report stats about the monkey run from the monkey log.
-     */
-    private MonkeyStatus reportMonkeyStats(MonkeyLogItem monkeyLog,
-            Map<String, String> monkeyMetrics) {
-        MonkeyStatus status = getStatus(monkeyLog);
-        monkeyMetrics.put("throttle", convertToString(monkeyLog.getThrottle()));
-        monkeyMetrics.put("status", status.toString());
-        monkeyMetrics.put("target_count", convertToString(monkeyLog.getTargetCount()));
-        monkeyMetrics.put("injected_count", convertToString(monkeyLog.getFinalCount()));
-        monkeyMetrics.put("run_duration", convertToString(monkeyLog.getTotalDuration()));
-        monkeyMetrics.put("uptime", convertToString((monkeyLog.getStopUptimeDuration() -
-                monkeyLog.getStartUptimeDuration())));
-        return status;
-    }
-
-    /**
-     * A utility method that converts an {@link Integer} to a {@link String}, and that can handle
-     * null.
-     */
-    private static String convertToString(Integer integer) {
-        return integer == null ? "" : integer.toString();
-    }
-
-    /**
-     * A utility method that converts a {@link Long} to a {@link String}, and that can handle null.
-     */
-    private static String convertToString(Long longInt) {
-        return longInt == null ? "" : longInt.toString();
-    }
-
-    /**
-     * Report stats about Java crashes from the monkey log.
-     */
-    private void reportJavaCrashes(MonkeyLogItem monkeyLog, Map<String, String> metrics,
-            StringBuilder crashTrace) {
-
-        if (monkeyLog.getCrash() != null && monkeyLog.getCrash() instanceof JavaCrashItem) {
-            JavaCrashItem jc = (JavaCrashItem) monkeyLog.getCrash();
-            metrics.put("java_crash", "1");
-            crashTrace.append("Detected java crash:\n");
-            crashTrace.append(jc.getStack());
-            crashTrace.append("\n");
-        }
-    }
-
-    /**
-     * Report stats about the native crashes from the bugreport.
-     */
-    private void reportNativeCrashes(LogcatItem systemLog, Map<String, String> metrics,
-            StringBuilder crashTrace)  {
-        if (systemLog.getEvents().size() > 0) {
-            int nativeCrashes = 0;
-            for (IItem item : systemLog.getEvents()) {
-                if (item instanceof NativeCrashItem) {
-                    nativeCrashes++;
-                    crashTrace.append("Detected native crash:\n");
-                    crashTrace.append(((NativeCrashItem)item).getStack());
-                    crashTrace.append("\n");
-                }
-            }
-            metrics.put("native_crash", Integer.toString(nativeCrashes));
-        }
-    }
-
-    /**
-     * Report stats about the ANRs from the monkey log.
-     */
-    private void reportAnrs(MonkeyLogItem monkeyLog, Map<String, String> metrics,
-            StringBuilder crashTrace) {
-        if (monkeyLog.getCrash() != null && monkeyLog.getCrash() instanceof AnrItem) {
-            AnrItem anr = (AnrItem) monkeyLog.getCrash();
-            metrics.put("anr_crash", "1");
-            crashTrace.append("Detected ANR:\n");
-            crashTrace.append(anr.getStack());
-            crashTrace.append("\n");
-        }
-    }
-
-    /**
-     * Return the {@link MonkeyStatus} based on how the monkey run ran.
-     */
-    private MonkeyStatus getStatus(MonkeyLogItem monkeyLog) {
-        // Uptime
-        try {
-            long startUptime = monkeyLog.getStartUptimeDuration();
-            long stopUptime = monkeyLog.getStopUptimeDuration();
-            long totalDuration = monkeyLog.getTotalDuration();
-            if (stopUptime - startUptime < totalDuration - MonkeyBase.UPTIME_BUFFER) {
-                return MonkeyStatus.UPTIME_FAILURE;
-            }
-            if (totalDuration >= mMonkeyTimeoutMs) {
-                return MonkeyStatus.TIMEOUT;
-            }
-        } catch (NullPointerException e) {
-            return MonkeyStatus.UPTIME_FAILURE;
-        }
-
-        // False count
-        if (monkeyLog.getIsFinished() &&
-                monkeyLog.getIntermediateCount() + 100 < monkeyLog.getTargetCount()) {
-            return MonkeyStatus.FALSE_COUNT;
-        }
-
-        // Finished
-        if (monkeyLog.getIsFinished()) {
-            return MonkeyStatus.FINISHED;
-        }
-
-        // Crashed
-        if (monkeyLog.getFinalCount() != null) {
-            return MonkeyStatus.CRASHED;
-        }
-
-        // Missing count
-        return MonkeyStatus.MISSING_COUNT;
-    }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyMetricsTest.java b/prod-tests/src/com/android/monkey/MonkeyMetricsTest.java
deleted file mode 100644
index 849bcf9..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyMetricsTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.monkey;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-
-/**
- * A {@link MonkeyBase} specialization that uses the brillopad parser to extract and report
- * monkey related metrics.
- */
-public class MonkeyMetricsTest extends MonkeyBase {
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        MonkeyBrillopadForwarder brilloAnalyzer = new MonkeyBrillopadForwarder(listener,
-                getMonkeyTimeoutMs());
-        super.run(brilloAnalyzer);
-    }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyPairedBase.java b/prod-tests/src/com/android/monkey/MonkeyPairedBase.java
deleted file mode 100644
index 1739916..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyPairedBase.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.monkey;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IMultiDeviceTest;
-import com.android.tradefed.util.clockwork.ClockworkUtils;
-
-import java.util.ArrayList;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.List;
-import java.util.Map;
-
-/** Runner for paired stress tests which use the monkey command. */
-public class MonkeyPairedBase extends MonkeyBase implements IMultiDeviceTest {
-
-    @Option(name = "companion-recurring-command", description = "recurring shell command "
-            + "on companion")
-    private String mCompanionRecurringCommand = null;
-
-    @Option(name = "companion-recurring-interval", description = "interval between recurring "
-            + "command in seconds")
-    private int mCompanionRecurringInterval = 25;
-
-    private ITestDevice mCompanion;
-    private List<ITestDevice> mDeviceList = new ArrayList<>();
-    private ScheduledExecutorService mScheduler;
-
-    /**
-     * Fetches the companion device allocated for the primary device
-     *
-     * @return the allocated companion device
-     * @throws RuntimeException if no companion device has been allocated
-     */
-    protected ITestDevice getCompanion() {
-        return mCompanion;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        if (mCompanionRecurringCommand != null) {
-            scheduleRecurringCommand();
-        }
-        try {
-            super.run(listener);
-        } finally {
-            stopRecurringCommand();
-        }
-    }
-
-    protected void scheduleRecurringCommand() {
-        mScheduler = Executors.newScheduledThreadPool(1);
-        mScheduler.scheduleAtFixedRate(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    getCompanion().executeShellCommand(mCompanionRecurringCommand);
-                } catch (DeviceNotAvailableException e) {
-                    CLog.e("Recurring command failed on %s (%s)", getCompanion().getSerialNumber(),
-                            mCompanionRecurringCommand);
-                }
-            }
-        }, mCompanionRecurringInterval, mCompanionRecurringInterval, TimeUnit.SECONDS);
-    }
-
-    protected void stopRecurringCommand() {
-        mScheduler.shutdownNow();
-        try {
-            mScheduler.awaitTermination(mCompanionRecurringInterval, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            CLog.e("Could not terminate recurring command on %s (%s)",
-                    getCompanion().getSerialNumber(), mCompanionRecurringCommand);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
-        ClockworkUtils cwUtils = new ClockworkUtils();
-        mCompanion = cwUtils.setUpMultiDevice(deviceInfos, mDeviceList);
-    }
-}
\ No newline at end of file
diff --git a/prod-tests/src/com/android/ota/tests/OtaStabilityTest.java b/prod-tests/src/com/android/ota/tests/OtaStabilityTest.java
deleted file mode 100644
index e74747a..0000000
--- a/prod-tests/src/com/android/ota/tests/OtaStabilityTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.ota.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IResumableTest;
-import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-
-/**
- * A test that will flash a build on a device, wait for the device to be OTA-ed to another build,
- * and then repeat N times.
- * <p/>
- * Note: this test assumes that the {@link ITargetPreparer}s included in this test's
- * {@link IConfiguration} will flash the device back to a baseline build, and prepare the device
- * to receive the OTA to a new build.
- */
-@OptionClass(alias = "ota-stability")
-public class OtaStabilityTest implements IDeviceTest, IBuildReceiver, IConfigurationReceiver,
-        IShardableTest, IResumableTest {
-
-    private static final String LOG_TAG = "OtaStabilityTest";
-    private IBuildInfo mDeviceBuild;
-    private IConfiguration mConfiguration;
-    private ITestDevice mDevice;
-
-    @Option(name = "run-name", description =
-        "The name of the ota stability test run. Used to report metrics.")
-    private String mRunName = "ota-stability";
-
-    @Option(name = "iterations", description =
-        "Number of ota stability 'flash + wait for ota' iterations to run.")
-    private int mIterations = 20;
-
-    @Option(name = "wait-recovery-time", description =
-        "Number of minutes to wait for device to begin installing ota.")
-    private int mWaitRecoveryTime = 15;
-
-    @Option(name = "wait-install-time", description =
-        "Number of minutes to wait for device to be online after beginning ota installation.")
-    private int mWaitInstallTime = 10;
-
-    @Option(name = "shards", description = "Optional number of shards to split test into. " +
-            "Iterations will be split evenly among shards.", importance = Importance.IF_UNSET)
-    private Integer mShards = null;
-
-    @Option(name = "resume", description = "Resume the ota test run if an device setup error " +
-            "stopped the previous test run.")
-    private boolean mResumeMode = false;
-
-    /** controls if this test should be resumed. Only used if mResumeMode is enabled */
-    private boolean mResumable = true;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setConfiguration(IConfiguration configuration) {
-        mConfiguration = configuration;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mDeviceBuild = buildInfo;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Set the wait recovery time
-     */
-    void setWaitRecoveryTime(int waitRecoveryTime) {
-        mWaitRecoveryTime = waitRecoveryTime;
-    }
-
-    /**
-     * Set the wait install time
-     */
-    void setWaitInstallTime(int waitInstallTime) {
-        mWaitInstallTime = waitInstallTime;
-    }
-
-    /**
-     * Set the run name
-     */
-    void setRunName(String runName) {
-        mRunName = runName;
-    }
-
-    /**
-     * Return the number of iterations.
-     * <p/>
-     * Exposed for unit testing
-     */
-    public int getIterations() {
-        return mIterations;
-    }
-
-    /**
-     * Set the iterations
-     */
-    void setIterations(int iterations) {
-        mIterations = iterations;
-    }
-
-    /**
-     * Set the number of shards
-     */
-    void setShards(int shards) {
-        mShards = shards;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Collection<IRemoteTest> split() {
-        if (mShards == null || mShards <= 1) {
-            return null;
-        }
-        Collection<IRemoteTest> shards = new ArrayList<>(mShards);
-        int remainingIterations = mIterations;
-        for (int i = mShards; i > 0; i--) {
-            OtaStabilityTest testShard = new OtaStabilityTest();
-            // device and configuration will be set by test invoker
-            testShard.setRunName(mRunName);
-            testShard.setWaitInstallTime(mWaitInstallTime);
-            testShard.setWaitRecoveryTime(mWaitRecoveryTime);
-            // attempt to divide iterations evenly among shards with no remainder
-            int iterationsForShard = Math.round(remainingIterations/i);
-            if (iterationsForShard > 0) {
-                testShard.setIterations(iterationsForShard);
-                remainingIterations -= iterationsForShard;
-                shards.add(testShard);
-            }
-        }
-        return shards;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // started run, turn to off
-        mResumable = false;
-        checkFields();
-
-        long startTime = System.currentTimeMillis();
-        listener.testRunStarted(mRunName, 0);
-        int actualIterations = 0;
-        try {
-            waitForOta(listener);
-            for (actualIterations = 1; actualIterations < mIterations; actualIterations++) {
-                flashDevice();
-                String buildId = waitForOta(listener);
-                Log.i(LOG_TAG,
-                        String.format("Device %s successfully OTA-ed to build %s. Iteration: %d",
-                                mDevice.getSerialNumber(), buildId, actualIterations));
-            }
-        } catch (AssertionError error) {
-            Log.e(LOG_TAG, error);
-        } catch (TargetSetupError e) {
-            CLog.i("Encountered TargetSetupError, marking this test as resumable");
-            mResumable = true;
-            CLog.e(e);
-            // throw up an exception so this test can be resumed
-            Assert.fail(e.toString());
-        } catch (BuildError e) {
-            Log.e(LOG_TAG, e);
-        } catch (ConfigurationException e) {
-            Log.e(LOG_TAG, e);
-        } finally {
-            HashMap<String, Metric> metrics = new HashMap<>();
-            metrics.put(
-                    "iterations",
-                    TfMetricProtoUtil.stringToMetric(Integer.toString(actualIterations)));
-            long endTime = System.currentTimeMillis() - startTime;
-            listener.testRunEnded(endTime, metrics);
-        }
-    }
-
-
-    /**
-     * Flash the device back to baseline build.
-     * <p/>
-     * Currently does this by re-running {@link ITargetPreparer#setUp(ITestDevice, IBuildInfo)}
-     *
-     * @throws DeviceNotAvailableException
-     * @throws BuildError
-     * @throws TargetSetupError
-     * @throws ConfigurationException
-     */
-    private void flashDevice() throws TargetSetupError, BuildError, DeviceNotAvailableException,
-            ConfigurationException {
-        // assume the target preparers will flash the device back to device build
-        for (ITargetPreparer preparer : mConfiguration.getTargetPreparers()) {
-            preparer.setUp(mDevice, mDeviceBuild);
-        }
-    }
-
-    /**
-     * Get the {@link IRunUtil} instance to use.
-     * <p/>
-     * Exposed so unit tests can mock.
-     */
-    IRunUtil getRunUtil() {
-        return RunUtil.getDefault();
-    }
-
-    /**
-     * Blocks and waits for OTA package to be installed.
-     *
-     * @param listener the {@link ITestInvocationListener}
-     * @return the build id the device ota-ed to
-     * @throws DeviceNotAvailableException
-     * @throws AssertionError
-     */
-    private String waitForOta(ITestInvocationListener listener)
-            throws DeviceNotAvailableException, AssertionError {
-        String currentBuildId = mDevice.getBuildId();
-        Assert.assertEquals(String.format("device %s does not have expected build id on boot.",
-                mDevice.getSerialNumber()), currentBuildId, mDeviceBuild.getBuildId());
-        // give some time for device to settle
-        getRunUtil().sleep(5*1000);
-        // force a checkin so device downloads OTA immediately
-        mDevice.executeShellCommand(
-                "am broadcast -a android.server.checkin.CHECKIN com.google.android.gms");
-        Assert.assertTrue(String.format(
-                "Device %s did not enter recovery after %d min.",
-                mDevice.getSerialNumber(), mWaitRecoveryTime),
-                mDevice.waitForDeviceInRecovery(mWaitRecoveryTime * 60 * 1000));
-        try {
-            mDevice.waitForDeviceOnline(mWaitInstallTime * 60 * 1000);
-        } catch (DeviceNotAvailableException e) {
-            Log.e(LOG_TAG, String.format(
-                    "Device %s did not come back online after leaving recovery",
-                    mDevice.getSerialNumber()));
-            sendRecoveryLog(listener);
-            throw e;
-        }
-        try {
-            mDevice.waitForDeviceAvailable();
-        } catch (DeviceNotAvailableException e) {
-            Log.e(LOG_TAG, String.format(
-                    "Device %s did not boot up successfully after leaving recovery/installing OTA",
-                    mDevice.getSerialNumber()));
-            throw e;
-        }
-        currentBuildId = mDevice.getBuildId();
-        // TODO: should exact expected build id be checked?
-        Assert.assertNotEquals(
-                String.format(
-                        "Device %s build id did not change after leaving recovery",
-                        mDevice.getSerialNumber()),
-                currentBuildId,
-                mDeviceBuild.getBuildId());
-        return currentBuildId;
-    }
-
-    private void sendRecoveryLog(ITestInvocationListener listener) throws
-            DeviceNotAvailableException {
-        File destFile = null;
-        InputStreamSource destSource = null;
-        try {
-            // get recovery log
-            destFile = FileUtil.createTempFile("recovery", "log");
-            boolean gotFile = mDevice.pullFile("/tmp/recovery.log", destFile);
-            if (gotFile) {
-                destSource = new FileInputStreamSource(destFile);
-                listener.testLog("recovery_log", LogDataType.TEXT, destSource);
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, String.format("Failed to get recovery log from device %s",
-                    mDevice.getSerialNumber()));
-            Log.e(LOG_TAG, e);
-        } finally {
-            FileUtil.deleteFile(destFile);
-            StreamUtil.cancel(destSource);
-        }
-    }
-
-    private void checkFields() {
-        if (mDevice == null) {
-            throw new IllegalArgumentException("missing device");
-        }
-        if (mConfiguration == null) {
-            throw new IllegalArgumentException("missing configuration");
-        }
-        if (mDeviceBuild == null) {
-            throw new IllegalArgumentException("missing build info");
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isResumable() {
-        return mResumeMode && mResumable;
-    }
-}
diff --git a/prod-tests/src/com/android/ota/tests/OtaStabilityTestTest.java b/prod-tests/src/com/android/ota/tests/OtaStabilityTestTest.java
deleted file mode 100644
index 1216c83..0000000
--- a/prod-tests/src/com/android/ota/tests/OtaStabilityTestTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.ota.tests;
-
-import com.android.tradefed.testtype.IRemoteTest;
-
-import junit.framework.TestCase;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * Unit tests for {@link OtaStabilityTest}
- */
-public class OtaStabilityTestTest extends TestCase {
-
-    /**
-     * Test basic case {@link OtaStabilityTest#split()}, where iterations divide evenly into each
-     * shards.
-     */
-    public void testSplit_even() {
-        OtaStabilityTest test = new OtaStabilityTest();
-        test.setIterations(10);
-        test.setShards(5);
-        Collection<IRemoteTest> shards = test.split();
-        assertEquals(5, shards.size());
-        for (IRemoteTest shardTest : shards) {
-            OtaStabilityTest otaShard = (OtaStabilityTest)shardTest;
-            assertEquals(2, otaShard.getIterations());
-        }
-    }
-
-    /**
-     * Test {@link OtaStabilityTest#split()}, where there are more iterations than shards.
-     */
-    public void testSplit_shards() {
-        OtaStabilityTest test = new OtaStabilityTest();
-        test.setIterations(5);
-        test.setShards(10);
-        Collection<IRemoteTest> shards = test.split();
-        assertEquals(5, shards.size());
-        for (IRemoteTest shardTest : shards) {
-            OtaStabilityTest otaShard = (OtaStabilityTest)shardTest;
-            assertEquals(1, otaShard.getIterations());
-        }
-    }
-
-    /**
-     * Test {@link OtaStabilityTest#split()}, where iterations does not divide evenly
-     */
-    public void testSplit_remainder() {
-        OtaStabilityTest test = new OtaStabilityTest();
-        test.setIterations(10);
-        test.setShards(3);
-        Collection<IRemoteTest> shards = test.split();
-        assertEquals(3, shards.size());
-        Iterator<IRemoteTest> iterator = shards.iterator();
-        IRemoteTest first = iterator.next();
-        assertEquals(3, ((OtaStabilityTest)first).getIterations());
-
-        IRemoteTest second = iterator.next();
-        assertEquals(3, ((OtaStabilityTest)second).getIterations());
-
-        IRemoteTest three = iterator.next();
-        assertEquals(4, ((OtaStabilityTest)three).getIterations());
-    }
-}
diff --git a/prod-tests/src/com/android/ota/tests/SideloadOtaStabilityTest.java b/prod-tests/src/com/android/ota/tests/SideloadOtaStabilityTest.java
deleted file mode 100644
index b475dda..0000000
--- a/prod-tests/src/com/android/ota/tests/SideloadOtaStabilityTest.java
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.ota.tests;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertThat;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.build.OtaDeviceBuildInfo;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IManagedTestDevice;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.TestDeviceState;
-import com.android.tradefed.log.LogReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IResumableTest;
-import com.android.tradefed.util.DeviceRecoveryModeUtil;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A test that will perform repeated flash + install OTA actions on a device.
- * <p/>
- * adb must have root.
- * <p/>
- * Expects a {@link OtaDeviceBuildInfo}.
- * <p/>
- * Note: this test assumes that the {@link ITargetPreparer}s included in this test's
- * {@link IConfiguration} will flash the device back to a baseline build, and prepare the device to
- * receive the OTA to a new build.
- */
-@OptionClass(alias = "ota-stability")
-public class SideloadOtaStabilityTest implements IDeviceTest, IBuildReceiver,
-        IConfigurationReceiver, IResumableTest {
-
-    private static final String UNCRYPT_FILE_PATH = "/cache/recovery/uncrypt_file";
-    private static final String UNCRYPT_STATUS_FILE = "/cache/recovery/uncrypt_status";
-    private static final String BLOCK_MAP_PATH = "@/cache/recovery/block.map";
-    private static final String RECOVERY_COMMAND_PATH = "/cache/recovery/command";
-    private static final String LOG_RECOV = "/cache/recovery/last_log";
-    private static final String LOG_KMSG = "/cache/recovery/last_kmsg";
-    private static final String KMSG_CMD = "cat /proc/kmsg";
-    private static final long SOCKET_RETRY_CT = 30;
-    private static final long UNCRYPT_TIMEOUT = 15 * 60 * 1000;
-
-    private static final long SHORT_WAIT_UNCRYPT = 3 * 1000;
-
-    private OtaDeviceBuildInfo mOtaDeviceBuild;
-    private IConfiguration mConfiguration;
-    private ITestDevice mDevice;
-
-    @Option(name = "run-name", description =
-            "The name of the ota stability test run. Used to report metrics.")
-    private String mRunName = "ota-stability";
-
-    @Option(name = "iterations", description =
-            "Number of ota stability 'flash + wait for ota' iterations to run.")
-    private int mIterations = 20;
-
-    @Option(name = "resume", description = "Resume the ota test run if an device setup error "
-            + "stopped the previous test run.")
-    private boolean mResumeMode = false;
-
-    @Option(name = "max-install-time", description =
-            "The maximum time to wait for an ota to install in seconds.")
-    private int mMaxInstallOnlineTimeSec = 5 * 60;
-
-    @Option(name = "package-data-path", description =
-            "path on /data for the package to be saved to")
-    /* This is currently the only path readable by uncrypt on the userdata partition */
-    private String mPackageDataPath = "/data/data/com.google.android.gsf/app_download/update.zip";
-
-    @Option(name = "max-reboot-time", description =
-            "The maximum time to wait for a device to reboot out of recovery if it fails")
-    private long mMaxRebootTimeSec = 5 * 60;
-
-    @Option(name = "uncrypt-only", description = "if true, only uncrypt then exit")
-    private boolean mUncryptOnly = false;
-
-    /** controls if this test should be resumed. Only used if mResumeMode is enabled */
-    private boolean mResumable = true;
-
-    private long mUncryptDuration;
-    private LogReceiver mKmsgReceiver;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setConfiguration(IConfiguration configuration) {
-        mConfiguration = configuration;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mOtaDeviceBuild = (OtaDeviceBuildInfo) buildInfo;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Set the run name
-     */
-    void setRunName(String runName) {
-        mRunName = runName;
-    }
-
-    /**
-     * Return the number of iterations.
-     * <p/>
-     * Exposed for unit testing
-     */
-    public int getIterations() {
-        return mIterations;
-    }
-
-    /**
-     * Set the iterations
-     */
-    void setIterations(int iterations) {
-        mIterations = iterations;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // started run, turn to off
-        mResumable = false;
-        mKmsgReceiver = new LogReceiver(getDevice(), KMSG_CMD, "kmsg");
-        checkFields();
-
-        CLog.i("Starting OTA sideload test from %s to %s, for %d iterations",
-                mOtaDeviceBuild.getDeviceImageVersion(),
-                mOtaDeviceBuild.getOtaBuild().getOtaPackageVersion(), mIterations);
-
-        long startTime = System.currentTimeMillis();
-        listener.testRunStarted(mRunName, 0);
-        int actualIterations = 0;
-        BootTimeInfo lastBootTime = null;
-        try {
-            while (actualIterations < mIterations) {
-                if (actualIterations != 0) {
-                    // don't need to flash device on first iteration
-                    flashDevice();
-                }
-                lastBootTime = installOta(listener, mOtaDeviceBuild.getOtaBuild());
-                actualIterations++;
-                CLog.i("Device %s successfully OTA-ed to build %s. Iteration: %d of %d",
-                        mDevice.getSerialNumber(),
-                        mOtaDeviceBuild.getOtaBuild().getOtaPackageVersion(),
-                        actualIterations, mIterations);
-            }
-        } catch (AssertionError | BuildError e) {
-            CLog.e(e);
-        } catch (TargetSetupError e) {
-            CLog.i("Encountered TargetSetupError, marking this test as resumable");
-            mResumable = true;
-            CLog.e(e);
-            // throw up an exception so this test can be resumed
-            Assert.fail(e.toString());
-        } finally {
-            // if the device is down, we need to recover it so we can safely pull logs
-            IManagedTestDevice managedDevice = (IManagedTestDevice) mDevice;
-            if (!managedDevice.getDeviceState().equals(TestDeviceState.ONLINE)) {
-                // not all IDeviceRecovery implementations can handle getting out of recovery mode,
-                // so we should just reboot in that case since we no longer need to be in
-                // recovery
-                CLog.i("Device is not online, attempting to recover before capturing logs");
-                DeviceRecoveryModeUtil.bootOutOfRecovery((IManagedTestDevice) mDevice,
-                        mMaxInstallOnlineTimeSec * 1000);
-            }
-            double updateTime = sendRecoveryLog(listener);
-            Map<String, String> metrics = new HashMap<>(1);
-            metrics.put("iterations", Integer.toString(actualIterations));
-            metrics.put("failed_iterations", Integer.toString(mIterations - actualIterations));
-            metrics.put("update_time", Double.toString(updateTime));
-            metrics.put("uncrypt_time", Long.toString(mUncryptDuration));
-            if (lastBootTime != null) {
-                metrics.put("boot_time_online", Double.toString(lastBootTime.mOnlineTime));
-                metrics.put("boot_time_available", Double.toString(lastBootTime.mAvailTime));
-            }
-            long endTime = System.currentTimeMillis() - startTime;
-            listener.testRunEnded(endTime, TfMetricProtoUtil.upgradeConvert(metrics));
-        }
-    }
-
-    /**
-     * Flash the device back to baseline build.
-     * <p/>
-     * Currently does this by re-running {@link ITargetPreparer#setUp(ITestDevice, IBuildInfo)}
-     */
-    private void flashDevice() throws TargetSetupError, BuildError, DeviceNotAvailableException {
-        // assume the target preparers will flash the device back to device build
-        for (ITargetPreparer preparer : mConfiguration.getTargetPreparers()) {
-            preparer.setUp(mDevice, mOtaDeviceBuild);
-        }
-    }
-
-    private void checkFields() {
-        if (mDevice == null) {
-            throw new IllegalArgumentException("missing device");
-        }
-        if (mConfiguration == null) {
-            throw new IllegalArgumentException("missing configuration");
-        }
-        if (mOtaDeviceBuild == null) {
-            throw new IllegalArgumentException("missing build info");
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isResumable() {
-        return mResumeMode && mResumable;
-    }
-
-    /**
-     * Actually install the OTA.
-     * @param listener
-     * @param otaBuild
-     * @return the amount of time in ms that the device took to boot after installing.
-     * @throws DeviceNotAvailableException
-     */
-    private BootTimeInfo installOta(ITestInvocationListener listener, IDeviceBuildInfo otaBuild)
-            throws DeviceNotAvailableException {
-        TestDescription test =
-                new TestDescription(getClass().getName(), String.format("apply_ota[%s]", mRunName));
-        Map<String, String> metrics = new HashMap<String, String>();
-        listener.testStarted(test);
-        try {
-            mKmsgReceiver.start();
-            try {
-                CLog.i("Pushing OTA package %s", otaBuild.getOtaPackageFile().getAbsolutePath());
-                Assert.assertTrue(mDevice.pushFile(otaBuild.getOtaPackageFile(), mPackageDataPath));
-                // this file needs to be uncrypted, since /data isn't mounted in recovery
-                // block.map should be empty since cache should be cleared
-                mDevice.pushString(mPackageDataPath + "\n", UNCRYPT_FILE_PATH);
-                // Flushing the file to flash.
-                mDevice.executeShellCommand("sync");
-
-                mUncryptDuration = doUncrypt(SocketFactory.getInstance(), listener);
-                metrics.put("uncrypt_duration", Long.toString(mUncryptDuration));
-                String installOtaCmd = String.format("--update_package=%s\n", BLOCK_MAP_PATH);
-                mDevice.pushString(installOtaCmd, RECOVERY_COMMAND_PATH);
-                CLog.i("Rebooting to install OTA");
-            } finally {
-                // Kmsg contents during the OTA will be capture in last_kmsg, so we can turn off the
-                // kmsg receiver now
-                mKmsgReceiver.postLog(listener);
-                mKmsgReceiver.stop();
-            }
-            // uncrypt is complete
-            if (mUncryptOnly) {
-                return new BootTimeInfo(-1, -1);
-            }
-            try {
-                mDevice.rebootIntoRecovery();
-            } catch (DeviceNotAvailableException e) {
-                // The device will only enter the RECOVERY state if it hits the recovery menu.
-                // Since we added a command to /cache/recovery/command, recovery mode executes the
-                // command rather than booting into the menu. While applying the update as a result
-                // of the installed command, the device reports its state as NOT_AVAILABLE. If the
-                // device *actually* becomes unavailable, we will catch the resulting DNAE in the
-                // next call to waitForDeviceOnline.
-                CLog.i("Didn't go to recovery, went straight to update");
-            }
-
-            mDevice.waitForDeviceNotAvailable(mMaxInstallOnlineTimeSec * 1000);
-            long start = System.currentTimeMillis();
-
-            try {
-                mDevice.waitForDeviceOnline(mMaxInstallOnlineTimeSec * 1000);
-            } catch (DeviceNotAvailableException e) {
-                CLog.e("Device %s did not come back online after recovery", mDevice.getSerialNumber());
-                listener.testFailed(test, e.getLocalizedMessage());
-                listener.testRunFailed("Device did not come back online after recovery");
-                sendUpdatePackage(listener, otaBuild);
-                throw new AssertionError("Device did not come back online after recovery");
-            }
-            double onlineTime = (System.currentTimeMillis() - start) / 1000.0;
-            try {
-                mDevice.waitForDeviceAvailable();
-            } catch (DeviceNotAvailableException e) {
-                CLog.e("Device %s did not boot up successfully after installing OTA",
-                        mDevice.getSerialNumber());
-                listener.testFailed(test, e.getLocalizedMessage());
-                listener.testRunFailed("Device failed to boot after OTA");
-                sendUpdatePackage(listener, otaBuild);
-                throw new AssertionError("Device failed to boot after OTA");
-            }
-            double availTime = (System.currentTimeMillis() - start) / 1000.0;
-            return new BootTimeInfo(availTime, onlineTime);
-        } finally {
-            listener.testEnded(test, TfMetricProtoUtil.upgradeConvert(metrics));
-        }
-    }
-
-    private InputStreamSource pullLogFile(String location)
-            throws DeviceNotAvailableException {
-        try {
-            // get recovery log
-            File destFile = FileUtil.createTempFile("recovery", "log");
-            boolean gotFile = mDevice.pullFile(location, destFile);
-            if (gotFile) {
-                return new FileInputStreamSource(destFile, true /* delete */);
-            }
-        } catch (IOException e) {
-            CLog.e("Failed to get recovery log from device %s", mDevice.getSerialNumber());
-            CLog.e(e);
-        }
-        return null;
-    }
-
-    protected void sendUpdatePackage(ITestInvocationListener listener, IDeviceBuildInfo otaBuild) {
-        InputStreamSource pkgSource = null;
-        try {
-            pkgSource = new FileInputStreamSource(otaBuild.getOtaPackageFile());
-            listener.testLog(mRunName + "_package", LogDataType.ZIP, pkgSource);
-        } catch (NullPointerException e) {
-            CLog.w("Couldn't save update package due to exception");
-            CLog.e(e);
-            return;
-        } finally {
-            StreamUtil.cancel(pkgSource);
-        }
-    }
-
-    protected double sendRecoveryLog(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        InputStreamSource lastLog = pullLogFile(LOG_RECOV);
-        InputStreamSource lastKmsg = pullLogFile(LOG_KMSG);
-        InputStreamSource blockMap = pullLogFile(BLOCK_MAP_PATH.substring(1));
-        double elapsedTime = 0;
-        // last_log contains a timing metric in its last line, capture it here and return it
-        // for the metrics map to report
-        try {
-            if (lastLog == null || lastKmsg == null) {
-                CLog.w(
-                        "Could not find last_log at directory %s, or last_kmsg at directory %s",
-                        LOG_RECOV, LOG_KMSG);
-                return elapsedTime;
-            }
-
-            try {
-                String[] lastLogLines = StreamUtil.getStringFromSource(lastLog).split("\n");
-                String endLine = lastLogLines[lastLogLines.length - 1];
-                elapsedTime = Double.parseDouble(
-                        endLine.substring(endLine.indexOf('[') + 1, endLine.indexOf(']')).trim());
-            } catch (IOException | NumberFormatException | NullPointerException e) {
-                CLog.w("Couldn't get elapsed time from last_log due to exception");
-                CLog.e(e);
-            }
-            listener.testLog(this.mRunName + "_recovery_log", LogDataType.TEXT,
-                    lastLog);
-            listener.testLog(this.mRunName + "_recovery_kmsg", LogDataType.TEXT,
-                    lastKmsg);
-            if (blockMap == null) {
-                CLog.w("Could not find block.map");
-            } else {
-                listener.testLog(this.mRunName + "_block_map", LogDataType.TEXT,
-                    blockMap);
-            }
-            return elapsedTime;
-        } finally {
-            StreamUtil.cancel(lastLog);
-            StreamUtil.cancel(lastKmsg);
-            StreamUtil.cancel(blockMap);
-        }
-    }
-
-    /**
-     * Uncrypt needs to attach to a socket before it will actually begin work, so we need to attach
-     * a socket to it.
-     *
-     * @return Elapse time of uncrypt
-     */
-    public long doUncrypt(
-            ISocketFactory sockets, @SuppressWarnings("unused") ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        // init has to start uncrypt or the socket will not be allocated
-        CLog.i("Starting uncrypt service");
-        mDevice.executeShellCommand("setprop ctl.start uncrypt");
-        try {
-            // This is a workaround for known issue with f2fs system.
-            CLog.i("Sleeping %d for uncrypt to be ready for socket connection.",
-                    SHORT_WAIT_UNCRYPT);
-            Thread.sleep(SHORT_WAIT_UNCRYPT);
-        } catch (InterruptedException e) {
-            CLog.i("Got interrupted when waiting to uncrypt file.");
-            Thread.currentThread().interrupt();
-        }
-        // MNC version of uncrypt does not require socket connection
-        if (mDevice.getApiLevel() < 24) {
-            CLog.i("Waiting for MNC uncrypt service finish");
-            return waitForUncrypt();
-        }
-        int port;
-        try {
-            port = getFreePort();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        // The socket uncrypt wants to run on is a local unix socket, so we can forward a tcp
-        // port to connect to it.
-        CLog.i("Connecting to uncrypt on port %d", port);
-        mDevice.executeAdbCommand("forward", "tcp:" + port, "localreserved:uncrypt");
-        // connect to uncrypt!
-        String hostname = "localhost";
-        long start = System.currentTimeMillis();
-        try (Socket uncrypt = sockets.createClientSocket(hostname, port)) {
-            connectSocket(uncrypt, hostname, port);
-            try (DataInputStream dis = new DataInputStream(uncrypt.getInputStream());
-                 DataOutputStream dos = new DataOutputStream(uncrypt.getOutputStream())) {
-                int status = Integer.MIN_VALUE;
-                while (true) {
-                    status = dis.readInt();
-                    if (isUncryptSuccess(status)) {
-                        dos.writeInt(0);
-                        break;
-                    }
-                }
-                CLog.i("Final uncrypt status: %d", status);
-                return System.currentTimeMillis() - start;
-            }
-        } catch (IOException e) {
-            CLog.e("Lost connection with uncrypt due to IOException:");
-            CLog.e(e);
-            return waitForUncrypt();
-        }
-    }
-
-    private long waitForUncrypt() throws DeviceNotAvailableException {
-        CLog.i("Continuing to watch uncrypt progress for %d ms", UNCRYPT_TIMEOUT);
-        long time = 0;
-        int lastStatus = -1;
-        long start = System.currentTimeMillis();
-        while ((time = System.currentTimeMillis() - start) < UNCRYPT_TIMEOUT) {
-            int status = readUncryptStatusFromFile();
-            if (isUncryptSuccess(status)) {
-                return time;
-            }
-            if (status != lastStatus) {
-                lastStatus = status;
-                CLog.d("uncrypt status: %d", status);
-            }
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException unused) {
-                Thread.currentThread().interrupt();
-            }
-        }
-        CLog.e("Uncrypt didn't finish, last status was %d", lastStatus);
-        throw new RuntimeException("Uncrypt didn't succeed after timeout");
-    }
-
-    private boolean isUncryptSuccess(int status) {
-        if (status == 100) {
-            CLog.i("Uncrypt finished successfully");
-            return true;
-        } else if (status > 100 || status < 0) {
-            CLog.e("Uncrypt returned error status %d", status);
-            assertThat(status, not(equalTo(100)));
-        }
-        return false;
-    }
-
-    protected int getFreePort() throws IOException {
-        try (ServerSocket sock = new ServerSocket(0)) {
-            return sock.getLocalPort();
-        }
-    }
-
-    /**
-     * Read the error status from uncrypt_status on device.
-     *
-     * @return 0 if uncrypt succeed, -1 if file not exists, specific error code otherwise.
-     */
-    protected int readUncryptStatusFromFile()
-            throws DeviceNotAvailableException {
-        try {
-            InputStreamSource status = pullLogFile(UNCRYPT_STATUS_FILE);
-            if (status == null) {
-                return -1;
-            }
-            String[] lastLogLines = StreamUtil.getStringFromSource(status).split("\n");
-            String endLine = lastLogLines[lastLogLines.length - 1];
-            if (endLine.toLowerCase().startsWith("uncrypt_error:")) {
-                String[] elements = endLine.split(":");
-                return Integer.parseInt(elements[1].trim());
-            } else {
-                // MNC device case
-                return Integer.parseInt(endLine.trim());
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    protected void connectSocket(Socket s, String host, int port) {
-        SocketAddress address = new InetSocketAddress(host, port);
-        boolean connected = false;
-        for (int i = 0; i < SOCKET_RETRY_CT; i++) {
-            try {
-                if (!s.isConnected()) {
-                    s.connect(address);
-                }
-                connected = true;
-                break;
-            } catch (IOException unused) {
-                try {
-                    Thread.sleep(1000);
-                    CLog.d("Uncrypt socket was not ready on iteration %d of %d, retrying", i,
-                            SOCKET_RETRY_CT);
-                } catch (InterruptedException e) {
-                    CLog.w("Interrupted while connecting uncrypt socket on iteration %d", i);
-                    Thread.currentThread().interrupt();
-                }
-            }
-        }
-        if (!connected) {
-            throw new RuntimeException("failed to connect uncrypt socket");
-        }
-    }
-
-    /**
-     * Provides a client socket. Allows for providing mock sockets to doUncrypt in unit testing.
-     */
-    public interface ISocketFactory {
-        public Socket createClientSocket(String host, int port) throws IOException;
-    }
-
-    /**
-     * Default implementation of {@link ISocketFactory}, which provides a {@link Socket}.
-     */
-    protected static class SocketFactory implements ISocketFactory {
-        private static SocketFactory sInstance;
-
-        private SocketFactory() {
-        }
-
-        public static SocketFactory getInstance() {
-            if (sInstance == null) {
-                sInstance = new SocketFactory();
-            }
-            return sInstance;
-        }
-
-        @Override
-        public Socket createClientSocket(String host, int port) throws IOException {
-            return new Socket(host, port);
-        }
-    }
-
-    private static class BootTimeInfo {
-        /**
-         * Time (s) until device is completely available
-         */
-        public double mAvailTime;
-        /**
-         * Time (s) until device is in "ONLINE" state
-         */
-        public double mOnlineTime;
-
-        public BootTimeInfo(double avail, double online) {
-            mAvailTime = avail;
-            mOnlineTime = online;
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/performance/tests/AppInstallTest.java b/prod-tests/src/com/android/performance/tests/AppInstallTest.java
deleted file mode 100644
index 427ae56..0000000
--- a/prod-tests/src/com/android/performance/tests/AppInstallTest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.AaptParser;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.junit.Assert;
-
-@OptionClass(alias = "app-install-perf")
-// Test framework that measures the install time for all apk files located under a given directory.
-// The test needs aapt to be in its path in order to determine the package name of the apk. The
-// package name is needed to clean up after the test is done.
-public class AppInstallTest implements IDeviceTest, IRemoteTest {
-
-    @Option(name = "test-apk-dir", description = "Directory that contains the test apks.",
-            importance= Option.Importance.ALWAYS)
-    private String mTestApkPath;
-
-    @Option(name = "test-label", description = "Unique test identifier label.")
-    private String mTestLabel = "AppInstallPerformance";
-
-    @Option(name = "test-start-delay",
-            description = "Delay in ms to wait for before starting the install test.")
-    private long mTestStartDelay = 60000;
-
-    // TODO: remove this once prod is updated.
-    @Option(name = "test-use-dex-metedata")
-    private boolean mUseDexMetadataMisspelled = false;
-    @Option(name = "test-dex-metedata-variant")
-    private String mDexMetadataVariantMisspelled = "";
-
-    @Option(
-        name = "test-use-dex-metadata",
-        description = "If the test should install the dex metadata files."
-    )
-    private boolean mUseDexMetadata = false;
-
-    @Option(name = "test-delay-between-installs",
-            description = "Delay in ms to wait for before starting the install test.")
-    private long mTestDelayBetweenInstalls = 5000;
-
-    @Option(
-        name = "test-dex-metadata-variant",
-        description =
-                "The dex metadata variant that should be used."
-                        + "When specified, the DM file name for foo.apk will be "
-                        + "constructed as fooVARIANT.dm"
-    )
-    private String mDexMetadataVariant = "";
-
-    @Option(name = "test-uninstall-after",
-            description = "If the apk should be uninstalled after.")
-    private boolean mUninstallAfter = true;
-
-    @Option(name = "package-list",
-            description = "If given, filters the apk files in the test dir based on the list of "
-                    + "packages. It checks that the apk name is packageName-version.apk")
-    private List<String> mPackages = new ArrayList<String>();
-
-    private ITestDevice mDevice;
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // Check if we need to use the obsolete, misspelled flags.
-        if (!mUseDexMetadata) {
-            mUseDexMetadata = mUseDexMetadataMisspelled;
-        }
-        if (mDexMetadataVariant.isEmpty()) {
-            mDexMetadataVariant = mDexMetadataVariantMisspelled;
-        }
-
-        // Delay test start time to give the background processes to finish.
-        if (mTestStartDelay > 0) {
-            RunUtil.getDefault().sleep(mTestStartDelay);
-        }
-
-        Assert.assertFalse(mTestApkPath.isEmpty());
-        File apkDir = new File(mTestApkPath);
-        Assert.assertTrue(apkDir.isDirectory());
-        // Find all apks in directory.
-        String[] files = apkDir.list();
-        Map<String, String> metrics = new HashMap<String, String> ();
-        try {
-            for (String fileName : files) {
-                if (!fileName.endsWith(".apk")) {
-                    CLog.d("Skipping non-apk %s", fileName);
-                    continue;
-                } else if (!matchesPackagesForInstall(fileName)) {
-                    CLog.d("Skipping apk %s", fileName);
-                    continue;
-                }
-                File file = new File(apkDir, fileName);
-                // Install app and measure time.
-                long installTime = installAndTime(file);
-                if (installTime > 0) {
-                    metrics.put(fileName, Long.toString(installTime));
-                }
-                RunUtil.getDefault().sleep(mTestDelayBetweenInstalls);
-            }
-        } finally {
-            reportMetrics(listener, mTestLabel, metrics);
-        }
-    }
-
-    /**
-     * Install file and time its install time. Cleans up after itself.
-     * @param packageFile apk file to install
-     * @return install time in msecs.
-     * @throws DeviceNotAvailableException
-     */
-    long installAndTime(File packageFile) throws DeviceNotAvailableException {
-        AaptParser parser = AaptParser.parse(packageFile);
-        if (parser == null) {
-            CLog.e("Failed to parse %s", packageFile);
-            return -1;
-        }
-        String packageName = parser.getPackageName();
-
-        String remotePath = "/data/local/tmp/" + packageFile.getName();
-        if (!mDevice.pushFile(packageFile, remotePath)) {
-            CLog.e("Failed to push %s", packageFile);
-            return -1;
-        }
-
-        String dmRemotePath = null;
-        if (mUseDexMetadata) {
-            File dexMetadataFile = getDexMetadataFile(packageFile);
-            dmRemotePath = "/data/local/tmp/" + dexMetadataFile.getName();
-            if (!mDevice.pushFile(dexMetadataFile, dmRemotePath)) {
-                CLog.e("Failed to push %s", dexMetadataFile);
-                return -1;
-            }
-        }
-
-        long start = System.currentTimeMillis();
-
-        // Create install session.
-        String output = mDevice.executeShellCommand("pm install-create -r -d -g");
-        if (!checkSuccess(output, packageFile, "install-create")) {
-            return -1;
-        }
-        String session = sessionFromInstallCreateOutput(output);
-
-        // Write the files to the session
-        output = mDevice.executeShellCommand(String.format(
-            "pm install-write %s %s %s", session, "base.apk", remotePath));
-        if (!checkSuccess(output, packageFile, "install-write base.apk")) {
-            return -1;
-        }
-
-        if (mUseDexMetadata) {
-            output = mDevice.executeShellCommand(String.format(
-                "pm install-write %s %s %s", session, "base.dm", dmRemotePath));
-            if (!checkSuccess(output, packageFile, "install-write base.dm")) {
-                return -1;
-            }
-        }
-
-        // Commit the session.
-        output = mDevice.executeShellCommand(String.format("pm install-commit %s", session));
-
-        long end = System.currentTimeMillis();
-        if (!checkSuccess(output, packageFile, "install-commit")) {
-            return -1;
-        }
-
-        // Remove the temp files.
-        mDevice.executeShellCommand(String.format("rm \"%s\"", remotePath));
-        if (mUseDexMetadata) {
-            mDevice.executeShellCommand(String.format("rm \"%s\"", dmRemotePath));
-        }
-
-        // Uninstall the package if needed.
-        if (mUninstallAfter && packageName != null) {
-            CLog.d("Uninstalling: %s", packageName);
-            mDevice.uninstallPackage(packageName);
-        }
-        return end - start;
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @param runName the test name
-     * @param metrics the {@link Map} that contains metrics for the given test
-     */
-    void reportMetrics(ITestInvocationListener listener, String runName,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics: %s", metrics);
-        listener.testRunStarted(runName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    /**
-     * Extracts the session id from 'pm install-create' output.
-     * Usual output is: "Success: created install session [710542260]"
-     */
-    private String sessionFromInstallCreateOutput(String output) {
-        int start = output.indexOf("[");
-        int end = output.indexOf("]");
-        return output.substring(start + 1, end);
-    }
-
-    /**
-     * Verifies that the output contains the "Success" mark.
-     */
-    private boolean checkSuccess(String output, File packageFile, String stepForErrorLog) {
-        if (output == null || output.indexOf("Success") == -1) {
-            CLog.e("Failed to execute [%s] for package %s with error %s",
-                stepForErrorLog, packageFile, output);
-            return false;
-        }
-        return true;
-    }
-
-    private File getDexMetadataFile(File packageFile) {
-        return new File(packageFile.getAbsolutePath().replace(".apk", mDexMetadataVariant + ".dm"));
-    }
-
-    private boolean matchesPackagesForInstall(String fileName) {
-        if (mPackages.isEmpty()) {
-            return true;
-        }
-
-        for (String pkg : mPackages) {
-            // "-" is the version delimiter and ensures we don't match for example
-            // com.google.android.apps.docs for com.google.android.apps.docs.slides.
-            if (fileName.contains(pkg + "-")) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/prod-tests/src/com/android/performance/tests/AppTransitionTests.java b/prod-tests/src/com/android/performance/tests/AppTransitionTests.java
deleted file mode 100644
index e3aff45..0000000
--- a/prod-tests/src/com/android/performance/tests/AppTransitionTests.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.performance.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.loganalysis.item.LatencyItem;
-import com.android.loganalysis.item.TransitionDelayItem;
-import com.android.loganalysis.parser.EventsLogParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.LogcatReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.SimpleStats;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.ZipUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test that drives the transition delays during different user behavior like
- * cold launch from launcher, hot launch from recent etc.This class invokes
- * the instrumentation test apk that does the transition and captures the events logs
- * during the transition and parse them and report in the dashboard.
- */
-public class AppTransitionTests implements IRemoteTest, IDeviceTest {
-
-    private static final String PACKAGE_NAME = "com.android.apptransition.tests";
-    private static final String CLASS_NAME = "com.android.apptransition.tests.AppTransitionTests";
-    private static final String TEST_COLD_LAUNCH = "testColdLaunchFromLauncher";
-    private static final String TEST_HOT_LAUNCH = "testHotLaunchFromLauncher";
-    private static final String TEST_APP_TO_HOME = "testAppToHome";
-    private static final String TEST_APP_TO_RECENT = "testAppToRecents";
-    private static final String TEST_LATENCY = "testLatency";
-    private static final String TEST_HOT_LAUNCH_FROM_RECENTS = "testHotLaunchFromRecents";
-    private static final String DROP_CACHE_SCRIPT_FILE = "dropCache";
-    private static final String SCRIPT_EXTENSION = ".sh";
-    private static final String DROP_CACHE_CMD = "echo 3 > /proc/sys/vm/drop_caches";
-    private static final String DEVICE_TEMPORARY_DIR_PATH = "/data/local/tmp/";
-    private static final String REMOVE_CMD = "rm -rf %s/%s";
-    private static final String EVENTS_CMD = "logcat -v threadtime -b events";
-    private static final String EVENTS_CLEAR_CMD = "logcat -v threadtime -b events -c";
-    private static final String EVENTS_LOG = "events_log";
-    private static final long EVENTS_LOGCAT_SIZE = 80 * 1024 * 1024;
-
-    @Option(name = "cold-apps", description = "Apps used for cold app launch"
-            + " transition delay testing from launcher screen.")
-    private String mColdLaunchApps = null;
-
-    @Option(name = "hot-apps", description = "Apps used for hot app launch"
-            + " transition delay testing from launcher screen.")
-    private String mHotLaunchApps = null;
-
-    @Option(name = "pre-launch-apps", description = "Apps used for populating the"
-            + " recents apps list before starting app_to_recents or hot_app_from_recents"
-            + " testing.")
-    private String mPreLaunchApps = null;
-
-    @Option(name = "apps-to-recents", description = "Apps used for app to recents"
-            + " transition delay testing.")
-    private String mAppToRecents = null;
-
-    @Option(name = "hot-apps-from-recents", description = "Apps used for hot"
-            + " launch app from recents list transition delay testing.")
-    private String mRecentsToApp = null;
-
-    @Option(name = "launch-iteration", description = "Iterations for launching each app to"
-            + "test the transition delay.")
-    private int mLaunchIteration = 10;
-
-    @Option(name = "trace-directory", description = "Directory to store the trace files"
-            + "while testing ther app transition delay.")
-    private String mTraceDirectory = null;
-
-    @Option(name = "runner", description = "The instrumentation test runner class name to use.")
-    private String mRunnerName = "android.support.test.runner.AndroidJUnitRunner";
-
-    @Option(name = "run-arg",
-            description = "Additional test specific arguments to provide.")
-    private Map<String, String> mArgMap = new LinkedHashMap<String, String>();
-
-    @Option(name = "launcher-activity", description = "Home activity name")
-    private String mLauncherActivity = ".NexusLauncherActivity";
-
-    @Option(name = "class",
-            description = "test class to run, may be repeated; multiple classess will be run"
-                    + " in the same order as provided in command line")
-    private List<String> mClasses = new ArrayList<String>();
-
-    @Option(name = "package",
-            description = "The manifest package name of the UI test package")
-    private String mPackage = "com.android.apptransition.tests";
-
-    @Option(name = "latency-iteration", description = "Iterations to be used in the latency tests.")
-    private int mLatencyIteration = 10;
-
-    @Option(name = "timeout",
-            description = "Aborts the test run if any test takes longer than the specified number "
-                    + "of milliseconds. For no timeout, set to 0.", isTimeVal = true)
-    private long mTestTimeout = 45 * 60 * 1000;  // default to 45 minutes
-
-    private ITestDevice mDevice = null;
-    private IRemoteAndroidTestRunner mRunner = null;
-    private CollectingTestListener mLaunchListener = null;
-    private LogcatReceiver mLaunchEventsLogs = null;
-    private EventsLogParser mEventsLogParser = new EventsLogParser();
-    private ITestInvocationListener mListener = null;
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-
-        addDropCacheScriptFile();
-        mListener = listener;
-
-        if (null != mColdLaunchApps && !mColdLaunchApps.isEmpty()) {
-            try {
-                mRunner = createRemoteAndroidTestRunner(TEST_COLD_LAUNCH, mColdLaunchApps, null);
-                mLaunchListener = new CollectingTestListener();
-                mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
-                        0);
-                startEventsLogs(mLaunchEventsLogs, TEST_COLD_LAUNCH);
-                runTests();
-                analyzeColdLaunchDelay(parseTransitionDelayInfo());
-            } finally {
-                stopEventsLogs(mLaunchEventsLogs, TEST_COLD_LAUNCH);
-                if (isTraceDirEnabled()) {
-                    uploadTraceFiles(listener, TEST_COLD_LAUNCH);
-                }
-            }
-        }
-
-        if (null != mHotLaunchApps && !mHotLaunchApps.isEmpty()) {
-            try {
-                mRunner = createRemoteAndroidTestRunner(TEST_HOT_LAUNCH, mHotLaunchApps, null);
-                mLaunchListener = new CollectingTestListener();
-                mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
-                        0);
-                startEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH);
-                runTests();
-                analyzeHotLaunchDelay(parseTransitionDelayInfo());
-            } finally {
-                stopEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH);
-                if (isTraceDirEnabled()) {
-                    uploadTraceFiles(listener, TEST_HOT_LAUNCH);
-                }
-            }
-        }
-
-        if ((null != mAppToRecents && !mAppToRecents.isEmpty()) &&
-                (null != mPreLaunchApps && !mPreLaunchApps.isEmpty())) {
-            try {
-                mRunner = createRemoteAndroidTestRunner(TEST_APP_TO_RECENT, mAppToRecents,
-                        mPreLaunchApps);
-                mLaunchListener = new CollectingTestListener();
-                mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
-                        0);
-                startEventsLogs(mLaunchEventsLogs, TEST_APP_TO_RECENT);
-                runTests();
-                analyzeAppToRecentsDelay(parseTransitionDelayInfo());
-            } finally {
-                stopEventsLogs(mLaunchEventsLogs, TEST_APP_TO_RECENT);
-                if (isTraceDirEnabled()) {
-                    uploadTraceFiles(listener, TEST_APP_TO_RECENT);
-                }
-            }
-        }
-
-        if ((null != mRecentsToApp && !mRecentsToApp.isEmpty()) &&
-                (null != mPreLaunchApps && !mPreLaunchApps.isEmpty())) {
-            try {
-                mRunner = createRemoteAndroidTestRunner(TEST_HOT_LAUNCH_FROM_RECENTS,
-                        mRecentsToApp,
-                        mPreLaunchApps);
-                mLaunchListener = new CollectingTestListener();
-                mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
-                        0);
-                startEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH_FROM_RECENTS);
-                runTests();
-                analyzeRecentsToAppDelay(parseTransitionDelayInfo());
-            } finally {
-                stopEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH_FROM_RECENTS);
-                if (isTraceDirEnabled()) {
-                    uploadTraceFiles(listener, TEST_HOT_LAUNCH_FROM_RECENTS);
-                }
-            }
-        }
-
-        if (!mClasses.isEmpty()) {
-            try {
-                mRunner = createTestRunner();
-                mLaunchListener = new CollectingTestListener();
-                mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
-                        0);
-                startEventsLogs(mLaunchEventsLogs, TEST_LATENCY);
-                runTests();
-                analyzeLatencyInfo(parseLatencyInfo());
-            } finally {
-                stopEventsLogs(mLaunchEventsLogs, TEST_LATENCY);
-                if (isTraceDirEnabled()) {
-                    uploadTraceFiles(listener, TEST_LATENCY);
-                }
-            }
-        }
-
-    }
-
-    private void runTests() throws DeviceNotAvailableException {
-        mDevice.runInstrumentationTests(mRunner, mLaunchListener);
-        final TestRunResult runResults = mLaunchListener.getCurrentRunResults();
-        if (runResults.isRunFailure()) {
-            throw new RuntimeException("Error: test run failed!");
-        }
-        if (runResults.hasFailedTests()) {
-            throw new RuntimeException("Error: some tests failed!");
-        }
-    }
-
-    /**
-     * Push drop cache script file to test device used for clearing the cache between the app
-     * launches.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    private void addDropCacheScriptFile() throws DeviceNotAvailableException {
-        File scriptFile = null;
-        try {
-            scriptFile = FileUtil.createTempFile(DROP_CACHE_SCRIPT_FILE, SCRIPT_EXTENSION);
-            FileUtil.writeToFile(DROP_CACHE_CMD, scriptFile);
-            getDevice().pushFile(scriptFile, String.format("%s%s.sh",
-                    DEVICE_TEMPORARY_DIR_PATH, DROP_CACHE_SCRIPT_FILE));
-        } catch (IOException ioe) {
-            CLog.e("Unable to create the Script file");
-            CLog.e(ioe);
-        }
-        getDevice().executeShellCommand(String.format("chmod 755 %s%s.sh",
-                DEVICE_TEMPORARY_DIR_PATH, DROP_CACHE_SCRIPT_FILE));
-        scriptFile.delete();
-    }
-
-    /**
-     * Method to create the runner with given list of arguments
-     *
-     * @return the {@link IRemoteAndroidTestRunner} to use.
-     * @throws DeviceNotAvailableException
-     */
-    IRemoteAndroidTestRunner createRemoteAndroidTestRunner(String testName, String launchApps,
-            String preLaunchApps) throws DeviceNotAvailableException {
-        RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
-                PACKAGE_NAME, mRunnerName, mDevice.getIDevice());
-        runner.setMethodName(CLASS_NAME, testName);
-        runner.addInstrumentationArg("launch_apps", launchApps);
-        runner.setMaxTimeout(mTestTimeout, TimeUnit.MILLISECONDS);
-        if (null != preLaunchApps && !preLaunchApps.isEmpty()) {
-            runner.addInstrumentationArg("pre_launch_apps", preLaunchApps);
-        }
-        runner.addInstrumentationArg("launch_iteration", Integer.toString(mLaunchIteration));
-        for (Map.Entry<String, String> entry : getTestRunArgMap().entrySet()) {
-            runner.addInstrumentationArg(entry.getKey(), entry.getValue());
-        }
-        if (isTraceDirEnabled()) {
-            mDevice.executeShellCommand(String.format("rm -rf %s/%s", mTraceDirectory, testName));
-            runner.addInstrumentationArg("trace_directory", mTraceDirectory);
-        }
-        return runner;
-    }
-
-    /**
-     * Method to create the runner with given runner name, package and list of classes.
-     * @return the {@link IRemoteAndroidTestRunner} to use.
-     * @throws DeviceNotAvailableException
-     */
-    IRemoteAndroidTestRunner createTestRunner() throws DeviceNotAvailableException {
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mPackage, mRunnerName,
-                getDevice().getIDevice());
-        if (!mClasses.isEmpty()) {
-            runner.setClassNames(mClasses.toArray(new String[] {}));
-        }
-        runner.addInstrumentationArg("iteration_count", Integer.toString(mLatencyIteration));
-        for (Map.Entry<String, String> entry : getTestRunArgMap().entrySet()) {
-            runner.addInstrumentationArg(entry.getKey(), entry.getValue());
-        }
-        if (isTraceDirEnabled()) {
-            mDevice.executeShellCommand(String.format("rm -rf %s/%s", mTraceDirectory,
-                    TEST_LATENCY));
-            runner.addInstrumentationArg("trace_directory",
-                    String.format("%s/%s", mTraceDirectory, TEST_LATENCY));
-        }
-        return runner;
-    }
-
-
-    /**
-     * Start the events logcat
-     *
-     * @param logReceiver
-     * @param testName
-     * @throws DeviceNotAvailableException
-     */
-    private void startEventsLogs(LogcatReceiver logReceiver, String testName)
-            throws DeviceNotAvailableException {
-        getDevice().clearLogcat();
-        getDevice().executeShellCommand(EVENTS_CLEAR_CMD);
-        logReceiver.start();
-    }
-
-    /**
-     * Stop the events logcat and upload the data to sponge
-     *
-     * @param logReceiver
-     */
-    private void stopEventsLogs(LogcatReceiver logReceiver,String launchDesc) {
-        try (InputStreamSource logcatData = logReceiver.getLogcatData()) {
-            mListener.testLog(
-                    String.format("%s-%s", EVENTS_LOG, launchDesc), LogDataType.TEXT, logcatData);
-        } finally {
-            logReceiver.stop();
-        }
-    }
-
-    /**
-     * Pull the trace files if exist under destDirectory and log it.
-     *
-     * @param listener test result listener
-     * @param srcDirectory source directory in the device where the files are copied to the local
-     *     tmp directory
-     * @param subFolderName to store the files corresponding to the test
-     * @throws DeviceNotAvailableException
-     * @throws IOException
-     */
-    private void logTraceFiles(
-            ITestInvocationListener listener, String srcDirectory, String subFolderName)
-            throws DeviceNotAvailableException, IOException {
-        File tmpDestDir = null;
-        FileInputStreamSource streamSource = null;
-        File zipFile = null;
-        try {
-            tmpDestDir = FileUtil.createTempDir(subFolderName);
-            IFileEntry srcDir = mDevice.getFileEntry(String.format("%s/%s",
-                    srcDirectory, subFolderName));
-            // Files are retrieved from source directory in device
-            if (srcDir != null) {
-                for (IFileEntry file : srcDir.getChildren(false)) {
-                    File pulledFile = new File(tmpDestDir, file.getName());
-                    if (!mDevice.pullFile(file.getFullPath(), pulledFile)) {
-                        throw new IOException(
-                                "Not able to pull the file from test device");
-                    }
-                }
-                zipFile = ZipUtil.createZip(tmpDestDir);
-                streamSource = new FileInputStreamSource(zipFile);
-                listener.testLog(tmpDestDir.getName(), LogDataType.ZIP, streamSource);
-            }
-        } finally {
-            FileUtil.recursiveDelete(tmpDestDir);
-            StreamUtil.cancel(streamSource);
-            FileUtil.deleteFile(zipFile);
-        }
-    }
-
-    /**
-     * To upload the trace files stored in the traceDirectory in device to sponge.
-     *
-     * @param listener
-     * @param subFolderName
-     * @throws DeviceNotAvailableException
-     */
-    private void uploadTraceFiles(ITestInvocationListener listener, String subFolderName)
-            throws DeviceNotAvailableException {
-        try {
-            logTraceFiles(listener, mTraceDirectory, subFolderName);
-        } catch (IOException ioe) {
-            CLog.e("Problem in uploading the log files.");
-            CLog.e(ioe);
-        }
-        mDevice.executeShellCommand(String.format(REMOVE_CMD, mTraceDirectory,
-                subFolderName));
-    }
-
-    /**
-     * Returns false if the traceDirectory is not set.
-     */
-    private boolean isTraceDirEnabled() {
-        return (null != mTraceDirectory && !mTraceDirectory.isEmpty());
-    }
-
-    /**
-     * To parse the transition delay info from the events log.
-     */
-    private List<TransitionDelayItem> parseTransitionDelayInfo() {
-        List<TransitionDelayItem> transitionDelayItems = null;
-        try (InputStreamSource logcatData = mLaunchEventsLogs.getLogcatData();
-                InputStream logcatStream = logcatData.createInputStream();
-                InputStreamReader streamReader = new InputStreamReader(logcatStream);
-                BufferedReader reader = new BufferedReader(streamReader)) {
-            transitionDelayItems = mEventsLogParser.parseTransitionDelayInfo(reader);
-        } catch (IOException e) {
-            CLog.e("Problem in parsing the transition delay items from events log");
-            CLog.e(e);
-        }
-        return transitionDelayItems;
-    }
-
-    /**
-     * To parse the latency info from the events log.
-     */
-    private List<LatencyItem> parseLatencyInfo() {
-        List<LatencyItem> latencyItems = null;
-        try (InputStreamSource logcatData = mLaunchEventsLogs.getLogcatData();
-                InputStream logcatStream = logcatData.createInputStream();
-                InputStreamReader streamReader = new InputStreamReader(logcatStream);
-                BufferedReader reader = new BufferedReader(streamReader)) {
-            latencyItems = mEventsLogParser.parseLatencyInfo(reader);
-        } catch (IOException e) {
-            CLog.e("Problem in parsing the latency items from events log");
-            CLog.e(e);
-        }
-        return latencyItems;
-    }
-
-    /**
-     * Analyze and report the cold launch transition delay from launcher screen.
-     *
-     * @param transitionDelayItems
-     */
-    private void analyzeColdLaunchDelay(List<TransitionDelayItem> transitionDelayItems) {
-        Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
-        Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
-        // Handle launcher to cold app launch transition
-        for (TransitionDelayItem delayItem : transitionDelayItems) {
-            if (cmpNameAppMap.containsKey(delayItem.getComponentName())) {
-                String appName = cmpNameAppMap.get(delayItem.getComponentName());
-                if (delayItem.getStartingWindowDelay() != null) {
-                    if (appKeyTransitionDelayMap.containsKey(appName)) {
-                        appKeyTransitionDelayMap.get(appName).add(
-                                delayItem.getStartingWindowDelay());
-                    } else {
-                        List<Long> delayTimeList = new ArrayList<Long>();
-                        delayTimeList.add(delayItem.getStartingWindowDelay());
-                        appKeyTransitionDelayMap.put(appName, delayTimeList);
-                    }
-                }
-            }
-        }
-        removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
-        computeAndUploadResults(TEST_COLD_LAUNCH, appKeyTransitionDelayMap);
-    }
-
-    /**
-     * Analyze and report the hot launch transition delay from launcher and app
-     * to home transition delay. Keep track of launcher to app transition delay
-     * which immediately followed by app to home transition. Skip the
-     * intitial cold launch on the apps.
-     *
-     * @param transitionDelayItems
-     */
-    private void analyzeHotLaunchDelay(List<TransitionDelayItem> transitionDelayItems) {
-        Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
-        Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
-        Map<String, List<Long>> appToHomeKeyTransitionDelayMap = new HashMap<>();
-        String prevAppName = null;
-        for (TransitionDelayItem delayItem : transitionDelayItems) {
-            // Handle app to home transition
-            if (null != prevAppName) {
-                if (delayItem.getComponentName().contains(mLauncherActivity)) {
-                    if (appToHomeKeyTransitionDelayMap.containsKey(prevAppName)) {
-                        appToHomeKeyTransitionDelayMap
-                                .get(prevAppName)
-                                .add(delayItem.getWindowDrawnDelay());
-                    } else {
-                        List<Long> delayTimeList = new ArrayList<Long>();
-                        delayTimeList.add(delayItem.getWindowDrawnDelay());
-                        appToHomeKeyTransitionDelayMap.put(prevAppName, delayTimeList);
-                    }
-                    prevAppName = null;
-                }
-                continue;
-            }
-            // Handle launcher to hot app launch transition
-            if (cmpNameAppMap.containsKey(delayItem.getComponentName())) {
-                // Not to consider the first cold launch for the app.
-                if (delayItem.getStartingWindowDelay() != null) {
-                    continue;
-                }
-                String appName = cmpNameAppMap.get(delayItem.getComponentName());
-                if (appKeyTransitionDelayMap.containsKey(appName)) {
-                    appKeyTransitionDelayMap.get(appName).add(delayItem.getTransitionDelay());
-                } else {
-                    List<Long> delayTimeList = new ArrayList<Long>();
-                    delayTimeList.add(delayItem.getTransitionDelay());
-                    appKeyTransitionDelayMap.put(appName, delayTimeList);
-                }
-                prevAppName = appName;
-            }
-        }
-        // Remove the first hot launch info through intents
-        removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
-        computeAndUploadResults(TEST_HOT_LAUNCH, appKeyTransitionDelayMap);
-        removeAdditionalLaunchInfo(appToHomeKeyTransitionDelayMap);
-        computeAndUploadResults(TEST_APP_TO_HOME, appToHomeKeyTransitionDelayMap);
-    }
-
-    /**
-     * Analyze and report app to recents transition delay info.
-     *
-     * @param transitionDelayItems
-     */
-    private void analyzeAppToRecentsDelay(List<TransitionDelayItem> transitionDelayItems) {
-        Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
-        Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
-        String prevAppName = null;
-        for (TransitionDelayItem delayItem : transitionDelayItems) {
-            if (delayItem.getComponentName().contains(mLauncherActivity)) {
-                if (appKeyTransitionDelayMap.containsKey(prevAppName)) {
-                    appKeyTransitionDelayMap.get(prevAppName).add(delayItem.getWindowDrawnDelay());
-                } else {
-                    if (null != prevAppName) {
-                        List<Long> delayTimeList = new ArrayList<Long>();
-                        delayTimeList.add(delayItem.getWindowDrawnDelay());
-                        appKeyTransitionDelayMap.put(prevAppName, delayTimeList);
-                    }
-                }
-                prevAppName = null;
-                continue;
-            }
-
-            if (cmpNameAppMap.containsKey(delayItem.getComponentName())) {
-                prevAppName = cmpNameAppMap.get(delayItem.getComponentName());
-            }
-        }
-        //Removing the first cold launch to recents transition delay.
-        removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
-        computeAndUploadResults(TEST_APP_TO_RECENT, appKeyTransitionDelayMap);
-    }
-
-    /**
-     * Analyze and report recents to hot app launch delay info. Skip the intitial cold
-     * launch transition delay on the apps. Also the first launch cannot always be the
-     * cold launch because the apps could be part of preapps list. The transition delay is
-     * tracked based on recents to apps transition delay items.
-     *
-     * @param transitionDelayItems
-     */
-    private void analyzeRecentsToAppDelay(List<TransitionDelayItem> transitionDelayItems) {
-        Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
-        Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
-        boolean isRecentsBefore = false;
-        for (TransitionDelayItem delayItem : transitionDelayItems) {
-            if (delayItem.getComponentName().contains(mLauncherActivity)) {
-                isRecentsBefore = true;
-                continue;
-            }
-            if (isRecentsBefore && cmpNameAppMap.containsKey(delayItem.getComponentName())) {
-                if (delayItem.getStartingWindowDelay() != null) {
-                    continue;
-                }
-                String appName = cmpNameAppMap.get(delayItem.getComponentName());
-                if (appKeyTransitionDelayMap.containsKey(appName)) {
-                    appKeyTransitionDelayMap.get(appName).add(delayItem.getTransitionDelay());
-                } else {
-                    List<Long> delayTimeList = new ArrayList<Long>();
-                    delayTimeList.add(delayItem.getTransitionDelay());
-                    appKeyTransitionDelayMap.put(appName, delayTimeList);
-                }
-            }
-            isRecentsBefore = false;
-        }
-        removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
-        computeAndUploadResults(TEST_HOT_LAUNCH_FROM_RECENTS, appKeyTransitionDelayMap);
-    }
-
-
-    /**
-     * Analyze and report different latency delay items captured from the events log
-     * file while running the LatencyTests
-     * @param latencyItemsList
-     */
-    private void analyzeLatencyInfo(List<LatencyItem> latencyItemsList) {
-        Map<String, List<Long>> actionDelayListMap = new HashMap<>();
-        for (LatencyItem delayItem : latencyItemsList) {
-            if (actionDelayListMap.containsKey(Integer.toString(delayItem.getActionId()))) {
-                actionDelayListMap.get(Integer.toString(delayItem.getActionId())).add(
-                        delayItem.getDelay());
-            } else {
-                List<Long> delayList = new ArrayList<Long>();
-                delayList.add(delayItem.getDelay());
-                actionDelayListMap.put(Integer.toString(delayItem.getActionId()), delayList);
-            }
-        }
-        computeAndUploadResults(TEST_LATENCY, actionDelayListMap);
-    }
-
-
-    /**
-     * To remove the additional launch info at the beginning of the test.
-     *
-     * @param appKeyTransitionDelayMap
-     */
-    private void removeAdditionalLaunchInfo(Map<String, List<Long>> appKeyTransitionDelayMap) {
-        for (List<Long> delayList : appKeyTransitionDelayMap.values()) {
-            while (delayList.size() > mLaunchIteration) {
-                delayList.remove(0);
-            }
-        }
-    }
-
-    /**
-     * To compute the min,max,avg,median and std_dev on the transition delay for each app
-     * and upload the metrics
-     *
-     * @param reportingKey
-     * @param appKeyTransitionDelayMap
-     */
-    private void computeAndUploadResults(String reportingKey,
-            Map<String, List<Long>> appKeyTransitionDelayMap) {
-        CLog.i(String.format("Testing : %s", reportingKey));
-        Map<String, String> activityMetrics = new HashMap<String, String>();
-        for (String appNameKey : appKeyTransitionDelayMap.keySet()) {
-            List<Long> delayList = appKeyTransitionDelayMap.get(appNameKey);
-            StringBuffer delayListStr = new StringBuffer();
-            for (Long delayItem : delayList) {
-                delayListStr.append(delayItem);
-                delayListStr.append(",");
-            }
-            CLog.i("%s : %s", appNameKey, delayListStr);
-            SimpleStats stats = new SimpleStats();
-            for (Long delay : delayList) {
-                stats.add(Double.parseDouble(delay.toString()));
-            }
-            activityMetrics.put(appNameKey + "_min", stats.min().toString());
-            activityMetrics.put(appNameKey + "_max", stats.max().toString());
-            activityMetrics.put(appNameKey + "_avg", stats.mean().toString());
-            activityMetrics.put(appNameKey + "_median", stats.median().toString());
-            activityMetrics.put(appNameKey + "_std_dev", stats.stdev().toString());
-        }
-        mListener.testRunStarted(reportingKey, 0);
-        mListener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(activityMetrics));
-    }
-
-    /**
-     * Retrieve the map of appname,componenetname from the results.
-     */
-    private Map<String,String> getAppComponentInfoMap() {
-        Collection<TestResult> testResultsCollection = mLaunchListener
-                .getCurrentRunResults().getTestResults().values();
-        List<TestResult> testResults = new ArrayList<>(
-                testResultsCollection);
-        return testResults.get(0).getMetrics();
-    }
-
-    /**
-     * Reverse and returnthe given appName,componentName info map to componenetName,appName info
-     * map.
-     */
-    private Map<String, String> reverseAppCmpInfoMap(Map<String, String> appNameCmpNameMap) {
-        Map<String, String> cmpNameAppNameMap = new HashMap<String, String>();
-        for (Map.Entry<String, String> entry : appNameCmpNameMap.entrySet()) {
-            cmpNameAppNameMap.put(entry.getValue(), entry.getKey());
-        }
-        return cmpNameAppNameMap;
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * @return the arguments map to pass to the test runner.
-     */
-    public Map<String, String> getTestRunArgMap() {
-        return mArgMap;
-    }
-
-    /**
-     * @param runArgMap the arguments to pass to the test runner.
-     */
-    public void setTestRunArgMap(Map<String, String> runArgMap) {
-        mArgMap = runArgMap;
-    }
-
-}
-
diff --git a/prod-tests/src/com/android/performance/tests/EmmcPerformanceTest.java b/prod-tests/src/com/android/performance/tests/EmmcPerformanceTest.java
deleted file mode 100644
index 6e8f61a..0000000
--- a/prod-tests/src/com/android/performance/tests/EmmcPerformanceTest.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.AbiFormatter;
-import com.android.tradefed.util.SimplePerfResult;
-import com.android.tradefed.util.SimplePerfUtil;
-import com.android.tradefed.util.SimplePerfUtil.SimplePerfType;
-import com.android.tradefed.util.SimpleStats;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * This test is targeting eMMC performance on read/ write.
- */
-public class EmmcPerformanceTest implements IDeviceTest, IRemoteTest {
-    private enum TestType {
-        DD,
-        RANDOM;
-    }
-
-    private static final String RUN_KEY = "emmc_performance_tests";
-
-    private static final String SEQUENTIAL_READ_KEY = "sequential_read";
-    private static final String SEQUENTIAL_WRITE_KEY = "sequential_write";
-    private static final String RANDOM_READ_KEY = "random_read";
-    private static final String RANDOM_WRITE_KEY = "random_write";
-    private static final String PERF_RANDOM = "/data/local/tmp/rand_emmc_perf|#ABI32#|";
-
-    private static final Pattern DD_PATTERN = Pattern.compile(
-            "\\d+ bytes transferred in \\d+\\.\\d+ secs \\((\\d+) bytes/sec\\)");
-
-    private static final Pattern EMMC_RANDOM_PATTERN = Pattern.compile(
-            "(\\d+) (\\d+)byte iops/sec");
-    private static final int BLOCK_SIZE = 1048576;
-    private static final int SEQ_COUNT = 200;
-
-    @Option(name = "cpufreq", description = "The path to the cpufreq directory on the DUT.")
-    private String mCpufreq = "/sys/devices/system/cpu/cpu0/cpufreq";
-
-    @Option(name = "auto-discover-cache-info",
-            description =
-                    "Indicate if test should attempt auto discover cache path and partition size "
-                            + "from the test device. Default to be false, ie. manually set "
-                            + "cache-device and cache-partition-size, or use default."
-                            + " If fail to discover, it will fallback to what is set in "
-                            + "cache-device")
-    private boolean mAutoDiscoverCacheInfo = false;
-
-    @Option(name = "cache-device", description = "The path to the cache block device on the DUT." +
-            "  Nakasi: /dev/block/platform/sdhci-tegra.3/by-name/CAC\n" +
-            "  Prime: /dev/block/platform/omap/omap_hsmmc.0/by-name/cache\n" +
-            "  Stingray: /dev/block/platform/sdhci-tegra.3/by-name/cache\n" +
-            "  Crespo: /dev/block/platform/s3c-sdhci.0/by-name/userdata\n",
-            importance = Importance.IF_UNSET)
-    private String mCache = null;
-
-    @Option(name = "iterations", description = "The number of iterations to run")
-    private int mIterations = 100;
-
-    @Option(name = AbiFormatter.FORCE_ABI_STRING,
-            description = AbiFormatter.FORCE_ABI_DESCRIPTION,
-            importance = Importance.IF_UNSET)
-    private String mForceAbi = null;
-
-    @Option(name = "cache-partition-size", description = "Cache partiton size in MB")
-    private static int mCachePartitionSize = 100;
-
-    @Option(name = "simpleperf-mode",
-            description = "Whether use simpleperf to get low level metrics")
-    private boolean mSimpleperfMode = false;
-
-    @Option(name = "simpleperf-argu", description = "simpleperf arguments")
-    private List<String> mSimpleperfArgu = new ArrayList<String>();
-
-    ITestDevice mTestDevice = null;
-    SimplePerfUtil mSpUtil = null;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        try {
-            setUp();
-
-            listener.testRunStarted(RUN_KEY, 5);
-            long beginTime = System.currentTimeMillis();
-            Map<String, String> metrics = new HashMap<String, String>();
-
-            runSequentialRead(mIterations, listener, metrics);
-            runSequentialWrite(mIterations, listener, metrics);
-            // FIXME: Figure out cache issues with random read and reenable test.
-            // runRandomRead(mIterations, listener, metrics);
-            // runRandomWrite(mIterations, listener, metrics);
-
-            CLog.d("Metrics: %s", metrics.toString());
-            listener.testRunEnded(
-                    (System.currentTimeMillis() - beginTime),
-                    TfMetricProtoUtil.upgradeConvert(metrics));
-        } finally {
-            cleanUp();
-        }
-    }
-
-    /**
-     * Run the sequential read test.
-     */
-    private void runSequentialRead(int iterations, ITestInvocationListener listener,
-            Map<String, String> metrics) throws DeviceNotAvailableException {
-        String command = String.format("dd if=%s of=/dev/null bs=%d count=%d", mCache, BLOCK_SIZE,
-                SEQ_COUNT);
-        runTest(SEQUENTIAL_READ_KEY, command, TestType.DD, true, iterations, listener, metrics);
-    }
-
-    /**
-     * Run the sequential write test.
-     */
-    private void runSequentialWrite(int iterations, ITestInvocationListener listener,
-            Map<String, String> metrics) throws DeviceNotAvailableException {
-        String command = String.format("dd if=/dev/zero of=%s bs=%d count=%d", mCache, BLOCK_SIZE,
-                SEQ_COUNT);
-        runTest(SEQUENTIAL_WRITE_KEY, command, TestType.DD, false, iterations, listener, metrics);
-    }
-
-    /**
-     * Run the random read test.
-     */
-    @SuppressWarnings("unused")
-    private void runRandomRead(int iterations, ITestInvocationListener listener,
-            Map<String, String> metrics) throws DeviceNotAvailableException {
-        String command = String.format("%s -r %d %s",
-                AbiFormatter.formatCmdForAbi(PERF_RANDOM, mForceAbi), mCachePartitionSize, mCache);
-        runTest(RANDOM_READ_KEY, command, TestType.RANDOM, true, iterations, listener, metrics);
-    }
-
-    /**
-     * Run the random write test with OSYNC disabled.
-     */
-    private void runRandomWrite(int iterations, ITestInvocationListener listener,
-            Map<String, String> metrics) throws DeviceNotAvailableException {
-        String command = String.format("%s -w %d %s",
-                AbiFormatter.formatCmdForAbi(PERF_RANDOM, mForceAbi), mCachePartitionSize, mCache);
-        runTest(RANDOM_WRITE_KEY, command, TestType.RANDOM, false, iterations, listener, metrics);
-    }
-
-    /**
-     * Run a test for a number of iterations.
-     *
-     * @param testKey the key used to report metrics.
-     * @param command the command to be run on the device.
-     * @param type the {@link TestType}, which determines how each iteration should be run.
-     * @param dropCache whether to drop the cache before starting each iteration.
-     * @param iterations the number of iterations to run.
-     * @param listener the {@link ITestInvocationListener}.
-     * @param metrics the map to store metrics of.
-     * @throws DeviceNotAvailableException If the device was not available.
-     */
-    private void runTest(String testKey, String command, TestType type, boolean dropCache,
-            int iterations, ITestInvocationListener listener, Map<String, String> metrics)
-            throws DeviceNotAvailableException {
-        CLog.i("Starting test %s", testKey);
-
-        TestDescription id = new TestDescription(RUN_KEY, testKey);
-        listener.testStarted(id);
-
-        Map<String, SimpleStats> simpleperfMetricsMap = new HashMap<String, SimpleStats>();
-        SimpleStats stats = new SimpleStats();
-        for (int i = 0; i < iterations; i++) {
-            if (dropCache) {
-                dropCache();
-            }
-
-            Double kbps = null;
-            switch (type) {
-                case DD:
-                    kbps = runDdIteration(command, simpleperfMetricsMap);
-                    break;
-                case RANDOM:
-                    kbps = runRandomIteration(command, simpleperfMetricsMap);
-                    break;
-            }
-
-            if (kbps != null) {
-                CLog.i("Result for %s, iteration %d: %f KBps", testKey, i + 1, kbps);
-                stats.add(kbps);
-            } else {
-                CLog.w("Skipping %s, iteration %d", testKey, i + 1);
-            }
-        }
-
-        if (stats.mean() != null) {
-            metrics.put(testKey, Double.toString(stats.median()));
-            for (Map.Entry<String, SimpleStats> entry : simpleperfMetricsMap.entrySet()) {
-                metrics.put(String.format("%s_%s", testKey, entry.getKey()),
-                        Double.toString(entry.getValue().median()));
-            }
-        } else {
-            listener.testFailed(id, "No metrics to report (see log)");
-        }
-        CLog.i("Test %s finished: mean=%f, stdev=%f, samples=%d", testKey, stats.mean(),
-                stats.stdev(), stats.size());
-        listener.testEnded(id, new HashMap<String, Metric>());
-    }
-
-    /**
-     * Run a single iteration of the dd (sequential) test.
-     *
-     * @param command the command to run on the device.
-     * @param simpleperfMetricsMap the map contain simpleperf metrics aggregated results
-     * @return The speed of the test in KBps or null if there was an error running or parsing the
-     * test.
-     * @throws DeviceNotAvailableException If the device was not available.
-     */
-    private Double runDdIteration(String command, Map<String, SimpleStats> simpleperfMetricsMap)
-            throws DeviceNotAvailableException {
-        String[] output;
-        SimplePerfResult spResult = null;
-        if (mSimpleperfMode) {
-            spResult = mSpUtil.executeCommand(command);
-            output = spResult.getCommandRawOutput().split("\n");
-        } else {
-            output = mTestDevice.executeShellCommand(command).split("\n");
-        }
-        String line = output[output.length - 1].trim();
-
-        Matcher m = DD_PATTERN.matcher(line);
-        if (m.matches()) {
-            simpleperfResultAggregation(spResult, simpleperfMetricsMap);
-            return convertBpsToKBps(Double.parseDouble(m.group(1)));
-        } else {
-            CLog.w("Line \"%s\" did not match expected output, ignoring", line);
-            return null;
-        }
-    }
-
-    /**
-     * Run a single iteration of the random test.
-     *
-     * @param command the command to run on the device.
-     * @param simpleperfMetricsMap the map contain simpleperf metrics aggregated results
-     * @return The speed of the test in KBps or null if there was an error running or parsing the
-     * test.
-     * @throws DeviceNotAvailableException If the device was not available.
-     */
-    private Double runRandomIteration(String command, Map<String, SimpleStats> simpleperfMetricsMap)
-            throws DeviceNotAvailableException {
-        String output;
-        SimplePerfResult spResult = null;
-        if (mSimpleperfMode) {
-            spResult = mSpUtil.executeCommand(command);
-            output = spResult.getCommandRawOutput();
-        } else {
-            output = mTestDevice.executeShellCommand(command);
-        }
-        Matcher m = EMMC_RANDOM_PATTERN.matcher(output.trim());
-        if (m.matches()) {
-            simpleperfResultAggregation(spResult, simpleperfMetricsMap);
-            return convertIopsToKBps(Double.parseDouble(m.group(1)));
-        } else {
-            CLog.w("Line \"%s\" did not match expected output, ignoring", output);
-            return null;
-        }
-    }
-
-    /**
-     * Helper function to aggregate simpleperf results
-     *
-     * @param spResult object that holds simpleperf results
-     * @param simpleperfMetricsMap map holds aggregated simpleperf results
-     */
-    private void simpleperfResultAggregation(SimplePerfResult spResult,
-            Map<String, SimpleStats> simpleperfMetricsMap) {
-        if (mSimpleperfMode) {
-            Assert.assertNotNull("simpleperf result is null object", spResult);
-            for (Map.Entry<String, String> entry : spResult.getBenchmarkMetrics().entrySet()) {
-                try {
-                    Double metricValue = NumberFormat.getNumberInstance(Locale.US)
-                            .parse(entry.getValue()).doubleValue();
-                    if (!simpleperfMetricsMap.containsKey(entry.getKey())) {
-                        SimpleStats newStat = new SimpleStats();
-                        simpleperfMetricsMap.put(entry.getKey(), newStat);
-                    }
-                    simpleperfMetricsMap.get(entry.getKey()).add(metricValue);
-                } catch (ParseException e) {
-                    CLog.e("Simpleperf metrics parse failure: " + e.toString());
-                }
-            }
-        }
-    }
-
-    /**
-     * Drop the disk cache on the device.
-     */
-    private void dropCache() throws DeviceNotAvailableException {
-        mTestDevice.executeShellCommand("echo 3 > /proc/sys/vm/drop_caches");
-    }
-
-    /**
-     * Convert bytes / sec reported by the dd tests into KBps.
-     */
-    private double convertBpsToKBps(double bps) {
-        return bps / 1024;
-    }
-
-    /**
-     * Convert the iops reported by the random tests into KBps.
-     * <p>
-     * The iops is number of 4kB block reads/writes per sec.  This makes the conversion factor 4.
-     * </p>
-     */
-    private double convertIopsToKBps(double iops) {
-        return 4 * iops;
-    }
-
-    /**
-     * Setup the device for tests by unmounting partitions and maxing the cpu speed.
-     */
-    private void setUp() throws DeviceNotAvailableException {
-        if (mAutoDiscoverCacheInfo) {
-            discoverCacheInfo();
-        }
-        mTestDevice.executeShellCommand("umount /sdcard");
-        mTestDevice.executeShellCommand("umount /data");
-        mTestDevice.executeShellCommand("umount /cache");
-
-        mTestDevice.executeShellCommand(
-                String.format("cat %s/cpuinfo_max_freq > %s/scaling_max_freq", mCpufreq, mCpufreq));
-        mTestDevice.executeShellCommand(
-                String.format("cat %s/cpuinfo_max_freq > %s/scaling_min_freq", mCpufreq, mCpufreq));
-
-        if (mSimpleperfMode) {
-            mSpUtil = SimplePerfUtil.newInstance(mTestDevice, SimplePerfType.STAT);
-            if (mSimpleperfArgu.size() == 0) {
-                mSimpleperfArgu.add("-e cpu-cycles:k,cpu-cycles:u");
-            }
-            mSpUtil.setArgumentList(mSimpleperfArgu);
-        }
-    }
-
-    /**
-     * Attempt to detect cache path and cache partition size automatically
-     */
-    private void discoverCacheInfo() throws DeviceNotAvailableException {
-        // Expected output look similar to the following:
-        //
-        // > ... vdc dump | grep cache
-        // 0 4123 /dev/block/platform/soc/7824900.sdhci/by-name/cache /cache ext4 rw, \
-        // seclabel,nosuid,nodev,noatime,discard,data=ordered 0 0
-        if (mTestDevice.enableAdbRoot()) {
-            String output = mTestDevice.executeShellCommand("vdc dump | grep cache");
-            CLog.d("Output from shell command 'vdc dump | grep cache':\n%s", output);
-            String[] segments = output.split("\\s+");
-            if (segments.length >= 3) {
-                mCache = segments[2];
-            } else {
-                CLog.w("Fail to detect cache path. Fall back to use '%s'", mCache);
-            }
-        } else {
-            CLog.d("Cannot get cache path because device %s is not rooted.",
-                    mTestDevice.getSerialNumber());
-        }
-
-        // Expected output looks similar to the following:
-        //
-        // > ... df cache
-        // Filesystem            1K-blocks Used Available Use% Mounted on
-        // /dev/block/mmcblk0p34     60400   56     60344   1% /cache
-        String output = mTestDevice.executeShellCommand("df cache");
-        CLog.d(String.format("Output from shell command 'df cache':\n%s", output));
-        String[] lines = output.split("\r?\n");
-        if (lines.length >= 2) {
-            String[] segments = lines[1].split("\\s+");
-            if (segments.length >= 2) {
-                if (lines[0].toLowerCase().contains("1k-blocks")) {
-                    mCachePartitionSize = Integer.parseInt(segments[1]) / 1024;
-                } else {
-                    throw new IllegalArgumentException("Unknown unit for the cache size.");
-                }
-            }
-        }
-
-        CLog.d("cache-device is set to %s ...", mCache);
-        CLog.d("cache-partition-size is set to %d ...", mCachePartitionSize);
-    }
-
-    /**
-     * Clean up the device by formatting a new cache partition.
-     */
-    private void cleanUp() throws DeviceNotAvailableException {
-        mTestDevice.executeShellCommand(String.format("mke2fs %s", mCache));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-}
-
diff --git a/prod-tests/src/com/android/performance/tests/FioBenchmarkTest.java b/prod-tests/src/com/android/performance/tests/FioBenchmarkTest.java
deleted file mode 100644
index 69ff904..0000000
--- a/prod-tests/src/com/android/performance/tests/FioBenchmarkTest.java
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.performance.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.NullOutputReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Runs the FIO benchmarks.
- * <p>
- * This test pushes the FIO executable to the device and runs several benchmarks.  Running each
- * benchmark consists of creating a config file, creating one or more data files, clearing the disk
- * cache and then running FIO. The test runs a variety of different configurations including a
- * simple benchmark with a single thread, a storage benchmark with 4 threads, a media server
- * emulator, and a media scanner emulator.
- * </p>
- */
-public class FioBenchmarkTest implements IDeviceTest, IRemoteTest {
-    // TODO: Refactor this to only pick out fields we care about.
-    private static final String[] FIO_V0_RESULT_FIELDS = {
-        "jobname", "groupid", "error",
-        // Read stats
-        "read-kb-io", "read-bandwidth", "read-runtime",
-        "read-slat-min", "read-slat-max", "read-slat-mean", "read-slat-stddev",
-        "read-clat-min", "read-clat-max", "read-clat-mean", "read-clat-stddev",
-        "read-bandwidth-min", "read-bandwidth-max", "read-bandwidth-percent", "read-bandwidth-mean",
-        "read-bandwidth-stddev",
-        // Write stats
-        "write-kb-io", "write-bandwidth", "write-runtime",
-        "write-slat-min", "write-slat-max", "write-slat-mean", "write-slat-stddev",
-        "write-clat-min", "write-clat-max", "write-clat-mean", "write-clat-stddev",
-        "write-bandwidth-min", "write-bandwidth-max", "write-bandwidth-percent",
-        "write-bandwidth-mean", "write-bandwidth-stddev",
-        // CPU stats
-        "cpu-user", "cpu-system", "cpu-context-switches", "cpu-major-page-faults",
-        "cpu-minor-page-faults",
-        // IO depth stats
-        "io-depth-1", "io-depth-2", "io-depth-4", "io-depth-8", "io-depth-16", "io-depth-32",
-        "io-depth-64",
-        // IO lat stats
-        "io-lat-2-ms", "io-lat-4-ms", "io-lat-10-ms", "io-lat-20-ms", "io-lat-50-ms",
-        "io-lat-100-ms", "io-lat-250-ms", "io-lat-500-ms", "io-lat-750-ms", "io-lat-1000-ms",
-        "io-lat-2000-ms"
-    };
-    private static final String[] FIO_V3_RESULT_FIELDS = {
-        "terse-version", "fio-version", "jobname", "groupid", "error",
-        // Read stats
-        "read-kb-io", "read-bandwidth", "read-iops", "read-runtime",
-        "read-slat-min", "read-slat-max", "read-slat-mean", "read-slat-stddev",
-        "read-clat-min", "read-clat-max", "read-clat-mean", "read-clat-stddev",
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null,
-        "read-lat-min", "read-lat-max", "read-lat-mean", "read-lat-stddev",
-        "read-bandwidth-min", "read-bandwidth-max", "read-bandwidth-percent", "read-bandwidth-mean",
-        "read-bandwidth-stddev",
-        // Write stats
-        "write-kb-io", "write-bandwidth", "write-iops", "write-runtime",
-        "write-slat-min", "write-slat-max", "write-slat-mean", "write-slat-stddev",
-        "write-clat-min", "write-clat-max", "write-clat-mean", "write-clat-stddev",
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null,
-        "write-lat-min", "write-lat-max", "write-lat-mean", "write-lat-stddev",
-        "write-bandwidth-min", "write-bandwidth-max", "write-bandwidth-percent",
-        "write-bandwidth-mean", "write-bandwidth-stddev",
-        // CPU stats
-        "cpu-user", "cpu-system", "cpu-context-switches", "cpu-major-page-faults",
-        "cpu-minor-page-faults",
-        // IO depth stats
-        "io-depth-1", "io-depth-2", "io-depth-4", "io-depth-8", "io-depth-16", "io-depth-32",
-        "io-depth-64",
-        // IO lat stats
-        "io-lat-2-us", "io-lat-4-us", "io-lat-10-us", "io-lat-20-us", "io-lat-50-us",
-        "io-lat-100-us", "io-lat-250-us", "io-lat-500-us", "io-lat-750-us", "io-lat-1000-us",
-        "io-lat-2-ms", "io-lat-4-ms", "io-lat-10-ms", "io-lat-20-ms", "io-lat-50-ms",
-        "io-lat-100-ms", "io-lat-250-ms", "io-lat-500-ms", "io-lat-750-ms", "io-lat-1000-ms",
-        "io-lat-2000-ms", "io-lat-greater"
-    };
-
-    private List<TestInfo> mTestCases = null;
-
-    /**
-     * Holds info about a job. The job translates into a job in the FIO config file. Contains the
-     * job name and a map from keys to values.
-     */
-    private static class JobInfo {
-        public String mJobName = null;
-        public Map<String, String> mParameters = new HashMap<>();
-
-        /**
-         * Gets the job as a string.
-         *
-         * @return a string of the job formatted for the config file.
-         */
-        public String createJob() {
-            if (mJobName == null) {
-                return "";
-            }
-            StringBuilder sb = new StringBuilder();
-            sb.append(String.format("[%s]\n", mJobName));
-            for (Entry<String, String> parameter : mParameters.entrySet()) {
-                if (parameter.getValue() == null) {
-                    sb.append(String.format("%s\n", parameter.getKey()));
-                } else {
-                    sb.append(String.format("%s=%s\n", parameter.getKey(), parameter.getValue()));
-                }
-            }
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Holds info about a file used in the benchmark. Because of limitations in FIO on Android,
-     * the file needs to be created before the tests are run. Contains the file name and size in kB.
-     */
-    private static class TestFileInfo {
-        public String mFileName = null;
-        public int mSize = -1;
-    }
-
-    /**
-     * Holds info about the perf metric that are cared about for a given job.
-     */
-    private static class PerfMetricInfo {
-        public enum ResultType {
-            STRING, INT, FLOAT, PERCENT;
-
-            String value(String input) {
-                switch(this) {
-                    case STRING:
-                    case INT:
-                    case FLOAT:
-                        return input;
-                    case PERCENT:
-                        if (input.length() < 2 || !input.endsWith("%")) {
-                            return null;
-                        }
-                        try {
-                            return String.format("%f", Double.parseDouble(
-                                    input.substring(0, input.length() - 1)) / 100);
-                        } catch (NumberFormatException e) {
-                            return null;
-                        }
-                    default: return null;
-                }
-            }
-        }
-
-        public String mJobName = null;
-        public String mFieldName = null;
-        public String mPostKey = null;
-        public ResultType mType = ResultType.STRING;
-    }
-
-    /**
-     * Holds the info associated with a test.
-     * <p>
-     * Contains the test name, key, a list of {@link JobInfo}, a set of {@link TestFileInfo},
-     * and a set of {@link PerfMetricInfo}.
-     * </p>
-     */
-    private static class TestInfo {
-        public String mTestName = null;
-        public String mKey = null;
-        public List<JobInfo> mJobs = new LinkedList<>();
-        public Set<TestFileInfo> mTestFiles = new HashSet<>();
-        public Set<PerfMetricInfo> mPerfMetrics = new HashSet<>();
-
-        /**
-         * Gets the config file.
-         *
-         * @return a string containing the contents of the config file needed to run the benchmark.
-         */
-        private String createConfig() {
-            StringBuilder sb = new StringBuilder();
-            for (JobInfo job : mJobs) {
-                sb.append(String.format("%s\n", job.createJob()));
-            }
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Parses the output of the FIO and allows the values to be looked up by job name and property.
-     */
-    private static class FioParser extends MultiLineReceiver {
-        public Map<String, Map<String, String>> mResults = new HashMap<>();
-
-        /**
-         * Gets the result for a job and property, or null if the job or the property do not exist.
-         *
-         * @param job the name of the job.
-         * @param property the name of the property. See {@code FIO_RESULT_FIELDS}.
-         * @return the fio results for the job and property or null if it does not exist.
-         */
-        public String getResult(String job, String property) {
-            if (!mResults.containsKey(job)) {
-                return null;
-            }
-            return mResults.get(job).get(property);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void processNewLines(String[] lines) {
-            for (String line : lines) {
-                CLog.d(line);
-                String[] fields = line.split(";");
-                if (fields.length < FIO_V0_RESULT_FIELDS.length) {
-                    continue;
-                }
-                if (fields.length < FIO_V3_RESULT_FIELDS.length) {
-                    Map<String, String> r = new HashMap<>();
-                    for (int i = 0; i < FIO_V0_RESULT_FIELDS.length; i++) {
-                        r.put(FIO_V0_RESULT_FIELDS[i], fields[i]);
-                    }
-                    mResults.put(fields[0], r); // Job name is index 0
-                } else if ("3".equals(fields[0])) {
-                    Map<String, String> r = new HashMap<>();
-                    for (int i = 0; i < FIO_V3_RESULT_FIELDS.length; i++) {
-                        r.put(FIO_V3_RESULT_FIELDS[i], fields[i]);
-                    }
-                    mResults.put(fields[2], r); // Job name is index 2
-                } else {
-                    Assert.fail("Unknown fio terse output version");
-                }
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public boolean isCancelled() {
-            return false;
-        }
-    }
-
-    ITestDevice mTestDevice = null;
-
-    private String mFioDir = null;
-    private String mFioBin = null;
-    private String mFioConfig = null;
-
-    @Option(name="fio-location", description="The path to the precompiled FIO executable. If "
-            + "unset, try to use fio from the system image.")
-    private String mFioLocation = null;
-
-    @Option(name="tmp-dir", description="The directory used for interal benchmarks.")
-    private String mTmpDir = "/data/tmp/fio";
-
-    @Option(name="internal-test-dir", description="The directory used for interal benchmarks.")
-    private String mInternalTestDir = "/data/fio/data";
-
-    @Option(name="media-test-dir", description="The directory used for media benchmarks.")
-    private String mMediaTestDir = "${EXTERNAL_STORAGE}/fio";
-
-    @Option(name="external-test-dir", description="The directory used for external benchmarks.")
-    private String mExternalTestDir = "${EXTERNAL_STORAGE}/fio";
-
-    @Option(name="collect-yaffs-logs", description="Collect yaffs logs before and after tests")
-    private Boolean mCollectYaffsLogs = false;
-
-    @Option(name="run-simple-internal-test", description="Run the simple internal benchmark.")
-    private Boolean mRunSimpleInternalTest = true;
-
-    @Option(name="simple-internal-file-size",
-            description="The file size of the simple internal benchmark in MB.")
-    private int mSimpleInternalFileSize = 256;
-
-    @Option(name="run-simple-external-test", description="Run the simple external benchmark.")
-    private Boolean mRunSimpleExternalTest = false;
-
-    @Option(name="simple-external-file-size",
-            description="The file size of the simple external benchmark in MB.")
-    private int mSimpleExternalFileSize = 256;
-
-    @Option(name="run-storage-internal-test", description="Run the storage internal benchmark.")
-    private Boolean mRunStorageInternalTest = true;
-
-    @Option(name="storage-internal-file-size",
-            description="The file size of the storage internal benchmark in MB.")
-    private int mStorageInternalFileSize = 256;
-
-    @Option(name="storage-internal-job-count",
-            description="The number of jobs for the storage internal benchmark.")
-    private int mStorageInternalJobCount = 4;
-
-    @Option(name="run-storage-external-test", description="Run the storage external benchmark.")
-    private Boolean mRunStorageExternalTest = false;
-
-    @Option(name="storage-external-file-size",
-            description="The file size of the storage external benchmark in MB.")
-    private int mStorageExternalFileSize = 256;
-
-    @Option(name="storage-external-job-count",
-            description="The number of jobs for the storage external benchmark.")
-    private int mStorageExternalJobCount = 4;
-
-    @Option(name="run-media-server-test", description="Run the media server benchmark.")
-    private Boolean mRunMediaServerTest = false;
-
-    @Option(name="media-server-duration",
-            description="The duration of the media server benchmark in secs.")
-    private long mMediaServerDuration = 30;
-
-    @Option(name="media-server-media-file-size",
-            description="The media file size of the media server benchmark in MB.")
-    private int mMediaServerMediaFileSize = 256;
-
-    @Option(name="media-server-worker-file-size",
-            description="The worker file size of the media server benchmark in MB.")
-    private int mMediaServerWorkerFileSize = 256;
-
-    @Option(name="media-server-worker-job-count",
-            description="The number of worker jobs for the media server benchmark.")
-    private int mMediaServerWorkerJobCount = 4;
-
-    @Option(name="run-media-scanner-test", description="Run the media scanner benchmark.")
-    private Boolean mRunMediaScannerTest = false;
-
-    @Option(name="media-scanner-media-file-size",
-            description="The media file size of the media scanner benchmark in kB.")
-    private int mMediaScannerMediaFileSize = 8;
-
-    @Option(name="media-scanner-media-file-count",
-            description="The number of media files to scan.")
-    private int mMediaScannerMediaFileCount = 256;
-
-    @Option(name="media-scanner-worker-file-size",
-            description="The worker file size of the media scanner benchmark in MB.")
-    private int mMediaScannerWorkerFileSize = 256;
-
-    @Option(name="media-scanner-worker-job-count",
-            description="The number of worker jobs for the media server benchmark.")
-    private int mMediaScannerWorkerJobCount = 4;
-
-    @Option(name="key-suffix",
-            description="The suffix to add to the reporting key in order to override the default")
-    private String mKeySuffix = null;
-
-    /**
-     * Sets up all the benchmarks.
-     */
-    private void setupTests() {
-        if (mTestCases != null) {
-            // assume already set up
-            return;
-        }
-
-        mTestCases = new LinkedList<>();
-
-        if (mRunSimpleInternalTest) {
-            addSimpleTest("read", "sync", true);
-            addSimpleTest("write", "sync", true);
-            addSimpleTest("randread", "sync", true);
-            addSimpleTest("randwrite", "sync", true);
-            addSimpleTest("randread", "mmap", true);
-            addSimpleTest("randwrite", "mmap", true);
-        }
-
-        if (mRunSimpleExternalTest) {
-            addSimpleTest("read", "sync", false);
-            addSimpleTest("write", "sync", false);
-            addSimpleTest("randread", "sync", false);
-            addSimpleTest("randwrite", "sync", false);
-            addSimpleTest("randread", "mmap", false);
-            addSimpleTest("randwrite", "mmap", false);
-        }
-
-        if (mRunStorageInternalTest) {
-            addStorageTest("read", "sync", true);
-            addStorageTest("write", "sync", true);
-            addStorageTest("randread", "sync", true);
-            addStorageTest("randwrite", "sync", true);
-            addStorageTest("randread", "mmap", true);
-            addStorageTest("randwrite", "mmap", true);
-        }
-
-        if (mRunStorageExternalTest) {
-            addStorageTest("read", "sync", false);
-            addStorageTest("write", "sync", false);
-            addStorageTest("randread", "sync", false);
-            addStorageTest("randwrite", "sync", false);
-            addStorageTest("randread", "mmap", false);
-            addStorageTest("randwrite", "mmap", false);
-        }
-
-        if (mRunMediaServerTest) {
-            addMediaServerTest("read");
-            addMediaServerTest("write");
-        }
-
-        if (mRunMediaScannerTest) {
-            addMediaScannerTest();
-        }
-    }
-
-    /**
-     * Sets up the simple FIO benchmark.
-     * <p>
-     * The test consists of a single process reading or writing to a file.
-     * </p>
-     *
-     * @param rw the type of IO pattern. One of {@code read}, {@code write}, {@code randread}, or
-     * {@code randwrite}.
-     * @param ioengine defines how the job issues I/O. Such as {@code sync}, {@code vsync},
-     * {@code mmap}, or {@code cpuio} and others.
-     * @param internal whether the test should be run on the internal (/data) partition or the
-     * external partition.
-     */
-    private void addSimpleTest(String rw, String ioengine, boolean internal) {
-        String fileName = "testfile";
-        String jobName = "job";
-
-        String directory;
-        int fileSize;
-
-        TestInfo t = new TestInfo();
-        if (internal) {
-            t.mTestName = String.format("SimpleBenchmark-int-%s-%s", ioengine, rw);
-            t.mKey = "fio_simple_int_benchmark";
-            directory = mInternalTestDir;
-            fileSize = mSimpleInternalFileSize;
-        } else {
-            t.mTestName = String.format("SimpleBenchmark-ext-%s-%s", ioengine, rw);
-            t.mKey = "fio_simple_ext_benchmark";
-            directory = mExternalTestDir;
-            fileSize = mSimpleExternalFileSize;
-        }
-
-        TestFileInfo f = new TestFileInfo();
-        f.mFileName = new File(directory, fileName).getAbsolutePath();
-        f.mSize = fileSize * 1024;  // fileSize is in MB but we want it in kB.
-        t.mTestFiles.add(f);
-
-        JobInfo j = new JobInfo();
-        j.mJobName = jobName;
-        j.mParameters.put("directory", directory);
-        j.mParameters.put("filename", fileName);
-        j.mParameters.put("fsync", "1024");
-        j.mParameters.put("ioengine", ioengine);
-        j.mParameters.put("rw", rw);
-        j.mParameters.put("size", String.format("%dM",fileSize));
-        t.mJobs.add(j);
-
-        PerfMetricInfo m = new PerfMetricInfo();
-        m.mJobName = jobName;
-        if ("sync".equals(ioengine)) {
-            m.mPostKey = String.format("%s_bandwidth", rw);
-        } else {
-            m.mPostKey = String.format("%s_%s_bandwidth", rw, ioengine);
-        }
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        if (rw.endsWith("read")) {
-            m.mFieldName = "read-bandwidth-mean";
-        } else if (rw.endsWith("write")) {
-            m.mFieldName = "write-bandwidth-mean";
-        }
-        t.mPerfMetrics.add(m);
-
-        mTestCases.add(t);
-    }
-
-    /**
-     * Sets up the storage FIO benchmark.
-     * <p>
-     * The test consists of several processes reading or writing to a file.
-     * </p>
-     *
-     * @param rw the type of IO pattern. One of {@code read}, {@code write}, {@code randread}, or
-     * {@code randwrite}.
-     * @param ioengine defines how the job issues I/O. Such as {@code sync}, {@code vsync},
-     * {@code mmap}, or {@code cpuio} and others.
-     * @param internal whether the test should be run on the internal (/data) partition or the
-     * external partition.
-     */
-    private void addStorageTest(String rw, String ioengine, boolean internal) {
-        String fileName = "testfile";
-        String jobName = "workers";
-
-        String directory;
-        int fileSize;
-        int jobCount;
-
-        TestInfo t = new TestInfo();
-        if (internal) {
-            t.mTestName = String.format("StorageBenchmark-int-%s-%s", ioengine, rw);
-            t.mKey = "fio_storage_int_benchmark";
-            directory = mInternalTestDir;
-            fileSize = mStorageInternalFileSize;
-            jobCount = mStorageInternalJobCount;
-        } else {
-            t.mTestName = String.format("StorageBenchmark-ext-%s-%s", ioengine, rw);
-            t.mKey = "fio_storage_ext_benchmark";
-            directory = mExternalTestDir;
-            fileSize = mStorageExternalFileSize;
-            jobCount = mStorageExternalJobCount;
-        }
-
-        TestFileInfo f = new TestFileInfo();
-        f.mFileName = new File(directory, fileName).getAbsolutePath();
-        f.mSize = fileSize * 1024;  // fileSize is in MB but we want it in kB.
-        t.mTestFiles.add(f);
-
-        JobInfo j = new JobInfo();
-        j.mJobName = jobName;
-        j.mParameters.put("directory", directory);
-        j.mParameters.put("filename", fileName);
-        j.mParameters.put("fsync", "1024");
-        j.mParameters.put("group_reporting", null);
-        j.mParameters.put("ioengine", ioengine);
-        j.mParameters.put("new_group", null);
-        j.mParameters.put("numjobs", String.format("%d", jobCount));
-        j.mParameters.put("rw", rw);
-        j.mParameters.put("size", String.format("%dM",fileSize));
-        t.mJobs.add(j);
-
-        PerfMetricInfo m = new PerfMetricInfo();
-        m.mJobName = jobName;
-        if ("sync".equals(ioengine)) {
-            m.mPostKey = String.format("%s_bandwidth", rw);
-        } else {
-            m.mPostKey = String.format("%s_%s_bandwidth", rw, ioengine);
-        }
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        if (rw.endsWith("read")) {
-            m.mFieldName = "read-bandwidth-mean";
-        } else if (rw.endsWith("write")) {
-            m.mFieldName = "write-bandwidth-mean";
-        }
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = jobName;
-        if ("sync".equals(ioengine)) {
-            m.mPostKey = String.format("%s_latency", rw);
-        } else {
-            m.mPostKey = String.format("%s_%s_latency", rw, ioengine);
-        }
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        if (rw.endsWith("read")) {
-            m.mFieldName = "read-clat-mean";
-        } else if (rw.endsWith("write")) {
-            m.mFieldName = "write-clat-mean";
-        }
-        t.mPerfMetrics.add(m);
-
-        mTestCases.add(t);
-    }
-
-    /**
-     * Sets up the media server benchmark.
-     * <p>
-     * The test consists of a single process at a higher priority reading or writing to a file
-     * while several other worker processes read and write to a different file.
-     * </p>
-     *
-     * @param rw the type of IO pattern. One of {@code read}, {@code write}
-     */
-    private void addMediaServerTest(String rw) {
-        String mediaJob = "media-server";
-        String mediaFile = "mediafile";
-        String workerJob = "workers";
-        String workerFile = "workerfile";
-
-        TestInfo t = new TestInfo();
-        t.mTestName = String.format("MediaServerBenchmark-%s", rw);
-        t.mKey = "fio_media_server_benchmark";
-
-        TestFileInfo f = new TestFileInfo();
-        f.mFileName = new File(mMediaTestDir, mediaFile).getAbsolutePath();
-        f.mSize = mMediaServerMediaFileSize * 1024;  // File size is in MB but we want it in kB.
-        t.mTestFiles.add(f);
-
-        f = new TestFileInfo();
-        f.mFileName = new File(mMediaTestDir, workerFile).getAbsolutePath();
-        f.mSize = mMediaServerWorkerFileSize * 1024;  // File size is in MB but we want it in kB.
-        t.mTestFiles.add(f);
-
-        JobInfo j = new JobInfo();
-        j.mJobName = "global";
-        j.mParameters.put("directory", mMediaTestDir);
-        j.mParameters.put("fsync", "1024");
-        j.mParameters.put("ioengine", "sync");
-        j.mParameters.put("runtime", String.format("%d", mMediaServerDuration));
-        j.mParameters.put("time_based", null);
-        t.mJobs.add(j);
-
-        j = new JobInfo();
-        j.mJobName = mediaJob;
-        j.mParameters.put("filename", mediaFile);
-        j.mParameters.put("iodepth", "32");
-        j.mParameters.put("nice", "-16");
-        j.mParameters.put("rate", "6m");
-        j.mParameters.put("rw", rw);
-        j.mParameters.put("size", String.format("%dM", mMediaServerMediaFileSize));
-        t.mJobs.add(j);
-
-        j = new JobInfo();
-        j.mJobName = workerJob;
-        j.mParameters.put("filename", workerFile);
-        j.mParameters.put("group_reporting", null);
-        j.mParameters.put("new_group", null);
-        j.mParameters.put("nice", "0");
-        j.mParameters.put("numjobs", String.format("%d", mMediaServerWorkerJobCount));
-        j.mParameters.put("rw", "randrw");
-        j.mParameters.put("size", String.format("%dM", mMediaServerWorkerFileSize));
-        t.mJobs.add(j);
-
-        PerfMetricInfo m = new PerfMetricInfo();
-        m.mJobName = mediaJob;
-        m.mPostKey = String.format("%s_media_bandwidth", rw);
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        if (rw.endsWith("read")) {
-            m.mFieldName = "read-bandwidth-mean";
-        } else if (rw.endsWith("write")) {
-            m.mFieldName = "write-bandwidth-mean";
-        }
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = mediaJob;
-        m.mPostKey = String.format("%s_media_latency", rw);
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        if (rw.endsWith("read")) {
-            m.mFieldName = "read-clat-mean";
-        } else if (rw.endsWith("write")) {
-            m.mFieldName = "write-clat-mean";
-        }
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = workerJob;
-        m.mPostKey = String.format("%s_workers_read_bandwidth", rw);
-        m.mFieldName = "read-bandwidth-mean";
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = workerJob;
-        m.mPostKey = String.format("%s_workers_write_bandwidth", rw);
-        m.mFieldName = "write-bandwidth-mean";
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        t.mPerfMetrics.add(m);
-
-        mTestCases.add(t);
-    }
-
-    /**
-     * Sets up the media scanner benchmark.
-     * <p>
-     * The test consists of a single process reading several small files while several other worker
-     * processes read and write to a different file.
-     * </p>
-     */
-    private void addMediaScannerTest() {
-        String mediaJob = "media-server";
-        String mediaFile = "mediafile.%d";
-        String workerJob = "workers";
-        String workerFile = "workerfile";
-
-        TestInfo t = new TestInfo();
-        t.mTestName = "MediaScannerBenchmark";
-        t.mKey = "fio_media_scanner_benchmark";
-
-        TestFileInfo f;
-        for (int i = 0; i < mMediaScannerMediaFileCount; i++) {
-            f = new TestFileInfo();
-            f.mFileName = new File(mMediaTestDir, String.format(mediaFile, i)).getAbsolutePath();
-            f.mSize = mMediaScannerMediaFileSize;  // File size is already in kB so do nothing.
-            t.mTestFiles.add(f);
-        }
-
-        f = new TestFileInfo();
-        f.mFileName = new File(mMediaTestDir, workerFile).getAbsolutePath();
-        f.mSize = mMediaScannerWorkerFileSize * 1024;  // File size is in MB but we want it in kB.
-        t.mTestFiles.add(f);
-
-        JobInfo j = new JobInfo();
-        j.mJobName = "global";
-        j.mParameters.put("directory", mMediaTestDir);
-        j.mParameters.put("fsync", "1024");
-        j.mParameters.put("ioengine", "sync");
-        t.mJobs.add(j);
-
-        j = new JobInfo();
-        j.mJobName = mediaJob;
-        StringBuilder fileNames = new StringBuilder();
-        fileNames.append(String.format(mediaFile, 0));
-        for (int i = 1; i < mMediaScannerMediaFileCount; i++) {
-            fileNames.append(String.format(":%s", String.format(mediaFile, i)));
-        }
-        j.mParameters.put("filename", fileNames.toString());
-        j.mParameters.put("exitall", null);
-        j.mParameters.put("openfiles", "4");
-        j.mParameters.put("rw", "read");
-        t.mJobs.add(j);
-
-        j = new JobInfo();
-        j.mJobName = workerJob;
-        j.mParameters.put("filename", workerFile);
-        j.mParameters.put("group_reporting", null);
-        j.mParameters.put("new_group", null);
-        j.mParameters.put("numjobs", String.format("%d", mMediaScannerWorkerJobCount));
-        j.mParameters.put("rw", "randrw");
-        j.mParameters.put("size", String.format("%dM", mMediaScannerWorkerFileSize));
-        t.mJobs.add(j);
-
-        PerfMetricInfo m = new PerfMetricInfo();
-        m.mJobName = mediaJob;
-        m.mPostKey = "media_bandwidth";
-        m.mFieldName = "read-bandwidth-mean";
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = mediaJob;
-        m.mPostKey = "media_latency";
-        m.mFieldName = "read-clat-mean";
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = workerJob;
-        m.mPostKey = "workers_read_bandwidth";
-        m.mFieldName = "read-bandwidth-mean";
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        t.mPerfMetrics.add(m);
-
-        m = new PerfMetricInfo();
-        m.mJobName = workerJob;
-        m.mPostKey = "workers_write_bandwidth";
-        m.mFieldName = "write-bandwidth-mean";
-        m.mType = PerfMetricInfo.ResultType.FLOAT;
-        t.mPerfMetrics.add(m);
-
-        mTestCases.add(t);
-    }
-
-    /**
-     * Creates the directories needed to run FIO, pushes the FIO executable to the device, and
-     * stops the runtime.
-     *
-     * @throws DeviceNotAvailableException if the device is not available.
-     */
-    private void setupDevice() throws DeviceNotAvailableException {
-        mTestDevice.executeShellCommand("stop");
-        mTestDevice.executeShellCommand(String.format("mkdir -p %s", mFioDir));
-        mTestDevice.executeShellCommand(String.format("mkdir -p %s", mTmpDir));
-        mTestDevice.executeShellCommand(String.format("mkdir -p %s", mInternalTestDir));
-        mTestDevice.executeShellCommand(String.format("mkdir -p %s", mMediaTestDir));
-        if (mExternalTestDir != null) {
-            mTestDevice.executeShellCommand(String.format("mkdir -p %s", mExternalTestDir));
-        }
-        if (mFioLocation != null) {
-            mTestDevice.pushFile(new File(mFioLocation), mFioBin);
-            mTestDevice.executeShellCommand(String.format("chmod 755 %s", mFioBin));
-        }
-    }
-
-    /**
-     * Reverses the actions of {@link #setDevice(ITestDevice)}.
-     *
-     * @throws DeviceNotAvailableException If the device is not available.
-     */
-    private void cleanupDevice() throws DeviceNotAvailableException {
-        if (mExternalTestDir != null) {
-            mTestDevice.executeShellCommand(String.format("rm -r %s", mExternalTestDir));
-        }
-        mTestDevice.executeShellCommand(String.format("rm -r %s", mMediaTestDir));
-        mTestDevice.executeShellCommand(String.format("rm -r %s", mInternalTestDir));
-        mTestDevice.executeShellCommand(String.format("rm -r %s", mTmpDir));
-        mTestDevice.executeShellCommand(String.format("rm -r %s", mFioDir));
-        mTestDevice.executeShellCommand("start");
-        mTestDevice.waitForDeviceAvailable();
-    }
-
-    /**
-     * Runs a single test, including creating the test files, clearing the cache, collecting before
-     * and after files, running the benchmark, and reporting the results.
-     *
-     * @param test the benchmark.
-     * @param listener the ITestInvocationListener
-     * @throws DeviceNotAvailableException if the device is not available.
-     */
-    private void runTest(TestInfo test, ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        CLog.i("Running %s benchmark", test.mTestName);
-        mTestDevice.executeShellCommand(String.format("rm -r %s/*", mTmpDir));
-        mTestDevice.executeShellCommand(String.format("rm -r %s/*", mInternalTestDir));
-        mTestDevice.executeShellCommand(String.format("rm -r %s/*", mMediaTestDir));
-        if (mExternalTestDir != null) {
-            mTestDevice.executeShellCommand(String.format("rm -r %s/*", mExternalTestDir));
-        }
-
-        for (TestFileInfo file : test.mTestFiles) {
-            CLog.v("Creating file: %s, size: %dkB", file.mFileName, file.mSize);
-            String cmd = String.format("dd if=/dev/urandom of=%s bs=1024 count=%d", file.mFileName,
-                    file.mSize);
-            int timeout = file.mSize * 2 * 1000; // Timeout is 2 seconds per kB.
-            mTestDevice.executeShellCommand(cmd, new NullOutputReceiver(),
-                    timeout, TimeUnit.MILLISECONDS, 2);
-        }
-
-        CLog.i("Creating config");
-        CLog.d("Config file:\n%s", test.createConfig());
-        mTestDevice.pushString(test.createConfig(), mFioConfig);
-
-        CLog.i("Dropping cache");
-        mTestDevice.executeShellCommand("echo 3 > /proc/sys/vm/drop_caches");
-
-        collectLogs(test, listener, "before");
-
-        CLog.i("Running test");
-        FioParser output = new FioParser();
-        // Run FIO with a timeout of 1 hour.
-        mTestDevice.executeShellCommand(String.format("%s --minimal %s", mFioBin, mFioConfig),
-                output, 60 * 60 * 1000, TimeUnit.MILLISECONDS, 2);
-
-        collectLogs(test, listener, "after");
-
-        // Report metrics
-        Map<String, String> metrics = new HashMap<>();
-        String key = mKeySuffix == null ? test.mKey : test.mKey + mKeySuffix;
-
-        listener.testRunStarted(key, 0);
-        for (PerfMetricInfo m : test.mPerfMetrics) {
-            if (!output.mResults.containsKey(m.mJobName)) {
-                CLog.w("Job name %s was not found in the results", m.mJobName);
-                continue;
-            }
-
-            String value = output.getResult(m.mJobName, m.mFieldName);
-            if (value != null) {
-                metrics.put(m.mPostKey, m.mType.value(value));
-            } else {
-                CLog.w("%s was not in results for the job %s", m.mFieldName, m.mJobName);
-            }
-        }
-
-        CLog.d("About to report metrics to %s: %s", key, metrics);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    private void collectLogs(TestInfo testInfo, ITestInvocationListener listener,
-            String descriptor) throws DeviceNotAvailableException {
-        if (mCollectYaffsLogs && mTestDevice.doesFileExist("/proc/yaffs")) {
-            logFile("/proc/yaffs", String.format("%s-yaffs-%s", testInfo.mTestName, descriptor),
-                    mTestDevice, listener);
-        }
-    }
-
-    private void logFile(String remoteFileName, String localFileName, ITestDevice testDevice,
-            ITestInvocationListener listener) throws DeviceNotAvailableException {
-        File outputFile = null;
-        InputStreamSource outputSource = null;
-        try {
-            outputFile = testDevice.pullFile(remoteFileName);
-            if (outputFile != null) {
-                CLog.d("Sending %d byte file %s to logosphere!", outputFile.length(), outputFile);
-                outputSource = new FileInputStreamSource(outputFile);
-                listener.testLog(localFileName, LogDataType.TEXT, outputSource);
-            }
-        } finally {
-            FileUtil.deleteFile(outputFile);
-            StreamUtil.cancel(outputSource);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-
-        mFioDir = new File(mTestDevice.getMountPoint(IDevice.MNT_DATA), "fio").getAbsolutePath();
-        if (mFioLocation != null) {
-            mFioBin = new File(mFioDir, "fio").getAbsolutePath();
-        } else {
-            mFioBin = "fio";
-        }
-        mFioConfig = new File(mFioDir, "config.fio").getAbsolutePath();
-
-        setupTests();
-        setupDevice();
-
-        for (TestInfo test : mTestCases) {
-            runTest(test, listener);
-        }
-
-        cleanupDevice();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    /**
-     * A meta-test to ensure that the bits of FioBenchmarkTest are working properly.
-     */
-    public static class MetaTest extends TestCase {
-
-        /**
-         * Test that {@link JobInfo#createJob()} properly formats a job.
-         */
-        public void testCreateJob() {
-            JobInfo j = new JobInfo();
-            assertEquals("", j.createJob());
-            j.mJobName = "job";
-            assertEquals("[job]\n", j.createJob());
-            j.mParameters.put("param1", null);
-            j.mParameters.put("param2", "value");
-            String[] lines = j.createJob().split("\n");
-            assertEquals(3, lines.length);
-            assertEquals("[job]", lines[0]);
-            Set<String> params = new HashSet<>(2);
-            params.add(lines[1]);
-            params.add(lines[2]);
-            assertTrue(params.contains("param1"));
-            assertTrue(params.contains("param2=value"));
-        }
-
-        /**
-         * Test that {@link TestInfo#createConfig()} properly formats a config.
-         */
-        public void testCreateConfig() {
-            TestInfo t = new TestInfo();
-            JobInfo j = new JobInfo();
-            j.mJobName = "job1";
-            j.mParameters.put("param1", "value1");
-            t.mJobs.add(j);
-
-            j = new JobInfo();
-            j.mJobName = "job2";
-            j.mParameters.put("param2", "value2");
-            t.mJobs.add(j);
-
-            j = new JobInfo();
-            j.mJobName = "job3";
-            j.mParameters.put("param3", "value3");
-            t.mJobs.add(j);
-
-            assertEquals("[job1]\nparam1=value1\n\n" +
-                    "[job2]\nparam2=value2\n\n" +
-                    "[job3]\nparam3=value3\n\n", t.createConfig());
-        }
-
-        /**
-         * Test that output lines are parsed correctly by the FioParser, invalid lines are ignored,
-         * and that the various fields are accessible with
-         * {@link FioParser#getResult(String, String)}.
-         */
-        public void testFioParser() {
-            String[] lines = new String[4];
-            // We build the lines up as follows (assuming FIO_RESULTS_FIELDS.length == 58):
-            // 0;3;6;...;171
-            // 1;4;7;...;172
-            // 2;5;8;...;173
-            for (int i = 0; i < 3; i++) {
-                StringBuilder sb = new StringBuilder();
-                sb.append(i);
-                for (int j = 1; j < FIO_V0_RESULT_FIELDS.length; j++) {
-                    sb.append(";");
-                    sb.append(j * 3 + i);
-                }
-                lines[i] = sb.toString();
-            }
-            // A line may have an optional description on the end which we don't care about, make
-            // sure it still parses.
-            lines[2] = lines[2] += ";description";
-            // Make sure an invalid output line does not parse.
-            lines[3] = "invalid";
-
-            FioParser p = new FioParser();
-            p.processNewLines(lines);
-
-
-            for (int i = 0; i < 3; i++) {
-                for (int j = 0; j < FIO_V0_RESULT_FIELDS.length; j++) {
-                    assertEquals(String.format("job=%d, field=%s", i, FIO_V0_RESULT_FIELDS[j]),
-                            String.format("%d", j * 3 + i),
-                            p.getResult(String.format("%d", i), FIO_V0_RESULT_FIELDS[j]));
-                }
-            }
-            assertNull(p.getResult("missing", "jobname"));
-            assertNull(p.getResult("invalid", "jobname"));
-            assertNull(p.getResult("0", "missing"));
-        }
-
-        /**
-         * Test that {@link PerfMetricInfo.ResultType#value(String)} correctly transforms strings
-         * based on the result type.
-         */
-        public void testResultTypeValue() {
-            assertEquals("test", PerfMetricInfo.ResultType.STRING.value("test"));
-            assertEquals("1", PerfMetricInfo.ResultType.INT.value("1"));
-            assertEquals("3.14159", PerfMetricInfo.ResultType.FLOAT.value("3.14159"));
-            assertEquals(String.format("%f", 0.34567),
-                    PerfMetricInfo.ResultType.PERCENT.value("34.567%"));
-            assertNull(PerfMetricInfo.ResultType.PERCENT.value(""));
-            assertNull(PerfMetricInfo.ResultType.PERCENT.value("34.567"));
-            assertNull(PerfMetricInfo.ResultType.PERCENT.value("test%"));
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/performance/tests/GLBenchmarkTest.java b/prod-tests/src/com/android/performance/tests/GLBenchmarkTest.java
deleted file mode 100644
index 4a8fd29..0000000
--- a/prod-tests/src/com/android/performance/tests/GLBenchmarkTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-/**
- * A harness that launches GLBenchmark and reports result. Requires GLBenchmark
- * custom XML. Assumes GLBenchmark app is already installed on device.
- */
-public class GLBenchmarkTest implements IDeviceTest, IRemoteTest {
-
-    private static final String RUN_KEY = "glbenchmark";
-    private static final long TIMEOUT_MS = 30 * 60 * 1000;
-    private static final long POLLING_INTERVAL_MS = 5 * 1000;
-    private static final Map<String, String> METRICS_KEY_MAP = createMetricsKeyMap();
-
-    private ITestDevice mDevice;
-
-    @Option(name = "custom-xml-path", description = "local path for GLBenchmark custom.xml",
-            importance = Importance.ALWAYS)
-    private File mGlbenchmarkCustomXmlLocal = new File("/tmp/glbenchmark_custom.xml");
-
-    @Option(name = "gl-package-name", description = "GLBenchmark package name")
-    private String mGlbenchmarkPackageName = "com.glbenchmark.glbenchmark25";
-
-    @Option(name = "gl-version", description = "GLBenchmark version (e.g. 2.5.1_b306a5)")
-    private String mGlbenchmarkVersion = "2.5.1_b306a5";
-
-    private String mGlbenchmarkCacheDir =
-            "${EXTERNAL_STORAGE}/Android/data/" + mGlbenchmarkPackageName + "/cache/";
-    private String mGlbenchmarkCustomXmlPath =
-            mGlbenchmarkCacheDir + "custom.xml";
-    private String mGlbenchmarkResultXmlPath =
-            mGlbenchmarkCacheDir + "last_results_" + mGlbenchmarkVersion + ".xml";
-    private String mGlbenchmarkExcelResultXmlPath =
-            mGlbenchmarkCacheDir + "results_%s_0.xml";
-    private String mGlbenchmarkAllResultXmlPath =
-            mGlbenchmarkCacheDir + "results*.xml";
-
-    private static Map<String, String> createMetricsKeyMap() {
-        Map<String, String> result = new HashMap<String, String>();
-        result.put("Fill rate - C24Z16", "fill-rate");
-        result.put("Fill rate - C24Z16 Offscreen", "fill-rate-offscreen");
-        result.put("Triangle throughput: Textured - C24Z16", "triangle-c24z16");
-        result.put("Triangle throughput: Textured - C24Z16 Offscreen",
-                "triangle-c24z16-offscreen");
-        result.put("Triangle throughput: Textured - C24Z16 Vertex lit",
-                "triangle-c24z16-vertex-lit");
-        result.put("Triangle throughput: Textured - C24Z16 Offscreen Vertex lit",
-                "triangle-c24z16-offscreen-vertex-lit");
-        result.put("Triangle throughput: Textured - C24Z16 Fragment lit",
-                "triangle-c24z16-fragment-lit");
-        result.put("Triangle throughput: Textured - C24Z16 Offscreen Fragment lit",
-                "triangle-c24z16-offscreen-fragment-lit");
-        result.put("GLBenchmark 2.5 Egypt HD - C24Z16", "egypt-hd-c24z16");
-        result.put("GLBenchmark 2.5 Egypt HD - C24Z16 Offscreen", "egypt-hd-c24z16-offscreen");
-        result.put("GLBenchmark 2.5 Egypt HD PVRTC4 - C24Z16", "egypt-hd-pvrtc4-c24z16");
-        result.put("GLBenchmark 2.5 Egypt HD PVRTC4 - C24Z16 Offscreen",
-                "egypt-hd-pvrtc4-c24z16-offscreen");
-        result.put("GLBenchmark 2.5 Egypt HD - C24Z24MS4", "egypt-hd-c24z24ms4");
-        result.put("GLBenchmark 2.5 Egypt HD - C24Z16 Fixed timestep",
-                "egypt-hd-c24z16-fixed-timestep");
-        result.put("GLBenchmark 2.5 Egypt HD - C24Z16 Fixed timestep Offscreen",
-                "egypt-hd-c24z16-fixed-timestep-offscreen");
-        result.put("GLBenchmark 2.1 Egypt Classic - C16Z16", "egypt-classic-c16z16");
-        result.put("GLBenchmark 2.1 Egypt Classic - C16Z16 Offscreen",
-                "egypt-classic-c16z16-offscreen");
-        return Collections.unmodifiableMap(result);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
-        ITestDevice device = getDevice();
-
-        // delete old result
-        device.executeShellCommand(String.format("rm %s", mGlbenchmarkResultXmlPath));
-        device.executeShellCommand(String.format("rm %s", mGlbenchmarkAllResultXmlPath));
-
-        // push glbenchmark custom xml to device
-        device.pushFile(mGlbenchmarkCustomXmlLocal, mGlbenchmarkCustomXmlPath);
-
-        listener.testRunStarted(RUN_KEY, 0);
-        listener.testStarted(testId);
-
-        long testStartTime = System.currentTimeMillis();
-        boolean isRunningBenchmark;
-
-        boolean isTimedOut = false;
-        boolean isResultGenerated = false;
-        Map<String, String> metrics = new HashMap<String, String>();
-        String errMsg = null;
-
-        String deviceModel = device.executeShellCommand("getprop ro.product.model");
-        String resultExcelXmlPath = String.format(mGlbenchmarkExcelResultXmlPath,
-                deviceModel.trim().replaceAll("[ -]", "_").toLowerCase());
-        CLog.i("Result excel xml path:" + resultExcelXmlPath);
-
-        // start glbenchmark and wait for test to complete
-        isTimedOut = false;
-        long benchmarkStartTime = System.currentTimeMillis();
-
-        device.executeShellCommand("am start -a android.intent.action.MAIN "
-                + "-n com.glbenchmark.glbenchmark25/com.glbenchmark.activities.MainActivity "
-                + "--ez custom true");
-        isRunningBenchmark = true;
-        while (isRunningBenchmark && !isResultGenerated && !isTimedOut) {
-            RunUtil.getDefault().sleep(POLLING_INTERVAL_MS);
-            isTimedOut = (System.currentTimeMillis() - benchmarkStartTime >= TIMEOUT_MS);
-            isResultGenerated = device.doesFileExist(resultExcelXmlPath);
-            isRunningBenchmark = device.executeShellCommand("ps").contains("glbenchmark");
-        }
-
-        if (isTimedOut) {
-            errMsg = "GLBenchmark timed out.";
-        } else {
-            // pull result from device
-            File benchmarkReport = device.pullFile(mGlbenchmarkResultXmlPath);
-            if (benchmarkReport != null) {
-                // parse result
-                CLog.i("== GLBenchmark result ==");
-                Map<String, String> benchmarkResult = parseResultXml(benchmarkReport);
-                if (benchmarkResult == null) {
-                    errMsg = "Failed to parse GLBenchmark result XML.";
-                } else {
-                    metrics = benchmarkResult;
-                }
-                // delete results from device and host
-                device.executeShellCommand(String.format("rm %s", mGlbenchmarkResultXmlPath));
-                device.executeShellCommand(String.format("rm %s", resultExcelXmlPath));
-                benchmarkReport.delete();
-            } else {
-                errMsg = "GLBenchmark report not found.";
-            }
-        }
-        if (errMsg != null) {
-            CLog.e(errMsg);
-            listener.testFailed(testId, errMsg);
-            listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
-            listener.testRunFailed(errMsg);
-        } else {
-            long durationMs = System.currentTimeMillis() - testStartTime;
-            listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
-            listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
-        }
-    }
-
-    /**
-     * Parse GLBenchmark result XML.
-     *
-     * @param resultXml GLBenchmark result XML {@link File}
-     * @return a {@link HashMap} that contains metrics key and result
-     */
-    private Map<String, String> parseResultXml(File resultXml) {
-        Map<String, String> benchmarkResult = new HashMap<String, String>();
-        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-        Document doc = null;
-        try {
-            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-            doc = dBuilder.parse(resultXml);
-        } catch (ParserConfigurationException e) {
-            return null;
-        } catch (IOException e) {
-            return null;
-        } catch (SAXException e) {
-            return null;
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-        doc.getDocumentElement().normalize();
-
-        NodeList nodes = doc.getElementsByTagName("test_result");
-        for (int i = 0; i < nodes.getLength(); i++) {
-            Node node = nodes.item(i);
-            if (node.getNodeType() == Node.ELEMENT_NODE) {
-                Element testResult = (Element) node;
-                String testTitle = getData(testResult, "title");
-                String testType = getData(testResult, "type");
-                String fps = getData(testResult, "fps");
-                String score = getData(testResult, "score");
-                String testName = String.format("%s - %s", testTitle, testType);
-                if (METRICS_KEY_MAP.containsKey(testName)) {
-                    if (testName.contains("Fill") || testName.contains("Triangle")) {
-                        // Use Mtexels/sec or MTriangles/sec as unit
-                        score = String.valueOf((long)(Double.parseDouble(score) / 1.0E6));
-                    }
-                    CLog.i(String.format("%s: %s (fps=%s)", testName, score, fps));
-                    String testKey = METRICS_KEY_MAP.get(testName);
-                    if (score != null && !score.trim().equals("0")) {
-                        benchmarkResult.put(testKey, score);
-                        if (fps != null && !fps.trim().equals("0.0")) {
-                            try {
-                                float fpsValue = Float.parseFloat(fps.replace("fps", ""));
-                                benchmarkResult.put(testKey + "-fps", String.valueOf(fpsValue));
-                            } catch (NumberFormatException e) {
-                                CLog.i(String.format("Got %s for fps value. Ignored.", fps));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return benchmarkResult;
-    }
-
-    /**
-     * Get value in the first matching tag under the element
-     *
-     * @param element the parent {@link Element} of the tag
-     * @param tag {@link String} of the tag name
-     * @return a {@link String} that contains the value in the tag; returns null if not found.
-     */
-    private String getData(Element element, String tag) {
-        NodeList tagNodes = element.getElementsByTagName(tag);
-        if (tagNodes.getLength() > 0) {
-            Node tagNode = tagNodes.item(0);
-            if (tagNode.getNodeType() == Node.ELEMENT_NODE) {
-                Node node = tagNode.getChildNodes().item(0);
-                if (node != null) {
-                    return node.getNodeValue();
-                } else {
-                    return null;
-                }
-            }
-        }
-        return null;
-    }
-}
diff --git a/prod-tests/src/com/android/performance/tests/GeekbenchTest.java b/prod-tests/src/com/android/performance/tests/GeekbenchTest.java
deleted file mode 100644
index 38263ea..0000000
--- a/prod-tests/src/com/android/performance/tests/GeekbenchTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.performance.tests;
-
-import com.android.ddmlib.CollectingOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A harness that launches Geekbench and reports result.
- * Requires Geekbench binary and plar file in device temporary directory.
- */
-public class GeekbenchTest implements IDeviceTest, IRemoteTest {
-
-    private static final String RUN_KEY = "geekbench3";
-    private static final int MAX_ATTEMPTS = 3;
-    private static final int TIMEOUT_MS = 10 * 60 * 1000;
-
-    private static final String DEVICE_TEMPORARY_DIR_PATH = "/data/local/tmp/";
-    private static final String GEEKBENCH_BINARY_FILENAME = "geekbench_armeabi-v7a_32";
-    private static final String GEEKBENCH_BINARY_DEVICE_PATH =
-            DEVICE_TEMPORARY_DIR_PATH + GEEKBENCH_BINARY_FILENAME;
-    private static final String GEEKBENCH_PLAR_DEVICE_PATH =
-            DEVICE_TEMPORARY_DIR_PATH + "geekbench.plar";
-    private static final String GEEKBENCH_RESULT_DEVICE_PATH =
-            DEVICE_TEMPORARY_DIR_PATH + "result.txt";
-
-    private static final String OVERALL_SCORE_NAME = "Overall Score";
-    private static final Map<String, String> METRICS_KEY_MAP = createMetricsKeyMap();
-
-    private ITestDevice mDevice;
-
-    private static Map<String, String> createMetricsKeyMap() {
-        Map<String, String> result = new HashMap<String, String>();
-        result.put(OVERALL_SCORE_NAME, "overall");
-        result.put("Integer", "integer");
-        result.put("Floating Point", "floating-point");
-        result.put("Memory", "memory");
-        return Collections.unmodifiableMap(result);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
-        ITestDevice device = getDevice();
-
-        // delete old results
-        device.executeShellCommand(String.format("rm %s", GEEKBENCH_RESULT_DEVICE_PATH));
-
-        Assert.assertTrue(String.format("Geekbench binary not found on device: %s",
-                GEEKBENCH_BINARY_DEVICE_PATH), device.doesFileExist(GEEKBENCH_BINARY_DEVICE_PATH));
-        Assert.assertTrue(String.format("Geekbench binary not found on device: %s",
-                GEEKBENCH_PLAR_DEVICE_PATH), device.doesFileExist(GEEKBENCH_PLAR_DEVICE_PATH));
-
-        listener.testRunStarted(RUN_KEY, 0);
-        listener.testStarted(testId);
-
-        long testStartTime = System.currentTimeMillis();
-        Map<String, String> metrics = new HashMap<String, String>();
-        String errMsg = null;
-
-        // start geekbench and wait for test to complete
-        CollectingOutputReceiver receiver = new CollectingOutputReceiver();
-        device.executeShellCommand(String.format("%s --no-upload --export-json %s",
-                GEEKBENCH_BINARY_DEVICE_PATH, GEEKBENCH_RESULT_DEVICE_PATH), receiver,
-                TIMEOUT_MS, TimeUnit.MILLISECONDS, MAX_ATTEMPTS);
-        CLog.v(receiver.getOutput());
-
-        // pull result from device
-        File benchmarkReport = device.pullFile(GEEKBENCH_RESULT_DEVICE_PATH);
-        if (benchmarkReport != null) {
-            // parse result
-            CLog.i("== Geekbench 3 result ==");
-            Map<String, String> benchmarkResult = parseResultJSON(benchmarkReport);
-            if (benchmarkResult == null) {
-                errMsg = "Failed to parse Geekbench result JSON.";
-            } else {
-                metrics = benchmarkResult;
-            }
-
-            // delete results from device and host
-            benchmarkReport.delete();
-            device.executeShellCommand("rm " + GEEKBENCH_RESULT_DEVICE_PATH);
-        } else {
-            errMsg = "Geekbench report not found.";
-        }
-
-        if (errMsg != null) {
-            CLog.e(errMsg);
-            listener.testFailed(testId, errMsg);
-            listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
-            listener.testRunFailed(errMsg);
-        } else {
-            long durationMs = System.currentTimeMillis() - testStartTime;
-            listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
-            listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
-        }
-    }
-
-    private Map<String, String> parseResultJSON(File resultJson) {
-        Map<String, String> benchmarkResult = new HashMap<String, String>();
-        try {
-            BufferedReader bufferedReader = new BufferedReader(new FileReader(resultJson));
-            String line = bufferedReader.readLine();
-            bufferedReader.close();
-            if (line != null) {
-                JSONTokener tokener = new JSONTokener(line);
-                JSONObject root = new JSONObject(tokener);
-                String overallScore = root.getString("score");
-                benchmarkResult.put(METRICS_KEY_MAP.get(OVERALL_SCORE_NAME), overallScore);
-                CLog.i(String.format("Overall: %s", overallScore));
-                String overallScoreMulticore = root.getString("multicore_score");
-                benchmarkResult.put(METRICS_KEY_MAP.get(OVERALL_SCORE_NAME) + "-multi",
-                        overallScoreMulticore);
-                CLog.i(String.format("Overall-multicore: %s", overallScore));
-                JSONArray arr = root.getJSONArray("sections");
-                for (int i = 0; i < arr.length(); i++) {
-                    JSONObject section = arr.getJSONObject(i);
-                    String sectionName = section.getString("name");
-                    String sectionScore = section.getString("score");
-                    String sectionScoreMulticore = section.getString("multicore_score");
-                    if (METRICS_KEY_MAP.containsKey(sectionName)) {
-                        CLog.i(String.format("%s: %s", sectionName, sectionScore));
-                        CLog.i(String.format("%s-multicore: %s", sectionName,
-                                sectionScoreMulticore));
-                        benchmarkResult.put(METRICS_KEY_MAP.get(sectionName), sectionScore);
-                        CLog.i(String.format("%s-multicore: %s", sectionName,
-                                sectionScoreMulticore));
-                        benchmarkResult.put(METRICS_KEY_MAP.get(sectionName) + "-multi",
-                                sectionScoreMulticore);
-                    }
-                }
-            }
-        } catch (IOException e) {
-            CLog.e("Geekbench3 result file not found.");
-            return null;
-        } catch (JSONException e) {
-            CLog.e("Error parsing Geekbench3 JSON result.");
-            return null;
-        }
-        return benchmarkResult;
-    }
-}
diff --git a/prod-tests/src/com/android/performance/tests/HermeticLaunchTest.java b/prod-tests/src/com/android/performance/tests/HermeticLaunchTest.java
deleted file mode 100644
index bba0dc3..0000000
--- a/prod-tests/src/com/android/performance/tests/HermeticLaunchTest.java
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.performance.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.LogcatReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * To test the app launch performance for the list of activities present in the given target package
- * or the custom list of activities present in the target package.Activities are launched number of
- * times present in the launch count. Launch time is analyzed from the logcat data and more detailed
- * timing(section names) is analyzed from the atrace files captured when launching each activity.
- */
-public class HermeticLaunchTest implements IRemoteTest, IDeviceTest {
-
-    private static enum AtraceSectionOptions {
-        LAYOUT("layout"),
-        DRAW("draw"),
-        BINDAPPLICATION("bindApplication"),
-        ACTIVITYSTART("activityStart"),
-        ONCREATE("onCreate"),
-        INFLATE("inflate");
-
-        private final String name;
-
-        private AtraceSectionOptions(String s) {
-            this.name = s;
-        }
-
-        @Override
-        public String toString() {
-            return name;
-        }
-    }
-
-    private static final String TOTALLAUNCHTIME = "totalLaunchTime";
-    private static final String LOGCAT_CMD = "logcat -v threadtime ActivityManager:* *:s";
-    private static final String LAUNCH_PREFIX="^\\d*-\\d*\\s*\\d*:\\d*:\\d*.\\d*\\s*\\d*\\s*"
-            + "\\d*\\s*I ActivityManager: Displayed\\s*";
-    private static final String LAUNCH_SUFFIX=":\\s*\\+(?<launchtime>.[a-zA-Z\\d]*)\\s*"
-            + "(?<totallaunch>.*)\\s*$";
-    private static final Pattern LAUNCH_ENTRY=Pattern.compile("^\\d*-\\d*\\s*\\d*:\\d*:\\d*."
-            + "\\d*\\s*\\d*\\s*\\d*\\s*I ActivityManager: Displayed\\s*(?<launchinfo>.*)\\s*$");
-    private static final Pattern TRACE_ENTRY1 = Pattern.compile(
-            "^[^-]*-(?<tid>\\d+)\\s+\\[\\d+\\]\\s+\\S{4}\\s+" +
-            "(?<secs>\\d+)\\.(?<usecs>\\d+):\\s+(?<function>.*)\\s*$");
-    private static final Pattern TRACE_ENTRY2 = Pattern.compile(
-            "^[^-]*-(?<tid>\\d+)\\s*\\(\\s*\\d*-*\\)\\s*\\[\\d+\\]\\s+\\S{4}\\s+" +
-            "(?<secs>\\d+)\\.(?<usecs>\\d+):\\s+(?<function>.*)\\s*$");
-    private static final Pattern ATRACE_BEGIN = Pattern
-            .compile("tracing_mark_write: B\\|(?<pid>\\d+)\\|(?<name>.+)");
-    // Matches new and old format of END time stamp.
-    // rformanceLaunc-6315  ( 6315) [007] ...1   182.622217: tracing_mark_write: E|6315
-    // rformanceLaunc-6315  ( 6315) [007] ...1   182.622217: tracing_mark_write: E
-    private static final Pattern ATRACE_END = Pattern.compile(
-            "tracing_mark_write: E\\|*(?<procid>\\d*)");
-    private static final Pattern ATRACE_COUNTER = Pattern
-            .compile("tracing_mark_write: C\\|(?<pid>\\d+)\\|(?<name>[^|]+)\\|(?<value>\\d+)");
-    private static final Pattern ATRACE_HEADER_ENTRIES = Pattern
-            .compile("# entries-in-buffer/entries-written:\\s+(?<buffered>\\d+)/"
-                    + "(?<written>\\d+)\\s+#P:\\d+\\s*");
-    private static final int LOGCAT_SIZE = 20971520; //20 mb
-    private static final long SEC_TO_MILLI = 1000;
-    private static final long MILLI_TO_MICRO = 1000;
-
-    @Option(name = "runner", description = "The instrumentation test runner class name to use.")
-    private String mRunnerName = "android.support.test.runner.AndroidJUnitRunner";
-
-    @Option(name = "package", shortName = 'p',
-            description = "The manifest package name of the Android test application to run.",
-            importance = Importance.IF_UNSET)
-    private String mPackageName = "com.android.performanceapp.tests";
-
-    @Option(name = "target-package", description = "package which contains all the "
-            + "activities to launch")
-    private String mtargetPackage = null;
-
-    @Option(name = "activity-names", description = "Fully qualified activity "
-            + "names separated by comma"
-            + "If not set then all the activities will be included for launching")
-    private String mactivityNames = "";
-
-    @Option(name = "launch-count", description = "number of time to launch the each activity")
-    private int mlaunchCount = 10;
-
-    @Option(name = "save-atrace", description = "Upload the atrace file in permanent storage")
-    private boolean mSaveAtrace = false;
-
-    @Option(name = "atrace-section", description = "Section to be parsed from atrace file. "
-            + "This option can be repeated")
-    private Set<AtraceSectionOptions> mSectionOptionSet = new HashSet<>();
-
-    @Option(name = "instantapp-url", description = "URL used to launch instant app")
-    private String mInstantAppUrl = "";
-
-    private ITestDevice mDevice = null;
-    private IRemoteAndroidTestRunner mRunner;
-    private LogcatReceiver mLogcat;
-    private Set<String> mSectionSet = new HashSet<>();
-    private Map<String, String> mActivityTraceFileMap;
-    private Map<String, Map<String, String>> mActivityTimeResultMap = new HashMap<>();
-    private Map<String,String> activityErrMsg=new HashMap<>();
-
-    @Override
-    public void run(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-
-        mLogcat = new LogcatReceiver(getDevice(), LOGCAT_CMD, LOGCAT_SIZE, 0);
-        mLogcat.start();
-        try {
-            if (mSectionOptionSet.isEmpty()) {
-                // Default sections
-                mSectionOptionSet.add(AtraceSectionOptions.LAYOUT);
-                mSectionOptionSet.add(AtraceSectionOptions.DRAW);
-                mSectionOptionSet.add(AtraceSectionOptions.BINDAPPLICATION);
-                mSectionOptionSet.add(AtraceSectionOptions.ACTIVITYSTART);
-                mSectionOptionSet.add(AtraceSectionOptions.ONCREATE);
-                mSectionOptionSet.add(AtraceSectionOptions.INFLATE);
-            } else if (mSectionOptionSet.contains(AtraceSectionOptions.LAYOUT)) {
-                // If layout is added, draw should also be included
-                mSectionOptionSet.add(AtraceSectionOptions.DRAW);
-            }
-
-            for (AtraceSectionOptions sectionOption : mSectionOptionSet) {
-                mSectionSet.add(sectionOption.toString());
-            }
-
-            //Remove if there is already existing atrace_logs folder
-            mDevice.executeShellCommand("rm -rf ${EXTERNAL_STORAGE}/atrace_logs");
-
-            mRunner = createRemoteAndroidTestRunner(mPackageName, mRunnerName,
-                        mDevice.getIDevice());
-            CollectingTestListener collectingListener = new CollectingTestListener();
-            mDevice.runInstrumentationTests(mRunner, collectingListener);
-
-            Collection<TestResult> testResultsCollection = collectingListener
-                        .getCurrentRunResults().getTestResults().values();
-            List<TestResult> testResults = new ArrayList<>(
-                        testResultsCollection);
-            /*
-             * Expected Metrics : Map of <activity name>=<comma separated list of atrace file names in
-             * external storage of the device>
-             */
-            mActivityTraceFileMap = testResults.get(0).getMetrics();
-            Assert.assertTrue("Unable to get the path to the trace files stored in the device",
-                    (mActivityTraceFileMap != null && !mActivityTraceFileMap.isEmpty()));
-
-            // Analyze the logcat data to get total launch time
-            analyzeLogCatData(mActivityTraceFileMap.keySet());
-        } finally {
-            // Stop the logcat
-            mLogcat.stop();
-        }
-
-        // Analyze the atrace data to get bindApplication,activityStart etc..
-        analyzeAtraceData(listener);
-
-        // Report the metrics to dashboard
-        reportMetrics(listener);
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in.
-     * @param listener The {@link ITestInvocationListener} of test results
-     */
-    private void reportMetrics(ITestInvocationListener listener) {
-        for (String activityName : mActivityTimeResultMap.keySet()) {
-            // Get the activity name alone from pkgname.activityname
-            String[] activityNameSplit = activityName.split("\\.");
-            if (!activityErrMsg.containsKey(activityName)) {
-                Map<String, String> activityMetrics = mActivityTimeResultMap.get(activityName);
-                if (activityMetrics != null && !activityMetrics.isEmpty()) {
-                    CLog.v("Metrics for the activity : %s", activityName);
-                    for (String sectionName : activityMetrics.keySet()) {
-                        CLog.v(String.format("Section name : %s - Time taken : %s",
-                                sectionName, activityMetrics.get(sectionName)));
-                    }
-                    listener.testRunStarted(
-                            activityNameSplit[activityNameSplit.length - 1].trim(), 0);
-                    listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(activityMetrics));
-                }
-            } else {
-                listener.testRunStarted(
-                        activityNameSplit[activityNameSplit.length - 1].trim(), 0);
-                listener.testRunFailed(activityErrMsg.get(activityName));
-            }
-        }
-    }
-
-    /**
-     * Method to create the runner with given list of arguments
-     * @return the {@link IRemoteAndroidTestRunner} to use.
-     * @throws DeviceNotAvailableException
-     */
-    IRemoteAndroidTestRunner createRemoteAndroidTestRunner(String packageName,
-            String runnerName, IDevice device)
-            throws DeviceNotAvailableException {
-        RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
-                packageName, runnerName, device);
-        runner.addInstrumentationArg("targetpackage", mtargetPackage);
-        runner.addInstrumentationArg("launchcount", mlaunchCount + "");
-        if(!mInstantAppUrl.isEmpty()){
-            runner.addInstrumentationArg("instanturl", mInstantAppUrl);
-        }
-        if (mactivityNames != null && !mactivityNames.isEmpty()) {
-            runner.addInstrumentationArg("activitylist", mactivityNames);
-        }
-        if (!mSaveAtrace) {
-            runner.addInstrumentationArg("recordtrace", "false");
-        }
-        return runner;
-    }
-
-    /**
-     * To analyze the log cat data to get the display time reported by activity manager during the
-     * launches
-     * activitySet is set of activityNames returned as a part of testMetrics from the device
-     */
-    public void analyzeLogCatData(Set<String> activitySet) {
-        Map<String, List<Integer>> amLaunchTimes = new HashMap<>();
-
-        Map<Pattern, String> activityPatternMap = new HashMap<>();
-        Matcher match = null;
-        String line;
-
-        /*
-         * Sample line format in logcat
-         * 06-17 16:55:49.6 60 642 I ActivityManager: Displayed pkg/.activity: +Tms (total +9s9ms)
-         */
-        for (String activityName : activitySet) {
-            int lastIndex = activityName.lastIndexOf(".");
-            /*
-             * actvitySet has set of activity names in the format packageName.activityName
-             * logcat has the format packageName/.activityName --> activityAlias
-             */
-            String activityAlias = new String();
-            if (mInstantAppUrl.isEmpty()) {
-                activityAlias = activityName.subSequence(0, lastIndex)
-                        + "/" + activityName.subSequence(lastIndex, activityName.length());
-            } else {
-                activityAlias = mtargetPackage + ".*";
-            }
-            String finalPattern = LAUNCH_PREFIX + activityAlias + LAUNCH_SUFFIX;
-            activityPatternMap.put(Pattern.compile(finalPattern),
-                    activityName);
-        }
-
-        try (InputStreamSource input = mLogcat.getLogcatData();
-                BufferedReader br =
-                        new BufferedReader(new InputStreamReader(input.createInputStream()))) {
-            while ((line = br.readLine()) != null) {
-                /*
-                 * Launch entry needed otherwise we will end up in comparing all the lines for all
-                 * the patterns
-                 */
-                if ((match = matches(LAUNCH_ENTRY, line)) != null) {
-                    for (Pattern pattern : activityPatternMap.keySet()) {
-                        if ((match = matches(pattern, line)) != null) {
-                            CLog.v("Launch Info : %s", line);
-                            int displayTimeInMs = extractLaunchTime(match.group("launchtime"));
-                            String activityName = activityPatternMap.get(pattern);
-                            if (amLaunchTimes.containsKey(activityName)) {
-                                amLaunchTimes.get(activityName).add(displayTimeInMs);
-                            } else {
-                                List<Integer> launchTimes = new ArrayList<>();
-                                launchTimes.add(displayTimeInMs);
-                                amLaunchTimes.put(activityName, launchTimes);
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (IOException io) {
-            CLog.e(io);
-        }
-
-        // Verify logcat data
-        for (String activityName : amLaunchTimes.keySet()) {
-            Assert.assertEquals("Data lost for launch time for the activity :"
-                    + activityName, amLaunchTimes.get(activityName).size(), mlaunchCount);
-        }
-
-        /*
-         * Extract and store the average launch time data reported by activity manager for each
-         * activity
-         */
-        for (String activityName : amLaunchTimes.keySet()) {
-            Double totalTime = 0d;
-            for (Integer launchTime : amLaunchTimes.get(activityName)) {
-                totalTime += launchTime;
-            }
-            Double averageTime = Double.valueOf(totalTime / amLaunchTimes.get(activityName).size());
-            if (mActivityTimeResultMap.containsKey(activityName)) {
-                mActivityTimeResultMap.get(activityName).put(TOTALLAUNCHTIME,
-                        String.format("%.2f", averageTime));
-            } else {
-                Map<String, String> launchTime = new HashMap<>();
-                launchTime.put(TOTALLAUNCHTIME,
-                        String.format("%.2f", averageTime));
-                mActivityTimeResultMap.put(activityName, launchTime);
-            }
-        }
-    }
-
-    /**
-     * To extract the launch time displayed in given line
-     *
-     * @param duration
-     * @return
-     */
-    public int extractLaunchTime(String duration) {
-        String formattedString = duration.replace("ms", "");
-        if (formattedString.contains("s")) {
-            String[] splitString = formattedString.split("s");
-            int finalTimeInMs = Integer.parseInt(splitString[0]) * 1000;
-            finalTimeInMs = finalTimeInMs + Integer.parseInt(splitString[1]);
-            return finalTimeInMs;
-        } else {
-            return Integer.parseInt(formattedString);
-        }
-    }
-
-    /**
-     * To analyze the trace data collected in the device during each activity launch.
-     */
-    public void analyzeAtraceData(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        for (String activityName : mActivityTraceFileMap.keySet()) {
-            try {
-                // Get the list of associated filenames for given activity
-                String filePathAll = mActivityTraceFileMap.get(activityName);
-                Assert.assertNotNull(
-                        String.format("Unable to find trace file paths for activity : %s",
-                                activityName), filePathAll);
-                String[] filePaths = filePathAll.split(",");
-                Assert.assertEquals(String.format("Unable to find file path for all the launches "
-                        + "for the activity :%s", activityName), filePaths.length, mlaunchCount);
-                // Pull and parse the info
-                List<Map<String, List<SectionPeriod>>> mutipleLaunchTraceInfo =
-                        new LinkedList<>();
-                for (int count = 0; count < filePaths.length; count++) {
-                    File currentAtraceFile = pullAtraceInfoFile(filePaths[count]);
-                    String[] splitName = filePaths[count].split("-");
-                    // Process id is appended to original file name
-                    Map<String, List<SectionPeriod>> singleLaunchTraceInfo = parseAtraceInfoFile(
-                            currentAtraceFile,
-                            splitName[splitName.length - 1]);
-                    // Upload the file if needed
-                    if (mSaveAtrace) {
-                        try (FileInputStreamSource stream =
-                                new FileInputStreamSource(currentAtraceFile)) {
-                            listener.testLog(currentAtraceFile.getName(), LogDataType.TEXT, stream);
-                        }
-                    }
-                    // Remove the atrace files
-                    FileUtil.deleteFile(currentAtraceFile);
-                    mutipleLaunchTraceInfo.add(singleLaunchTraceInfo);
-                }
-
-                // Verify and Average out the aTrace Info and store it in result map
-                averageAtraceData(activityName, mutipleLaunchTraceInfo);
-            } catch (FileNotFoundException foe) {
-                CLog.e(foe);
-                activityErrMsg.put(activityName,
-                        "Unable to find the trace file for the activity launch :" + activityName);
-            } catch (IOException ioe) {
-                CLog.e(ioe);
-                activityErrMsg.put(activityName,
-                        "Unable to read the contents of the atrace file for the activity :"
-                                + activityName);
-            }
-        }
-
-    }
-
-    /**
-     * To pull the trace file from the device
-     * @param aTraceFile
-     * @return
-     * @throws DeviceNotAvailableException
-     */
-    public File pullAtraceInfoFile(String aTraceFile)
-            throws DeviceNotAvailableException {
-        String dir = "${EXTERNAL_STORAGE}/atrace_logs";
-        File atraceFileHandler = null;
-        atraceFileHandler = getDevice().pullFile(dir + "/" + aTraceFile);
-        Assert.assertTrue("Unable to retrieve the atrace files", atraceFileHandler != null);
-        return atraceFileHandler;
-    }
-
-    /**
-     * To parse and find the time taken for the given section names in each launch
-     * @param currentAtraceFile
-     * @param sectionSet
-     * @param processId
-     * @return
-     * @throws FileNotFoundException,IOException
-     */
-    public Map<String, List<SectionPeriod>> parseAtraceInfoFile(
-            File currentAtraceFile, String processId)
-            throws FileNotFoundException, IOException {
-        CLog.v("Currently parsing :" + currentAtraceFile.getName());
-        String line;
-        BufferedReader br = null;
-        br = new BufferedReader(new FileReader(currentAtraceFile));
-        LinkedList<TraceRecord> processStack = new LinkedList<>();
-        Map<String, List<SectionPeriod>> sectionInfo = new HashMap<>();
-
-        while ((line = br.readLine()) != null) {
-            // Skip extra lines that aren't part of the trace
-            if (line.isEmpty() || line.startsWith("capturing trace...")
-                    || line.equals("TRACE:") || line.equals("done")) {
-                continue;
-            }
-            // Header information
-            Matcher match = null;
-            // Check if any trace entries were lost
-            if ((match = matches(ATRACE_HEADER_ENTRIES, line)) != null) {
-                int buffered = Integer.parseInt(match.group("buffered"));
-                int written = Integer.parseInt(match.group("written"));
-                if (written != buffered) {
-                    CLog.w(String.format("%d trace entries lost for the file %s",
-                            written - buffered, currentAtraceFile.getName()));
-                }
-            } else if ((match = matches(TRACE_ENTRY1, line)) != null
-                    || (match = matches(TRACE_ENTRY2, line)) != null) {
-                /*
-                 * Two trace entries because trace format differs across devices <...>-tid [yyy]
-                 * ...1 zzz.ttt: tracing_mark_write: B|xxxx|tag_name pkg.name ( tid) [yyy] ...1
-                 * zzz.tttt: tracing_mark_write: B|xxxx|tag_name
-                 */
-                long timestamp = SEC_TO_MILLI
-                        * Long.parseLong(match.group("secs"))
-                        + Long.parseLong(match.group("usecs")) / MILLI_TO_MICRO;
-                // Get the function name from the trace entry
-                String taskId = match.group("tid");
-                String function = match.group("function");
-                // Analyze the lines that matches the processid
-                if (!taskId.equals(processId)) {
-                    continue;
-                }
-                if ((match = matches(ATRACE_BEGIN, function)) != null) {
-                    // Matching pattern looks like tracing_mark_write: B|xxxx|tag_name
-                    String sectionName = match.group("name");
-                    // Push to the stack
-                    processStack.add(new TraceRecord(sectionName, taskId,
-                            timestamp));
-                } else if ((match = matches(ATRACE_END, function)) != null) {
-                    /*
-                     * Matching pattern looks like tracing_mark_write: E Pop from the stack when end
-                     * reaches
-                     */
-                    String endProcId = match.group("procid");
-                    if (endProcId.isEmpty() || endProcId.equals(processId)) {
-                        TraceRecord matchingBegin = processStack.removeLast();
-                        if (mSectionSet.contains(matchingBegin.name)) {
-                            if (sectionInfo.containsKey(matchingBegin.name)) {
-                                SectionPeriod newSecPeriod = new SectionPeriod(
-                                        matchingBegin.timestamp, timestamp);
-                                CLog.v("Section :%s took :%f msecs ",
-                                        matchingBegin.name, newSecPeriod.duration);
-                                sectionInfo.get(matchingBegin.name).add(newSecPeriod);
-                            } else {
-                                List<SectionPeriod> infoList = new LinkedList<>();
-                                SectionPeriod newSecPeriod = new SectionPeriod(
-                                        matchingBegin.timestamp, timestamp);
-                                CLog.v(String.format("Section :%s took :%f msecs ",
-                                        matchingBegin.name, newSecPeriod.duration));
-                                infoList.add(newSecPeriod);
-                                sectionInfo.put(matchingBegin.name, infoList);
-                            }
-                        }
-                    }
-                } else if ((match = matches(ATRACE_COUNTER, function)) != null) {
-                    // Skip this for now. May want to track these later if needed.
-                }
-            }
-
-        }
-        StreamUtil.close(br);
-        return sectionInfo;
-    }
-
-    /**
-     * To take the average of the multiple launches for each activity
-     * @param activityName
-     * @param mutipleLaunchTraceInfo
-     */
-    public void averageAtraceData(String activityName,
-            List<Map<String, List<SectionPeriod>>> mutipleLaunchTraceInfo) {
-        String verificationResult = verifyAtraceMapInfo(mutipleLaunchTraceInfo);
-        if (verificationResult != null) {
-            CLog.w(
-                    "Not all the section info captured for the activity :%s. Missing: %s. "
-                            + "Please go to atrace file to look for detail.",
-                    activityName, verificationResult);
-        }
-        Map<String, Double> launchSum = new HashMap<>();
-        for (String sectionName : mSectionSet) {
-            launchSum.put(sectionName, 0d);
-        }
-        for (Map<String, List<SectionPeriod>> singleLaunchInfo : mutipleLaunchTraceInfo) {
-            for (String sectionName : singleLaunchInfo.keySet()) {
-                for (SectionPeriod secPeriod : singleLaunchInfo
-                        .get(sectionName)) {
-                    if (sectionName.equals(AtraceSectionOptions.DRAW.toString())) {
-                        // Get the first draw time for the launch
-                        Double currentSum = launchSum.get(sectionName)
-                                + secPeriod.duration;
-                        launchSum.put(sectionName, currentSum);
-                        break;
-                    }
-                    //Sum the multiple layout times before the first draw in this launch
-                    if (sectionName.equals(AtraceSectionOptions.LAYOUT.toString())) {
-                        Double drawStartTime = singleLaunchInfo
-                                .get(AtraceSectionOptions.DRAW.toString()).get(0).startTime;
-                        if (drawStartTime < secPeriod.startTime) {
-                            break;
-                        }
-                    }
-                    Double currentSum = launchSum.get(sectionName) + secPeriod.duration;
-                    launchSum.put(sectionName, currentSum);
-                }
-            }
-        }
-        // Update the final result map
-        for (String sectionName : mSectionSet) {
-            Double averageTime = launchSum.get(sectionName)
-                    / mutipleLaunchTraceInfo.size();
-            mActivityTimeResultMap.get(activityName).put(sectionName,
-                    String.format("%.2f", averageTime));
-        }
-    }
-
-    /**
-     * To check if all the section info caught for all the app launches
-     *
-     * @param multipleLaunchTraceInfo
-     * @return String: the missing section name, null if no section info missing.
-     */
-    public String verifyAtraceMapInfo(
-            List<Map<String, List<SectionPeriod>>> multipleLaunchTraceInfo) {
-        for (Map<String, List<SectionPeriod>> singleLaunchInfo : multipleLaunchTraceInfo) {
-            Set<String> testSet = new HashSet<>(mSectionSet);
-            testSet.removeAll(singleLaunchInfo.keySet());
-            if (testSet.size() != 0) {
-                return testSet.toString();
-            }
-        }
-        return null;
-    }
-
-
-    /**
-     * Checks whether {@code line} matches the given {@link Pattern}.
-     * @return The resulting {@link Matcher} obtained by matching the {@code line} against
-     *         {@code pattern}, or null if the {@code line} does not match.
-     */
-    private static Matcher matches(Pattern pattern, String line) {
-        Matcher ret = pattern.matcher(line);
-        return ret.matches() ? ret : null;
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * A record to keep track of the section start time,end time and the duration in milliseconds.
-     */
-    public static class SectionPeriod {
-
-        private double startTime;
-        private double endTime;
-        private double duration;
-
-        public SectionPeriod(double startTime, double endTime) {
-            this.startTime = startTime;
-            this.endTime = endTime;
-            this.duration = endTime - startTime;
-        }
-
-        public double getStartTime() {
-            return startTime;
-        }
-
-        public void setStartTime(long startTime) {
-            this.startTime = startTime;
-        }
-
-        public double getEndTime() {
-            return endTime;
-        }
-
-        public void setEndTime(long endTime) {
-            this.endTime = endTime;
-        }
-
-        public double getDuration() {
-            return duration;
-        }
-
-        public void setDuration(long duration) {
-            this.duration = duration;
-        }
-    }
-
-    /**
-     * A record of a trace event. Includes the name of the section, and the time that the event
-     * occurred (in milliseconds).
-     */
-    public static class TraceRecord {
-
-        private String name;
-        private String processId;
-        private double timestamp;
-
-        /**
-         * Construct a new {@link TraceRecord} with the given {@code name} and {@code timestamp} .
-         */
-        public TraceRecord(String name, String processId, long timestamp) {
-            this.name = name;
-            this.processId = processId;
-            this.timestamp = timestamp;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        public String getProcessId() {
-            return processId;
-        }
-
-        public void setProcessId(String processId) {
-            this.processId = processId;
-        }
-
-        public double getTimestamp() {
-            return timestamp;
-        }
-
-        public void setTimestamp(long timestamp) {
-            this.timestamp = timestamp;
-        }
-    }
-
-}
diff --git a/prod-tests/src/com/android/performance/tests/HermeticMemoryTest.java b/prod-tests/src/com/android/performance/tests/HermeticMemoryTest.java
deleted file mode 100644
index fcde5a2..0000000
--- a/prod-tests/src/com/android/performance/tests/HermeticMemoryTest.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.ProcessInfo;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Test to gather post launch memory details after launching app
- * that include app memory usage and system memory usage
- */
-public class HermeticMemoryTest implements IDeviceTest, IRemoteTest {
-
-    private static final String AM_START = "am start -n %s";
-    private static final String AM_BROADCAST = "am broadcast -a %s -n %s %s";
-    private static final String PROC_MEMINFO = "cat /proc/meminfo";
-    private static final String CACHED_PROCESSES = "dumpsys meminfo|awk '/Total PSS by category:"
-            + "/{found=0} {if(found) print} /: Cached/{found=1}'|tr -d ' '";
-    private static final Pattern PID_PATTERN = Pattern.compile("^.*pid(?<processid>[0-9]*).*$");
-    private static final String DUMPSYS_PROCESS = "dumpsys meminfo %s";
-    private static final String DUMPSYS_MEMINFO = "dumpsys meminfo -a ";
-    private static final String MAPS_INFO = "cat /proc/%d/maps";
-    private static final String SMAPS_INFO = "cat /proc/%d/smaps";
-    private static final String STATUS_INFO = "cat /proc/%d/status";
-    private static final String NATIVE_HEAP = "Native";
-    private static final String DALVIK_HEAP = "Dalvik";
-    private static final String HEAP = "Heap";
-    private static final String MEMTOTAL = "MemTotal";
-    private static final String MEMFREE = "MemFree";
-    private static final String CACHED = "Cached";
-    private static final int NO_PROCESS_ID = -1;
-    private static final String DROP_CACHE = "echo 3 > /proc/sys/vm/drop_caches";
-    private static final String SEPARATOR ="\\s+";
-    private static final String LINE_SEPARATOR = "\\n";
-    private static final String MEM_AVAIL_PATTERN = "^MemAvailable.*";
-    private static final String MEM_TOTAL = "^\\s+TOTAL\\s+.*";
-
-
-    @Option(name = "post-app-launch-delay",
-            description = "The delay, between the app launch and the meminfo dump",
-            isTimeVal = true)
-    private long mPostAppLaunchDelay = 60;
-
-    @Option(name = "component-name",
-            description = "package/activity name to launch the activity")
-    private String mComponentName = new String();
-
-    @Option(name = "intent-action", description = "intent action to broadcast")
-    private String mIntentAction = new String();
-
-    @Option(name = "intent-params", description = "intent parameters")
-    private String mIntentParams = new String();
-
-    @Option(name = "total-memory-kb",
-            description = "Built in total memory of the device")
-    private long mTotalMemory = 0;
-
-    @Option(name = "reporting-key", description = "Reporting key is the unique identifier"
-            + "used to report data in the dashboard.")
-    private String mRuKey = "";
-
-    private ITestDevice mTestDevice = null;
-    private ITestInvocationListener mlistener = null;
-    private Map<String, String> mMetrics = new HashMap<String, String> ();
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        mlistener = listener;
-
-        calculateFreeMem();
-
-        String preMemInfo = mTestDevice.executeShellCommand(PROC_MEMINFO);
-
-        if (!preMemInfo.isEmpty()) {
-
-            uploadLogFile(preMemInfo, "BeforeLaunchProcMemInfo");
-        } else {
-            CLog.e("Not able to collect the /proc/meminfo before launching app");
-        }
-
-        Assert.assertTrue("Device built in memory in kb is mandatory.Use --total-memory-kb value"
-                + "command line parameter",
-                mTotalMemory != 0);
-        RunUtil.getDefault().sleep(5000);
-        mTestDevice.executeShellCommand(DROP_CACHE);
-        RunUtil.getDefault().sleep(5000);
-        Assert.assertTrue("Not a valid component name to start the activity",
-                (mComponentName.split("/").length == 2));
-        if (mIntentAction.isEmpty()) {
-            mTestDevice.executeShellCommand(String.format(AM_START, mComponentName));
-        } else {
-            mTestDevice.executeShellCommand(
-                    String.format(AM_BROADCAST, mIntentAction, mComponentName, mIntentParams));
-        }
-
-        RunUtil.getDefault().sleep(mPostAppLaunchDelay);
-        String postMemInfo = mTestDevice.executeShellCommand(PROC_MEMINFO);
-        int processId = getProcessId();
-        String dumpsysMemInfo = mTestDevice.executeShellCommand(
-                String.format("%s %d", DUMPSYS_MEMINFO, processId));
-        String mapsInfo = mTestDevice.executeShellCommand(
-                String.format(MAPS_INFO, processId));
-        String sMapsInfo = mTestDevice.executeShellCommand(
-                String.format(SMAPS_INFO, processId));
-        String statusInfo = mTestDevice.executeShellCommand(
-                String.format(STATUS_INFO, processId));
-
-        if (!postMemInfo.isEmpty()) {
-            uploadLogFile(postMemInfo, "AfterLaunchProcMemInfo");
-            parseProcInfo(postMemInfo);
-        } else {
-            CLog.e("Not able to collect the proc/meminfo after launching app");
-        }
-
-        if (NO_PROCESS_ID == processId) {
-            CLog.e("Process Id not found for the activity launched");
-        } else {
-            if (!dumpsysMemInfo.isEmpty()) {
-                uploadLogFile(dumpsysMemInfo, String.format("DumpsysMemInfo_%s", mComponentName));
-                parseDumpsysInfo(dumpsysMemInfo);
-            } else {
-                CLog.e("Not able to collect the Dumpsys meminfo after launching app");
-            }
-            if (!mapsInfo.isEmpty()) {
-                uploadLogFile(mapsInfo, "mapsInfo");
-            } else {
-                CLog.e("Not able to collect maps info after launching app");
-            }
-            if (!sMapsInfo.isEmpty()) {
-                uploadLogFile(sMapsInfo, "smapsInfo");
-            } else {
-                CLog.e("Not able to collect smaps info after launching app");
-            }
-            if (!statusInfo.isEmpty()) {
-                uploadLogFile(statusInfo, "statusInfo");
-            } else {
-                CLog.e("Not able to collect status info after launching app");
-            }
-        }
-
-        reportMetrics(listener, mRuKey, mMetrics);
-
-    }
-
-    /**
-     * Method to get the process id of the target package/activity name
-     *
-     * @return processId of the activity launched
-     * @throws DeviceNotAvailableException
-     */
-    private int getProcessId() throws DeviceNotAvailableException {
-        String pkgActivitySplit[] = mComponentName.split("/");
-        if (pkgActivitySplit[0] != null) {
-            ProcessInfo processData = mTestDevice.getProcessByName(pkgActivitySplit[0]);
-            if (null != processData) {
-                return processData.getPid();
-            }
-        }
-        return NO_PROCESS_ID;
-    }
-
-    /**
-     * Method to write the data to test logs.
-     * @param data
-     * @param fileName
-     */
-    private void uploadLogFile(String data, String fileName) {
-        ByteArrayInputStreamSource inputStreamSrc = null;
-        try {
-            inputStreamSrc = new ByteArrayInputStreamSource(data.getBytes());
-            mlistener.testLog(fileName, LogDataType.TEXT, inputStreamSrc);
-        } finally {
-            StreamUtil.cancel(inputStreamSrc);
-        }
-    }
-
-    /**
-     * Method to parse dalvik and heap info for launched app
-     */
-    private void parseDumpsysInfo(String dumpInfo) {
-        String line[] = dumpInfo.split(LINE_SEPARATOR);
-        for (int lineCount = 0; lineCount < line.length; lineCount++) {
-            String dataSplit[] = line[lineCount].trim().split(SEPARATOR);
-            if ((dataSplit[0].equalsIgnoreCase(NATIVE_HEAP) && dataSplit[1]
-                    .equalsIgnoreCase(HEAP)) ||
-                    (dataSplit[0].equalsIgnoreCase(DALVIK_HEAP) && dataSplit[1]
-                            .equalsIgnoreCase(HEAP)) ||
-                    dataSplit[0].equalsIgnoreCase("Total")) {
-                if (dataSplit.length > 10) {
-                    if (dataSplit[0].contains(NATIVE_HEAP)
-                            || dataSplit[0].contains(DALVIK_HEAP)) {
-                        mMetrics.put(dataSplit[0] + ":PSS_TOTAL", dataSplit[2]);
-                        mMetrics.put(dataSplit[0] + ":SHARED_DIRTY", dataSplit[4]);
-                        mMetrics.put(dataSplit[0] + ":PRIVATE_DIRTY", dataSplit[5]);
-                        mMetrics.put(dataSplit[0] + ":HEAP_TOTAL", dataSplit[9]);
-                        mMetrics.put(dataSplit[0] + ":HEAP_ALLOC", dataSplit[10]);
-                    } else {
-                        mMetrics.put(dataSplit[0] + ":PSS", dataSplit[1]);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Method to parse the system memory details
-     */
-    private void parseProcInfo(String memInfo) {
-        String lineSplit[] = memInfo.split(LINE_SEPARATOR);
-        long memTotal = 0;
-        long memFree = 0;
-        long cached = 0;
-        for (int lineCount = 0; lineCount < lineSplit.length; lineCount++) {
-            String line = lineSplit[lineCount].replace(":", "").trim();
-            String dataSplit[] = line.split(SEPARATOR);
-            if (dataSplit[0].equalsIgnoreCase(MEMTOTAL) ||
-                    dataSplit[0].equalsIgnoreCase(MEMFREE) ||
-                    dataSplit[0].equalsIgnoreCase(CACHED)) {
-                if (dataSplit[0].equalsIgnoreCase(MEMTOTAL)) {
-                    memTotal = Long.parseLong(dataSplit[1]);
-                }
-                if (dataSplit[0].equalsIgnoreCase(MEMFREE)) {
-                    memFree = Long.parseLong(dataSplit[1]);
-                }
-                if (dataSplit[0].equalsIgnoreCase(CACHED)) {
-                    cached = Long.parseLong(dataSplit[1]);
-                }
-                mMetrics.put("System_" + dataSplit[0], dataSplit[1]);
-            }
-        }
-        mMetrics.put("System_Kernal_Firmware", String.valueOf((mTotalMemory - memTotal)));
-        mMetrics.put("System_Framework_Apps", String.valueOf((memTotal - (memFree + cached))));
-    }
-
-    /**
-     * Method to parse the free memory based on total memory available from proc/meminfo and
-     * private dirty and private clean information of the cached processess
-     * from dumpsys meminfo.
-     */
-    private void calculateFreeMem() throws DeviceNotAvailableException {
-        String memInfo = mTestDevice.executeShellCommand(PROC_MEMINFO);
-        uploadLogFile(memInfo, "proc_meminfo_In_CacheProcDirty");
-        Pattern p = Pattern.compile(MEM_AVAIL_PATTERN, Pattern.MULTILINE);
-        Matcher m = p.matcher(memInfo);
-        String memAvailable[] = null;
-        if (m.find()) {
-            memAvailable = m.group(0).split(SEPARATOR);
-        }
-        int cacheProcDirty = Integer.parseInt(memAvailable[1]);
-
-        String cachedProcesses = mTestDevice.executeShellCommand(CACHED_PROCESSES);
-        String processes[] = cachedProcesses.split(LINE_SEPARATOR);
-        StringBuilder processesDumpsysInfo = new StringBuilder();
-        for (String process : processes) {
-            Matcher match = null;
-            if (((match = matches(PID_PATTERN, process))) != null) {
-                String processId = match.group("processid");
-                processesDumpsysInfo.append(String.format("Process Name : %s - PID : %s", process,
-                        processId));
-                processesDumpsysInfo.append("\n");
-                String processInfoStr = mTestDevice.executeShellCommand(String.format(
-                        DUMPSYS_PROCESS, processId));
-                processesDumpsysInfo.append(processInfoStr);
-                processesDumpsysInfo.append("\n");
-                Pattern p1 = Pattern.compile(MEM_TOTAL, Pattern.MULTILINE);
-                Matcher m1 = p1.matcher(processInfoStr);
-                String processInfo[] = null;
-                if (m1.find()) {
-                    processInfo = m1.group(0).split(LINE_SEPARATOR);
-                }
-                if (null != processInfo && processInfo.length > 0) {
-                    String procDetails[] = processInfo[0].trim().split(SEPARATOR);
-                    cacheProcDirty = cacheProcDirty + Integer.parseInt(procDetails[2].trim())
-                            + Integer.parseInt(procDetails[3]);
-                }
-            }
-        }
-        uploadLogFile(processesDumpsysInfo.toString(), "ProcessesDumpsysInfo_In_CacheProcDirty");
-        mMetrics.put("MemAvailable_CacheProcDirty", String.valueOf(cacheProcDirty));
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @param runName the test name
-     * @param metrics the {@link Map} that contains metrics for the given test
-     */
-    void reportMetrics(ITestInvocationListener listener, String runName,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics: %s", metrics);
-        listener.testRunStarted(runName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    /**
-     * Checks whether {@code line} matches the given {@link Pattern}.
-     *
-     * @return The resulting {@link Matcher} obtained by matching the {@code line} against
-     *         {@code pattern}, or null if the {@code line} does not match.
-     */
-    private static Matcher matches(Pattern pattern, String line) {
-        Matcher ret = pattern.matcher(line);
-        return ret.matches() ? ret : null;
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-}
-
-
-
diff --git a/prod-tests/src/com/android/performance/tests/StartupMetricsTest.java b/prod-tests/src/com/android/performance/tests/StartupMetricsTest.java
deleted file mode 100644
index 6fabdf4..0000000
--- a/prod-tests/src/com/android/performance/tests/StartupMetricsTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.performance.tests;
-
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.MemInfoItem;
-import com.android.loganalysis.item.ProcrankItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.ITestDevice.RecoveryMode;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests to gather device metrics from during and immediately after boot
- */
-public class StartupMetricsTest implements IDeviceTest, IRemoteTest {
-    public static final String BUGREPORT_LOG_NAME = "bugreport_startup.txt";
-
-    @Option(name="boot-time-ms", description="Timeout in ms to wait for device to boot.")
-    private long mBootTimeMs = 20 * 60 * 1000;
-
-    @Option(name="boot-poll-time-ms", description="Delay in ms between polls for device to boot.")
-    private long mBootPoolTimeMs = 500;
-
-    @Option(name="post-boot-delay-ms",
-            description="Delay in ms after boot complete before taking the bugreport.")
-    private long mPostBootDelayMs = 60000;
-
-    @Option(name="skip-memory-stats", description="Report boot time only, without memory stats.")
-    private boolean mSkipMemoryStats = false;
-
-    ITestDevice mTestDevice = null;
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        executeRebootTest(listener);
-        if (!mSkipMemoryStats) {
-            fetchBugReportMetrics(listener);
-        }
-    }
-
-    /**
-     * Check how long the device takes to come online and become available after
-     * a reboot.
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     */
-    void executeRebootTest(ITestInvocationListener listener) throws DeviceNotAvailableException {
-
-        /*Not using /proc/uptime to get the initial boot time
-        because it includes delays running 'permission utils',
-        and the CPU throttling waiter*/
-        Map<String, String> runMetrics = new HashMap<String, String>();
-        //Initial reboot
-        mTestDevice.rebootIntoBootloader();
-        mTestDevice.setUseFastbootErase(false);
-        mTestDevice.fastbootWipePartition("userdata");
-        mTestDevice.executeFastbootCommand("reboot");
-        mTestDevice.waitForDeviceOnline(10 * 60 * 1000);
-        long initOnlineTime = System.currentTimeMillis();
-        Assert.assertTrue(waitForBootComplete(mTestDevice, mBootTimeMs, mBootPoolTimeMs));
-        long initAvailableTime = System.currentTimeMillis();
-        double initUnavailDuration = initAvailableTime - initOnlineTime;
-        runMetrics.put("init-boot", Double.toString(initUnavailDuration / 1000.0));
-
-        mTestDevice.setRecoveryMode(RecoveryMode.NONE);
-        CLog.d("Reboot test start.");
-        mTestDevice.nonBlockingReboot();
-        long startTime = System.currentTimeMillis();
-        mTestDevice.waitForDeviceOnline();
-        long onlineTime = System.currentTimeMillis();
-        Assert.assertTrue(waitForBootComplete(mTestDevice, mBootTimeMs, mBootPoolTimeMs));
-        long availableTime = System.currentTimeMillis();
-
-        double offlineDuration = onlineTime - startTime;
-        double unavailDuration = availableTime - startTime;
-        CLog.d("Reboot: %f millis until online, %f until available",
-                offlineDuration, unavailDuration);
-        runMetrics.put("online", Double.toString(offlineDuration/1000.0));
-        runMetrics.put("bootcomplete", Double.toString(unavailDuration/1000.0));
-
-        reportMetrics(listener, "boottime", runMetrics);
-    }
-
-    /**
-     * Fetch proc rank metrics from the bugreport after reboot.
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @throws DeviceNotAvailableException
-     */
-    void fetchBugReportMetrics(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        // Make sure the device is available and settled, before getting bugreport.
-        mTestDevice.waitForDeviceAvailable();
-        RunUtil.getDefault().sleep(mPostBootDelayMs);
-        BugreportParser parser = new BugreportParser();
-        BugreportItem bugreport = null;
-        // Retrieve bugreport
-        try (InputStreamSource bugSource = mTestDevice.getBugreport()) {
-            listener.testLog(BUGREPORT_LOG_NAME, LogDataType.BUGREPORT, bugSource);
-            bugreport = parser.parse(new BufferedReader(new InputStreamReader(
-                    bugSource.createInputStream())));
-        } catch (IOException e) {
-            Assert.fail(String.format("Failed to fetch and parse bugreport for device %s: %s",
-                    mTestDevice.getSerialNumber(), e));
-        }
-
-        if (bugreport != null) {
-            // Process meminfo information and post it to the dashboard
-            MemInfoItem item = bugreport.getMemInfo();
-            if (item != null) {
-                Map<String, String> memInfoMap = convertMap(item);
-                reportMetrics(listener, "startup-meminfo", memInfoMap);
-            }
-
-            // Process procrank information and post it to the dashboard
-            if (bugreport.getProcrank() != null) {
-                parseProcRankMap(listener, bugreport.getProcrank());
-            }
-        }
-    }
-
-    /**
-     * Helper method to convert a {@link MemInfoItem} to Map&lt;String, String&gt;.
-     *
-     * @param input the {@link Map} to convert from
-     * @return output the converted {@link Map}
-     */
-    Map<String, String> convertMap(MemInfoItem item) {
-        Map<String, String> output = new HashMap<String, String>();
-        for (String key : item.keySet()) {
-            output.put(key, item.get(key).toString());
-        }
-        return output;
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @param runName the test name
-     * @param metrics the {@link Map} that contains metrics for the given test
-     */
-    void reportMetrics(ITestInvocationListener listener, String runName,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics: %s", metrics);
-        listener.testRunStarted(runName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    /**
-     * Aggregates the procrank data by the pss, rss, and uss values.
-     *
-     * @param listener the {@link ITestInvocationListener} of test results
-     * @param procrank the {@link Map} parsed from brillopad for the procrank section
-     */
-    void parseProcRankMap(ITestInvocationListener listener, ProcrankItem procrank) {
-        // final maps for pss, rss, and uss.
-        Map<String, String> pssOutput = new HashMap<String, String>();
-        Map<String, String> rssOutput = new HashMap<String, String>();
-        Map<String, String> ussOutput = new HashMap<String, String>();
-        // total number of processes.
-        Integer numProcess = 0;
-        // aggregate pss, rss, uss across all processes.
-        Integer pssTotal = 0;
-        Integer rssTotal = 0;
-        Integer ussTotal = 0;
-
-        for (Integer pid : procrank.getPids()) {
-            numProcess++;
-            Integer pss = procrank.getPss(pid);
-            Integer rss = procrank.getRss(pid);
-            Integer uss = procrank.getUss(pid);
-            if (pss != null) {
-                pssTotal += pss;
-                pssOutput.put(procrank.getProcessName(pid), pss.toString());
-            }
-            if (rss != null) {
-                rssTotal += rss;
-                rssOutput.put(procrank.getProcessName(pid), rss.toString());
-            }
-            if (uss != null) {
-                ussTotal += pss;
-                ussOutput.put(procrank.getProcessName(pid), uss.toString());
-            }
-        }
-        // Add aggregation data.
-        pssOutput.put("count", numProcess.toString());
-        pssOutput.put("total", pssTotal.toString());
-        rssOutput.put("count", numProcess.toString());
-        rssOutput.put("total", rssTotal.toString());
-        ussOutput.put("count", numProcess.toString());
-        ussOutput.put("total", ussTotal.toString());
-
-        // Report metrics to dashboard
-        reportMetrics(listener, "startup-procrank-pss", pssOutput);
-        reportMetrics(listener, "startup-procrank-rss", rssOutput);
-        reportMetrics(listener, "startup-procrank-uss", ussOutput);
-    }
-
-    /**
-     * Blocks until the device's boot complete flag is set.
-     *
-     * @param device the {@link ITestDevice}
-     * @param timeOut time in msecs to wait for the flag to be set
-     * @param pollDelay time in msecs between checks
-     * @return true if device's boot complete flag is set within the timeout
-     * @throws DeviceNotAvailableException
-     */
-    private boolean waitForBootComplete(ITestDevice device,long timeOut, long pollDelay)
-            throws DeviceNotAvailableException {
-        long startTime = System.currentTimeMillis();
-        while ((System.currentTimeMillis() - startTime) < timeOut) {
-            String output = device.executeShellCommand("getprop dev.bootcomplete");
-            output = output.replace('#', ' ').trim();
-            if (output.equals("1")) {
-                return true;
-            }
-            RunUtil.getDefault().sleep(pollDelay);
-        }
-        CLog.w("Device %s did not boot after %d ms", device.getSerialNumber(), timeOut);
-        return false;
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mTestDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-}
diff --git a/prod-tests/src/com/android/performance/tests/VellamoBenchmark.java b/prod-tests/src/com/android/performance/tests/VellamoBenchmark.java
deleted file mode 100644
index 3ab15b9..0000000
--- a/prod-tests/src/com/android/performance/tests/VellamoBenchmark.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.performance.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A harness that launches VellamoBenchmark and reports result. Requires
- * VellamoBenchmark apk.
- */
-public class VellamoBenchmark implements IDeviceTest, IRemoteTest {
-
-    private static final String LOGTAG = "VAUTOMATIC";
-    private static final String RUN_KEY = "vellamobenchmark-3202";
-    private static final String PACKAGE_NAME = "com.quicinc.vellamo";
-    private static final long TIMEOUT_MS = 30 * 60 * 1000;
-    private static final long POLLING_INTERVAL_MS = 10 * 1000;
-    private static final int INDEX_NAME = 0;
-    private static final int INDEX_CODE = 4;
-    private static final int INDEX_SCORE = 5;
-
-    private ITestDevice mDevice;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
-        ITestDevice device = getDevice();
-        listener.testRunStarted(RUN_KEY, 0);
-        listener.testStarted(testId);
-
-        long testStartTime = System.currentTimeMillis();
-        Map<String, String> metrics = new HashMap<String, String>();
-        String errMsg = null;
-
-        boolean isTimedOut = false;
-        boolean isResultGenerated = false;
-        boolean hasScore = false;
-        double sumScore = 0;
-        int errorCode = 0;
-        device.clearErrorDialogs();
-        isTimedOut = false;
-
-        long benchmarkStartTime = System.currentTimeMillis();
-        // start the vellamo benchmark app and run all the tests
-        // the documentation and binary for the Vellamo 3.2.2 for Automation APK
-        // can be found here:
-        // https://b.corp.google.com/issue?id=23107318
-        CLog.i("Starting Vellamo Benchmark");
-        device.executeShellCommand("am start -a com.quicinc.vellamo.AUTOMATIC"
-                + " -e w com.quicinc.skunkworks.wvb" // use System WebView
-                + " -n com.quicinc.vellamo/.main.MainActivity");
-        String line;
-        while (!isResultGenerated && !isTimedOut) {
-            RunUtil.getDefault().sleep(POLLING_INTERVAL_MS);
-            isTimedOut = (System.currentTimeMillis() - benchmarkStartTime >= TIMEOUT_MS);
-
-            // get the logcat and parse
-            try (InputStreamSource logcatSource = device.getLogcat();
-                    BufferedReader logcat =
-                            new BufferedReader(
-                                    new InputStreamReader(logcatSource.createInputStream()))) {
-                while ((line = logcat.readLine()) != null) {
-                    // filter only output from the Vellamo process
-                    if (!line.contains(LOGTAG)) {
-                        continue;
-                    }
-                    line = line.substring(line.indexOf(LOGTAG) + LOGTAG.length());
-                    // we need to see if the score is generated since there are some
-                    // cases the result with </automatic> tag is generated but no score is included
-                    if (line.contains("</automatic>")) {
-                        if (hasScore) {
-                            isResultGenerated = true;
-                            break;
-                        }
-                    }
-                    // get the score out
-                    if (line.contains(" b: ")) {
-                        hasScore = true;
-                        String[] results = line.split(" b: ")[1].split(",");
-                        errorCode = Integer.parseInt(results[INDEX_CODE]);
-                        if (errorCode != 0) {
-                            CLog.w("Non-zero error code: %d from becnhmark '%s'",
-                                    errorCode, results[INDEX_NAME]);
-                        } else {
-                            sumScore += Double.parseDouble(results[INDEX_SCORE]);
-                        }
-                        metrics.put(results[INDEX_NAME], results[INDEX_SCORE]);
-                        CLog.i("%s :: %s", results[INDEX_NAME], results[INDEX_SCORE]);
-                    }
-                }
-            } catch (IOException e) {
-                CLog.e(e);
-            }
-
-            if (null == device.getProcessByName(PACKAGE_NAME)) {
-                break;
-            }
-        }
-
-        if (isTimedOut) {
-            errMsg = "Vellamo Benchmark timed out.";
-        } else {
-            CLog.i("Done running Vellamo Benchmark");
-        }
-        if (!hasScore) {
-            errMsg = "Test ended but no scores can be found.";
-        }
-        if (errMsg != null) {
-            CLog.e(errMsg);
-            listener.testFailed(testId, errMsg);
-        }
-        long durationMs = System.currentTimeMillis() - testStartTime;
-        metrics.put("total", Double.toString(sumScore));
-        CLog.i("total :: %f", sumScore);
-        listener.testEnded(testId, new HashMap<String, Metric>());
-        listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-}
diff --git a/prod-tests/src/com/android/sdk/tests/EmulatorGpsPreparer.java b/prod-tests/src/com/android/sdk/tests/EmulatorGpsPreparer.java
deleted file mode 100644
index 44a3e12..0000000
--- a/prod-tests/src/com/android/sdk/tests/EmulatorGpsPreparer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.sdk.tests;
-
-import com.android.ddmlib.EmulatorConsole;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.TargetSetupError;
-
-import org.junit.Assert;
-
-/** Injects specific gps location into emulator. */
-public class EmulatorGpsPreparer extends BaseTargetPreparer {
-
-    // default gps location for the gps test
-    // TODO: make these options rather than hardcoding
-    private static final double LONGITUDE = -122.08345770835876;
-    private static final double LATITUDE = 37.41991859119417;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
-            BuildError, DeviceNotAvailableException {
-        Assert.assertTrue("device is not a emulator", device.getIDevice().isEmulator());
-        EmulatorConsole console = EmulatorConsole.getConsole(device.getIDevice());
-        console.sendLocation(LONGITUDE, LATITUDE, 0);
-    }
-}
diff --git a/prod-tests/src/com/android/sdk/tests/EmulatorSmsPreparer.java b/prod-tests/src/com/android/sdk/tests/EmulatorSmsPreparer.java
deleted file mode 100644
index 35063e0..0000000
--- a/prod-tests/src/com/android/sdk/tests/EmulatorSmsPreparer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.sdk.tests;
-
-import com.android.ddmlib.EmulatorConsole;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.TargetSetupError;
-
-import org.junit.Assert;
-
-/** Sends and SMS message to the emulator */
-public class EmulatorSmsPreparer extends BaseTargetPreparer {
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
-            BuildError, DeviceNotAvailableException {
-        Assert.assertTrue("device is not a emulator", device.getIDevice().isEmulator());
-        EmulatorConsole console = EmulatorConsole.getConsole(device.getIDevice());
-        // these values mus match exactly with platform/development/tools/emulator/...
-        // test-apps/SmsTest/src/com/android/emulator/test/SmsTest.java
-        console.sendSms("5551212","test sms");
-    }
-}
diff --git a/prod-tests/src/com/android/stability/tests/RebootStressTest.java b/prod-tests/src/com/android/stability/tests/RebootStressTest.java
deleted file mode 100644
index 2532a0a..0000000
--- a/prod-tests/src/com/android/stability/tests/RebootStressTest.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.stability.tests;
-
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A test that reboots device many times, and reports successful iteration count.
- */
-public class RebootStressTest implements IRemoteTest, IDeviceTest, IShardableTest {
-
-    private static final String[] LAST_KMSG_PATHS = {
-        "/sys/fs/pstore/console-ramoops-0",
-        "/sys/fs/pstore/console-ramoops",
-        "/proc/last_kmsg",
-    };
-    // max number of ms to allowed for the post-boot waitForDeviceAvailable check
-    private static final long DEVICE_AVAIL_TIME = 3 * 1000;
-
-    @Option(name = "iterations", description = "number of reboot iterations to perform")
-    private int mIterations = 1;
-
-    @Option(name = "shards", description = "Optional number of shards to split test into. " +
-            "Iterations will be split evenly among shards.", importance = Importance.IF_UNSET)
-    private Integer mShards = null;
-
-    @Option(name = "run-name", description =
-            "The test run name used to report metrics.")
-    private String mRunName = "reboot-stress";
-
-    @Option(name = "post-boot-wait-time", description =
-            "Total number of seconds to wait between reboot attempts")
-    private int mWaitTime = 10;
-
-    @Option(name = "post-boot-poll-time", description =
-            "Number of seconds to wait between device health checks")
-    private int mPollSleepTime = 1;
-
-    @Option(name = "wipe-data", description =
-            "Flag to set if userdata should be wiped between reboots")
-    private boolean mWipeUserData = false;
-
-    @Option(name = "wipe-data-cmd", description =
-            "the fastboot command(s) to use to wipe data and reboot device.")
-    private Collection<String> mFastbootWipeCmds = new ArrayList<String>();
-
-    @Option(name = "boot-into-bootloader", description =
-            "Flag to set if reboot should enter bootloader")
-    private boolean mBootIntoBootloader = true;
-
-    private ITestDevice mDevice;
-    private String mLastKmsg;
-    private String mDmesg;
-
-    /**
-     * Set the run name
-     */
-    void setRunName(String runName) {
-        mRunName = runName;
-    }
-
-    /**
-     * Return the number of iterations.
-     * <p/>
-     * Exposed for unit testing
-     */
-    public int getIterations() {
-        return mIterations;
-    }
-
-    /**
-     * Set the iterations
-     */
-    void setIterations(int iterations) {
-        mIterations = iterations;
-    }
-
-    /**
-     * Set the number of shards
-     */
-    void setShards(int shards) {
-        mShards = shards;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    void setWaitTime(int waitTimeSec) {
-        mWaitTime = waitTimeSec;
-    }
-
-    void setPollTime(int pollTime) {
-        mPollSleepTime = pollTime;
-
-    }
-
-    void setWipeData(boolean wipeData) {
-        mWipeUserData = wipeData;
-    }
-
-    void setFastbootWipeDataCmds(Collection<String> cmds) {
-        mFastbootWipeCmds.addAll(cmds);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Collection<IRemoteTest> split() {
-        if (mShards == null || mShards <= 1) {
-            return null;
-        }
-        Collection<IRemoteTest> shards = new ArrayList<IRemoteTest>(mShards);
-        int remainingIterations = mIterations;
-        for (int i = mShards; i > 0; i--) {
-            RebootStressTest testShard = new RebootStressTest();
-            // device will be set by test invoker
-            testShard.setRunName(mRunName);
-            testShard.setWaitTime(mWaitTime);
-            testShard.setWipeData(mWipeUserData);
-            testShard.setFastbootWipeDataCmds(mFastbootWipeCmds);
-            testShard.setPollTime(mPollSleepTime);
-            // attempt to divide iterations evenly among shards with no remainder
-            int iterationsForShard = Math.round(remainingIterations/i);
-            if (iterationsForShard > 0) {
-                testShard.setIterations(iterationsForShard);
-                remainingIterations -= iterationsForShard;
-                shards.add(testShard);
-            }
-        }
-        return shards;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        Assert.assertNotNull(getDevice());
-
-        listener.testRunStarted(mRunName, 0);
-        long startTime = System.currentTimeMillis();
-        int actualIterations = 0;
-        try {
-            for (actualIterations = 0; actualIterations < mIterations; actualIterations++) {
-                CLog.i("Reboot attempt %d of %d", actualIterations+1, mIterations);
-                if (mBootIntoBootloader){
-                    getDevice().rebootIntoBootloader();
-                    if (mWipeUserData) {
-                        executeFastbootWipeCommand();
-                    } else {
-                        getDevice().executeFastbootCommand("reboot");
-                    }
-                } else {
-                    getDevice().reboot();
-                }
-                getDevice().waitForDeviceAvailable();
-                doWaitAndCheck();
-                CLog.logAndDisplay(LogLevel.INFO, "Device %s completed %d of %d iterations",
-                        getDevice().getSerialNumber(), actualIterations+1, mIterations);
-            }
-        } finally {
-            Map<String, String> metrics = new HashMap<String, String>(1);
-            long durationMs = System.currentTimeMillis() - startTime;
-            metrics.put("iterations", Integer.toString(actualIterations));
-            metrics.put("shards", "1");
-            listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
-            if (mLastKmsg != null) {
-                listener.testLog(String.format("last_kmsg_%s", getDevice().getSerialNumber()),
-                        LogDataType.KERNEL_LOG,
-                        new ByteArrayInputStreamSource(mLastKmsg.getBytes()));
-            }
-            if (mDmesg != null) {
-                listener.testLog(String.format("dmesg_%s", getDevice().getSerialNumber()),
-                        LogDataType.KERNEL_LOG, new ByteArrayInputStreamSource(mDmesg.getBytes()));
-            }
-            CLog.logAndDisplay(LogLevel.INFO, "Device %s completed %d of %d iterations",
-                    getDevice().getSerialNumber(), actualIterations, mIterations);
-        }
-    }
-
-    private void executeFastbootWipeCommand() throws DeviceNotAvailableException {
-        if (mFastbootWipeCmds.isEmpty()) {
-            // default to use fastboot -w reboot
-            mFastbootWipeCmds.add("-w reboot");
-        }
-        for (String fastbootCmd : mFastbootWipeCmds) {
-            CLog.i("Running '%s'", fastbootCmd);
-            CommandResult result = getDevice().executeFastbootCommand(fastbootCmd.split(" "));
-            Assert.assertEquals(result.getStderr(), CommandStatus.SUCCESS, result.getStatus());
-        }
-    }
-
-    /**
-     * Perform wait between reboots. Perform periodic checks on device to ensure is still available.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    private void doWaitAndCheck() throws DeviceNotAvailableException {
-        long waitTimeMs = mWaitTime * 1000;
-        long elapsedTime = 0;
-
-        while (elapsedTime < waitTimeMs) {
-            long startTime = System.currentTimeMillis();
-            // ensure device is still up
-            getDevice().waitForDeviceAvailable(DEVICE_AVAIL_TIME);
-            checkForUserDataFailure();
-            RunUtil.getDefault().sleep(mPollSleepTime * 1000);
-            elapsedTime += System.currentTimeMillis() - startTime;
-        }
-    }
-
-    /**
-     * Check logs for userdata formatting/mounting issues.
-     *
-     * @throws DeviceNotAvailableException
-     */
-    private void checkForUserDataFailure() throws DeviceNotAvailableException {
-        for (String path : LAST_KMSG_PATHS) {
-            if (getDevice().doesFileExist(path)) {
-                mLastKmsg = getDevice().executeShellCommand("cat " + path);
-                Assert.assertFalse(String.format("Last kmsg log showed a kernel panic on %s",
-                        getDevice().getSerialNumber()), mLastKmsg.contains("Kernel panic"));
-                break;
-            }
-        }
-        mDmesg = getDevice().executeShellCommand("dmesg");
-        Assert.assertFalse(String.format("Read only mount of userdata detected on %s",
-                getDevice().getSerialNumber()),
-                mDmesg.contains("Remounting filesystem read-only"));
-    }
-}
diff --git a/prod-tests/src/com/android/tradefed/HelloWorldMultiDevices.java b/prod-tests/src/com/android/tradefed/HelloWorldMultiDevices.java
deleted file mode 100644
index 49d1030..0000000
--- a/prod-tests/src/com/android/tradefed/HelloWorldMultiDevices.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.tradefed;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IInvocationContextReceiver;
-import com.android.tradefed.testtype.IMultiDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-
-import org.junit.Assert;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Hello world example of Multiple Devices support in Trade Federation.
- * </p>
- * We implements the existing {@link IRemoteTest} interface to be a TradeFed Tests, and we can now
- * also implement the new {@link IMultiDeviceTest} to get all the device informations for our test.
- * OR you can implement {@link IInvocationContextReceiver} to get the full invocation metadata.
- * </p>
- * In this example we implement both but you should only implement one or the other.
- */
-public class HelloWorldMultiDevices implements IRemoteTest, IMultiDeviceTest,
-        IInvocationContextReceiver {
-
-    private Map<ITestDevice, IBuildInfo> mDevicesInfos;
-    private IInvocationContext mContext;
-
-    @Override
-    public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
-        mDevicesInfos = deviceInfos;
-    }
-
-    @Override
-    public void setInvocationContext(IInvocationContext invocationContext) {
-        mContext = invocationContext;
-    }
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // This is going to iterate over all the devices in the configuration using the
-        // {@link IMultiDeviceTest} interface
-        for (Entry<ITestDevice, IBuildInfo> entry : mDevicesInfos.entrySet()) {
-            CLog.i("Hello World! device '%s' with build id '%s'", entry.getKey().getSerialNumber(),
-                    entry.getValue().getBuildId());
-        }
-
-        // We can also use the IInvocationContext information, which have various functions to
-        // access the ITestDevice or IBuildInfo.
-        for (ITestDevice device : mContext.getDevices()) {
-            CLog.i("Hello World!  device '%s' from context with build '%s'",
-                    device.getSerialNumber(), mContext.getBuildInfo(device));
-        }
-
-        // We can do a look up by the device name in the configuration using the IInvocationContext
-        for (String deviceName : mContext.getDeviceConfigNames()) {
-            CLog.i(
-                    "device '%s' has the name '%s' in the config.",
-                    mContext.getDevice(deviceName).getSerialNumber(), deviceName);
-        }
-
-        // if the device name is known, doing a direct look up is possible.
-        Assert.assertNotNull(mContext.getDevice("device1"));
-        CLog.i(
-                "device named device1 direct look up is '%s'",
-                mContext.getDevice("device1").getSerialNumber());
-    }
-}
diff --git a/prod-tests/src/com/android/tradefed/Sl4aBluetoothDiscovery.java b/prod-tests/src/com/android/tradefed/Sl4aBluetoothDiscovery.java
deleted file mode 100644
index 5dc1fc3..0000000
--- a/prod-tests/src/com/android/tradefed/Sl4aBluetoothDiscovery.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.tradefed;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IMultiDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.sl4a.Sl4aClient;
-import com.android.tradefed.util.sl4a.Sl4aEventDispatcher.EventSl4aObject;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.junit.Assert;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Bluetooth discovery test using Sl4A scripting layer to query some device APIs.
- */
-public class Sl4aBluetoothDiscovery implements IRemoteTest, IMultiDeviceTest {
-
-    private ITestDevice mDut;
-    private ITestDevice mDiscoverer;
-    private Map<ITestDevice, IBuildInfo> mDevicesInfos;
-
-    private static final String BLUETOOTH_NAME = "TEST_NAME";
-
-    @Override
-    public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
-        mDevicesInfos = deviceInfos;
-        List<ITestDevice> listDevices = new ArrayList<>(mDevicesInfos.keySet());
-        mDut = listDevices.get(0);
-        mDiscoverer = listDevices.get(1);
-    }
-
-    /**
-     * Setup the devices state before doing the actual test.
-     *
-     * @param clientDut sl4a client of the device under test (DUT)
-     * @param clientDiscoverer sl4a client of the device doing the discovery of the DUT
-     * @throws IOException
-     */
-    public void setup(Sl4aClient clientDut, Sl4aClient clientDiscoverer) throws IOException {
-        clientDut.rpcCall("bluetoothToggleState", false);
-        clientDut.getEventDispatcher().clearAllEvents();
-        clientDut.rpcCall("bluetoothToggleState", true);
-
-        clientDiscoverer.rpcCall("bluetoothToggleState", false);
-        clientDiscoverer.getEventDispatcher().clearAllEvents();
-        clientDiscoverer.rpcCall("bluetoothToggleState", true);
-
-        EventSl4aObject response = clientDut.getEventDispatcher()
-                .popEvent("BluetoothStateChangedOn", 20000);
-        Assert.assertNotNull(response);
-        response = clientDiscoverer.getEventDispatcher()
-                .popEvent("BluetoothStateChangedOn", 20000);
-        Assert.assertNotNull(response);
-
-        Object rep = clientDut.rpcCall("bluetoothCheckState");
-        Assert.assertEquals(true, rep);
-
-        clientDut.rpcCall("bluetoothSetLocalName", BLUETOOTH_NAME);
-        rep = clientDut.rpcCall("bluetoothGetLocalName");
-        Assert.assertEquals(BLUETOOTH_NAME, rep);
-    }
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // We provide null path for the apk to assume it's already installed.
-        Sl4aClient dutClient = Sl4aClient.startSL4A(mDut, null);
-        Sl4aClient discovererClient = Sl4aClient.startSL4A(mDiscoverer, null);
-
-        TestDescription testId =
-                new TestDescription(this.getClass().getCanonicalName(), "bluetooth_discovery");
-
-        long startTime = System.currentTimeMillis();
-        listener.testRunStarted("sl4a_bluetooth", 1);
-        listener.testStarted(testId);
-
-        try {
-            setup(dutClient, discovererClient);
-            dutClient.rpcCall("bluetoothMakeDiscoverable");
-            Object rep = dutClient.rpcCall("bluetoothGetScanMode");
-            // 3 signifies CONNECTABLE and DISCOVERABLE
-            Assert.assertEquals(3, rep);
-
-            discovererClient.getEventDispatcher().clearAllEvents();
-            discovererClient.rpcCall("bluetoothStartDiscovery");
-            discovererClient.getEventDispatcher()
-                    .popEvent("BluetoothDiscoveryFinished", 60000);
-            Object listDiscovered = discovererClient.rpcCall("bluetoothGetDiscoveredDevices");
-            JSONArray response = (JSONArray) listDiscovered;
-            boolean found = false;
-            for (int i = 0; i < response.length(); i++) {
-                JSONObject j = response.getJSONObject(i);
-                if (j.has("name") && BLUETOOTH_NAME.equals(j.getString("name"))) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                listener.testFailed(testId, "Did not find the bluetooth from DUT.");
-            }
-        } catch (IOException | JSONException e) {
-            CLog.e(e);
-            listener.testFailed(testId, "Exception " + e);
-        } finally {
-            listener.testEnded(testId, new HashMap<String, Metric>());
-            listener.testRunEnded(
-                    System.currentTimeMillis() - startTime, new HashMap<String, Metric>());
-            dutClient.close();
-            discovererClient.close();
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/tradefed/presubmit/DeviceTestsConfigValidation.java b/prod-tests/src/com/android/tradefed/presubmit/DeviceTestsConfigValidation.java
deleted file mode 100644
index aa94674..0000000
--- a/prod-tests/src/com/android/tradefed/presubmit/DeviceTestsConfigValidation.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.tradefed.presubmit;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.ConfigurationFactory;
-import com.android.tradefed.config.ConfigurationUtil;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationFactory;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.suite.ValidateSuiteConfigHelper;
-
-import com.google.common.base.Joiner;
-
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Validation tests to run against the configuration in device-tests.zip to ensure they can all
- * parse.
- *
- * <p>Do not add to UnitTests.java. This is meant to run standalone.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class DeviceTestsConfigValidation implements IBuildReceiver {
-
-    private IBuildInfo mBuild;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = buildInfo;
-    }
-
-    /** Get all the configuration copied to the build tests dir and check if they load. */
-    @Test
-    public void testConfigsLoad() throws Exception {
-        List<String> errors = new ArrayList<>();
-        Assume.assumeTrue(mBuild instanceof IDeviceBuildInfo);
-
-        IConfigurationFactory configFactory = ConfigurationFactory.getInstance();
-        List<File> configs = new ArrayList<>();
-        IDeviceBuildInfo deviceBuildInfo = (IDeviceBuildInfo) mBuild;
-        File testsDir = deviceBuildInfo.getTestsDir();
-        List<File> extraTestCasesDirs = Arrays.asList(testsDir);
-        // Only load the .config as .xml might be data in device-tests.zip case.
-        configs.addAll(
-                ConfigurationUtil.getConfigNamesFileFromDirs(
-                        null, extraTestCasesDirs, Arrays.asList(".*\\.config$")));
-        for (File config : configs) {
-            try {
-                IConfiguration c =
-                        configFactory.createConfigurationFromArgs(
-                                new String[] {config.getAbsolutePath()});
-                // All configurations in device-tests.zip should be module since they are generated
-                // from AndroidTest.xml
-                ValidateSuiteConfigHelper.validateConfig(c);
-                // Add more checks if necessary
-            } catch (ConfigurationException e) {
-                errors.add(String.format("\t%s: %s", config.getName(), e.getMessage()));
-            }
-        }
-
-        // If any errors report them in a final exception.
-        if (!errors.isEmpty()) {
-            throw new ConfigurationException(
-                    String.format("Fail configuration check:\n%s", Joiner.on("\n").join(errors)));
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/tradefed/presubmit/GeneralTestsConfigValidation.java b/prod-tests/src/com/android/tradefed/presubmit/GeneralTestsConfigValidation.java
deleted file mode 100644
index 3c56ea0..0000000
--- a/prod-tests/src/com/android/tradefed/presubmit/GeneralTestsConfigValidation.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.tradefed.presubmit;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.ConfigurationFactory;
-import com.android.tradefed.config.ConfigurationUtil;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationFactory;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.suite.ValidateSuiteConfigHelper;
-
-import com.google.common.base.Joiner;
-
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Validation tests to run against the configuration in general-tests.zip to ensure they can all
- * parse.
- *
- * <p>Do not add to UnitTests.java. This is meant to run standalone.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class GeneralTestsConfigValidation implements IBuildReceiver {
-
-    private IBuildInfo mBuild;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = buildInfo;
-    }
-
-    /** Get all the configuration copied to the build tests dir and check if they load. */
-    @Test
-    public void testConfigsLoad() throws Exception {
-        List<String> errors = new ArrayList<>();
-        Assume.assumeTrue(mBuild instanceof IDeviceBuildInfo);
-
-        IConfigurationFactory configFactory = ConfigurationFactory.getInstance();
-        List<String> configs = new ArrayList<>();
-        IDeviceBuildInfo deviceBuildInfo = (IDeviceBuildInfo) mBuild;
-        File testsDir = deviceBuildInfo.getTestsDir();
-        List<File> extraTestCasesDirs = Arrays.asList(testsDir);
-        configs.addAll(ConfigurationUtil.getConfigNamesFromDirs(null, extraTestCasesDirs));
-        for (String configName : configs) {
-            try {
-                IConfiguration c =
-                        configFactory.createConfigurationFromArgs(new String[] {configName});
-                // All configurations in general-tests.zip should be module since they are generated
-                // from AndroidTest.xml
-                ValidateSuiteConfigHelper.validateConfig(c);
-                // Add more checks if necessary
-            } catch (ConfigurationException e) {
-                errors.add(String.format("\t%s: %s", configName, e.getMessage()));
-            }
-        }
-
-        // If any errors report them in a final exception.
-        if (!errors.isEmpty()) {
-            throw new ConfigurationException(
-                    String.format("Fail configuration check:\n%s", Joiner.on("\n").join(errors)));
-        }
-    }
-}
diff --git a/prod-tests/src/com/android/wireless/tests/RadioHelper.java b/prod-tests/src/com/android/wireless/tests/RadioHelper.java
deleted file mode 100644
index 2b57de6..0000000
--- a/prod-tests/src/com/android/wireless/tests/RadioHelper.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.wireless.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-
-/**
- * Helper class to get device radio settings
- */
-public class RadioHelper {
-    private static final String[] PING_SERVER_LIST = {
-        "www.google.com", "www.facebook.com", "www.bing.com", "www.ask.com", "www.yahoo.com"
-    };
-    private static final int RETRY_ATTEMPTS = 3;
-    private static final int ACTIVATION_WAITING_TIME = 5 * 60 * 1000; // 5 minutes;
-    private static final String WIFI_ONLY = "wifi-only";
-    /* Maximum time to wait for device to connect to data network */
-    public static final int MAX_DATA_SETUP_TIME = 3 * 60 * 1000; // 3 minutes
-    private ITestDevice mDevice;
-
-    RadioHelper(ITestDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * Gets the {@link IRunUtil} instance to use.
-     */
-    IRunUtil getRunUtil() {
-        return RunUtil.getDefault();
-    }
-
-    /**
-     * Get phone type 0 - None, 1 - GSM, 2 - CDMA
-     */
-    private String getPhoneType() throws DeviceNotAvailableException {
-        return mDevice.getProperty("gsm.current.phone-type");
-    }
-
-    /**
-     * Get sim state
-     */
-    private String getSimState() throws DeviceNotAvailableException {
-        return mDevice.getProperty("gsm.sim.state");
-    }
-
-    /**
-     * Verify whether a device is a CDMA only device
-     * @return true for CDMA only device, false for GSM or LTE device
-     * @throws DeviceNotAvailableException
-     */
-    public boolean isCdmaDevice() throws DeviceNotAvailableException {
-        // Wait 30 seconds for SIM to load
-        getRunUtil().sleep(30*1000);
-        String phoneType = null;
-        String simState = null;
-        for (int i = 0; i < RETRY_ATTEMPTS && (phoneType == null || simState == null); i++) {
-            phoneType = getPhoneType();
-            simState = getSimState();
-            CLog.d("phonetype: %s", phoneType);
-            CLog.d("gsm.sim.state: %s", simState);
-            RunUtil.getDefault().sleep(5 * 1000);
-        }
-
-        if (phoneType == null || simState == null) {
-            CLog.d("Error: phoneType or simState is null.");
-            return false;
-        }
-
-        if ((phoneType.compareToIgnoreCase("2") == 0) &&
-            (simState.compareToIgnoreCase("UNKNOWN") == 0)) {
-            // GSM device as phoneType "1"
-            // LTE device should have SIM state set to "READY"
-            CLog.d("it is a CDMA device, return true");
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Verify whether a device is a Wi-Fi only device (e.g. Wingray)
-     */
-    public boolean isWifiOnlyDevice() throws DeviceNotAvailableException {
-        return mDevice.getProperty("ro.carrier").contains(WIFI_ONLY);
-    }
-
-    public void resetBootComplete() throws DeviceNotAvailableException {
-        mDevice.executeShellCommand("setprop dev.bootcomplete 0");
-    }
-
-    public boolean pingTest() throws DeviceNotAvailableException {
-        String failString = "ping: unknown host";
-        // assume the chance that all servers are down is very small
-        for (int i = 0; i < PING_SERVER_LIST.length; i++ ) {
-            String host = PING_SERVER_LIST[i];
-            CLog.d("Start ping test, ping %s", host);
-            String res = mDevice.executeShellCommand("ping -c 10 -w 100 " + host);
-            if (!res.contains(failString)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Activate a device if it is needed.
-     * @return true if the activation is successful.
-     * @throws DeviceNotAvailableException
-     */
-    public boolean radioActivation() throws DeviceNotAvailableException {
-        if (isWifiOnlyDevice()) {
-            return true;
-        }
-        if (!isCdmaDevice()) {
-            // for GSM device and LTE device
-            CLog.d("not a CDMA device, no need to activiate the device");
-            return true;
-        } else if (pingTest()) {
-            // for CDMA device which has been activiated (e.g. no radio updates)
-            CLog.d("CDMA device has been activated.");
-            return true;
-        }
-
-        // Activate a CDMA device which doesn't have data connection yet
-        for (int i = 0; i < RETRY_ATTEMPTS; i++ ) {
-            mDevice.executeShellCommand("radiooptions 8 *22899");
-            long startTime = System.currentTimeMillis();
-            while ((System.currentTimeMillis() - startTime) < ACTIVATION_WAITING_TIME) {
-                getRunUtil().sleep(30 * 1000);
-                if (pingTest()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Wait for device data setup
-     *
-     * @return true if data setup succeeded, false otherwise
-     */
-    public boolean waitForDataSetup() throws DeviceNotAvailableException {
-        long startTime = System.currentTimeMillis();
-        while ((System.currentTimeMillis() - startTime) < MAX_DATA_SETUP_TIME) {
-            getRunUtil().sleep(30 * 1000);
-            if (pingTest()) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/prod-tests/src/com/android/wireless/tests/WifiStressTest.java b/prod-tests/src/com/android/wireless/tests/WifiStressTest.java
deleted file mode 100644
index ddce045..0000000
--- a/prod-tests/src/com/android/wireless/tests/WifiStressTest.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.wireless.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RegexTrie;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Run the WiFi stress tests. This test stresses WiFi soft ap, WiFi scanning
- * and WiFi reconnection in which device switches between cellular and WiFi connection.
- */
-public class WifiStressTest implements IRemoteTest, IDeviceTest {
-    private ITestDevice mTestDevice = null;
-    private static final long START_TIMER = 5 * 60 * 1000; //5 minutes
-    // Define instrumentation test package and runner.
-    private static final String TEST_PACKAGE_NAME = "com.android.connectivitymanagertest";
-    private static final String TEST_RUNNER_NAME = ".ConnectivityManagerStressTestRunner";
-
-    private static final Pattern ITERATION_PATTERN =
-        Pattern.compile("^iteration (\\d+) out of (\\d+)");
-    private static final int AP_TEST_TIMER = 3 * 60 * 60 * 1000; // 3 hours
-    private static final int SCAN_TEST_TIMER = 30 * 60 * 1000; // 30 minutes
-    private static final int RECONNECT_TEST_TIMER = 12 * 60 * 60 * 1000; // 12 hours
-
-    private String mOutputFile = "WifiStressTestOutput.txt";
-
-    /**
-     * Stores the test cases that we should consider running.
-     * <p/>
-     * This currently consists of "ap", "scanning", and "reconnection" tests.
-     */
-    private List<TestInfo> mTestList = null;
-
-    private static class TestInfo {
-        public String mTestName = null;
-        public String mTestClass = null;
-        public String mTestMethod = null;
-        public String mTestMetricsName = null;
-        public int mTestTimer;
-        public RegexTrie<String> mPatternMap = null;
-
-        @Override
-        public String toString() {
-            return String.format("TestInfo: mTestName(%s), mTestClass(%s), mTestMethod(%s)," +
-                    " mTestMetricsName(%s), mPatternMap(%s), mTestTimer(%d)", mTestName,
-                    mTestClass, mTestMethod, mTestMetricsName, mPatternMap.toString(), mTestTimer);
-        }
-    }
-
-    @Option(
-        name = "ap-iteration",
-        description = "The number of iterations to run soft ap stress test"
-    )
-    private String mApIteration = "0";
-
-    @Option(name="idle-time",
-        description="The device idle time after screen off")
-    private String mIdleTime = "30"; // 30 seconds
-
-    @Option(name="reconnect-iteration",
-            description="The number of iterations to run WiFi reconnection stress test")
-    private String mReconnectionIteration = "100";
-
-    @Option(name="reconnect-password",
-            description="The password for the above ssid in WiFi reconnection stress test")
-    private String mReconnectionPassword = "androidwifi";
-
-    @Option(name="reconnect-ssid",
-        description="The ssid for WiFi recoonection stress test")
-    private String mReconnectionSsid = "securenetdhcp";
-
-    @Option(name="reconnection-test",
-        description="Option to run the wifi reconnection stress test")
-    private boolean mReconnectionTestFlag = true;
-
-    @Option(name="scan-iteration",
-        description="The number of iterations to run WiFi scanning test")
-    private String mScanIteration = "100";
-
-    @Option(name="scan-test",
-            description="Option to run the scan stress test")
-    private boolean mScanTestFlag = true;
-
-    @Option(name="skip-set-device-screen-timeout",
-            description="Option to skip screen timeout configuration")
-    private boolean mSkipSetDeviceScreenTimeout = false;
-
-    @Option(name="tether-test",
-            description="Option to run the tethering stress test")
-    private boolean mTetherTestFlag = true;
-
-    @Option(name="wifi-only")
-    private boolean mWifiOnly = false;
-
-    private void setupTests() {
-        if (mTestList != null) {
-            return;
-        }
-        mTestList = new ArrayList<>(3);
-
-        // Add WiFi scanning test
-        TestInfo t = new TestInfo();
-        t.mTestName = "WifiScanning";
-        t.mTestClass = "com.android.connectivitymanagertest.stress.WifiStressTest";
-        t.mTestMethod = "testWifiScanning";
-        t.mTestMetricsName = "wifi_scan_performance";
-        t.mTestTimer = SCAN_TEST_TIMER;
-        t.mPatternMap = new RegexTrie<>();
-        t.mPatternMap.put("avg_scan_time", "^average scanning time is (\\d+)");
-        t.mPatternMap.put("scan_quality","ssid appear (\\d+) out of (\\d+) scan iterations");
-        if (mScanTestFlag) {
-            mTestList.add(t);
-        }
-
-        // Add WiFi reconnection test
-        t = new TestInfo();
-        t.mTestName = "WifiReconnectionStress";
-        t.mTestClass = "com.android.connectivitymanagertest.stress.WifiStressTest";
-        t.mTestMethod = "testWifiReconnectionAfterSleep";
-        t.mTestMetricsName = "wifi_stress";
-        t.mTestTimer = RECONNECT_TEST_TIMER;
-        t.mPatternMap = new RegexTrie<>();
-        t.mPatternMap.put("wifi_reconnection_stress", ITERATION_PATTERN);
-        if (mReconnectionTestFlag) {
-            mTestList.add(t);
-        }
-    }
-
-    /**
-     * Configure screen timeout property
-     * @throws DeviceNotAvailableException
-     */
-    private void setDeviceScreenTimeout() throws DeviceNotAvailableException {
-        // Set device screen_off_timeout as svc power can be set to false in the Wi-Fi test
-        String command = ("sqlite3 /data/data/com.android.providers.settings/databases/settings.db "
-                + "\"UPDATE system SET value=\'600000\' WHERE name=\'screen_off_timeout\';\"");
-        CLog.d("Command to set screen timeout value to 10 minutes: %s", command);
-        mTestDevice.executeShellCommand(command);
-
-        // reboot to allow the setting to take effect, post setup will be taken care by the reboot
-        mTestDevice.reboot();
-    }
-
-    /**
-     * Enable/disable screen never timeout property
-     * @param on
-     * @throws DeviceNotAvailableException
-     */
-    private void setScreenProperty(boolean on) throws DeviceNotAvailableException {
-        CLog.d("set svc power stay on " + on);
-        mTestDevice.executeShellCommand("svc power stayon " + on);
-    }
-
-    @Override
-    public void setDevice(ITestDevice testDevice) {
-        mTestDevice = testDevice;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mTestDevice;
-    }
-
-    /**
-     * Run the Wi-Fi stress test
-     * Collect results and post results to dashboard
-     */
-    @Override
-    public void run(ITestInvocationListener standardListener)
-            throws DeviceNotAvailableException {
-        Assert.assertNotNull(mTestDevice);
-        setupTests();
-        if (!mSkipSetDeviceScreenTimeout) {
-            setDeviceScreenTimeout();
-        }
-        RunUtil.getDefault().sleep(START_TIMER);
-
-        if (!mWifiOnly) {
-            final RadioHelper radioHelper = new RadioHelper(mTestDevice);
-            Assert.assertTrue("Radio activation failed", radioHelper.radioActivation());
-            Assert.assertTrue("Data setup failed", radioHelper.waitForDataSetup());
-        }
-
-        IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
-                TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
-        runner.addInstrumentationArg("softap_iterations", mApIteration);
-        runner.addInstrumentationArg("scan_iterations", mScanIteration);
-        runner.addInstrumentationArg("reconnect_iterations", mReconnectionIteration);
-        runner.addInstrumentationArg("reconnect_ssid", mReconnectionSsid);
-        runner.addInstrumentationArg("reconnect_password", mReconnectionPassword);
-        runner.addInstrumentationArg("sleep_time", mIdleTime);
-        if (mWifiOnly) {
-            runner.addInstrumentationArg("wifi-only", String.valueOf(mWifiOnly));
-        }
-
-        // Add bugreport listener for failed test
-        BugreportCollector bugListener = new
-            BugreportCollector(standardListener, mTestDevice);
-        bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
-        // Device may reboot during the test, to capture a bugreport after that,
-        // wait for 30 seconds for device to be online, otherwise, bugreport will be empty
-        bugListener.setDeviceWaitTime(30);
-
-        for (TestInfo testCase : mTestList) {
-            // for Wi-Fi reconnection test,
-            if ("WifiReconnectionStress".equals(testCase.mTestName)) {
-                setScreenProperty(false);
-            } else {
-                setScreenProperty(true);
-            }
-            CLog.d("TestInfo: " + testCase.toString());
-            runner.setClassName(testCase.mTestClass);
-            runner.setMethodName(testCase.mTestClass, testCase.mTestMethod);
-            runner.setMaxTimeToOutputResponse(testCase.mTestTimer, TimeUnit.MILLISECONDS);
-            bugListener.setDescriptiveName(testCase.mTestName);
-            mTestDevice.runInstrumentationTests(runner, bugListener);
-            logOutputFile(testCase, bugListener);
-            cleanOutputFiles();
-        }
-    }
-
-    /**
-     * Collect test results, report test results to dash board.
-     *
-     * @param test
-     * @param listener
-     */
-    private void logOutputFile(TestInfo test, ITestInvocationListener listener)
-        throws DeviceNotAvailableException {
-        File resFile = null;
-        InputStreamSource outputSource = null;
-
-        try {
-            resFile = mTestDevice.pullFileFromExternal(mOutputFile);
-            if (resFile != null) {
-                // Save a copy of the output file
-                CLog.d("Sending %d byte file %s into the logosphere!",
-                        resFile.length(), resFile);
-                outputSource = new FileInputStreamSource(resFile);
-                listener.testLog(String.format("result-%s.txt", test.mTestName), LogDataType.TEXT,
-                        outputSource);
-
-                // Parse the results file and post results to test listener
-                parseOutputFile(test, resFile, listener);
-            }
-        } finally {
-            FileUtil.deleteFile(resFile);
-            StreamUtil.cancel(outputSource);
-        }
-    }
-
-    private void parseOutputFile(TestInfo test, File dataFile,
-            ITestInvocationListener listener) {
-        Map<String, String> runMetrics = new HashMap<>();
-        Map<String, String> runScanMetrics = null;
-        boolean isScanningTest = "WifiScanning".equals(test.mTestName);
-        Integer iteration = null;
-        BufferedReader br = null;
-        try {
-            br = new BufferedReader(new FileReader(dataFile));
-            String line = null;
-            while ((line = br.readLine()) != null) {
-                List<List<String>> capture = new ArrayList<>(1);
-                String key = test.mPatternMap.retrieve(capture, line);
-                if (key != null) {
-                    CLog.d("In output file of test case %s: retrieve key: %s, " +
-                            "catpure: %s", test.mTestName, key, capture.toString());
-                    //Save results in the metrics
-                    if ("scan_quality".equals(key)) {
-                        // For scanning test, calculate the scan quality
-                        int count = Integer.parseInt(capture.get(0).get(0));
-                        int total = Integer.parseInt(capture.get(0).get(1));
-                        int quality = 0;
-                        if (total != 0) {
-                            quality = (100 * count) / total;
-                        }
-                        runMetrics.put(key, Integer.toString(quality));
-                    } else {
-                        runMetrics.put(key, capture.get(0).get(0));
-                    }
-                } else {
-                    // For scanning test, iterations will also be counted.
-                    if (isScanningTest) {
-                        Matcher m = ITERATION_PATTERN.matcher(line);
-                        if (m.matches()) {
-                            iteration = Integer.parseInt(m.group(1));
-                        }
-                    }
-                }
-            }
-            if (isScanningTest) {
-                runScanMetrics = new HashMap<>(1);
-                if (iteration == null) {
-                    // no matching is found
-                    CLog.d("No iteration logs found in %s, set to 0", mOutputFile);
-                    iteration = Integer.valueOf(0);
-                }
-                runScanMetrics.put("wifi_scan_stress", iteration.toString());
-            }
-
-            // Report results
-            reportMetrics(test.mTestMetricsName, listener, runMetrics);
-            if (isScanningTest) {
-                reportMetrics("wifi_stress", listener, runScanMetrics);
-            }
-        } catch (IOException e) {
-            CLog.e("IOException while reading from data stream");
-            CLog.e(e);
-            return;
-        } finally {
-            StreamUtil.close(br);
-        }
-    }
-
-    /**
-     * Report run metrics by creating an empty test run to stick them in
-     * <p />
-     * Exposed for unit testing
-     */
-    private void reportMetrics(String metricsName, ITestInvocationListener listener,
-            Map<String, String> metrics) {
-        // Create an empty testRun to report the parsed runMetrics
-        CLog.d("About to report metrics to %s: %s", metricsName, metrics);
-        listener.testRunStarted(metricsName, 0);
-        listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
-    }
-
-    /**
-     * Clean up output files from the last test run
-     */
-    private void cleanOutputFiles() throws DeviceNotAvailableException {
-        CLog.d("Remove output file: %s", mOutputFile);
-        String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, mOutputFile));
-    }
-}
diff --git a/prod-tests/tests/.classpath b/prod-tests/tests/.classpath
deleted file mode 100644
index c472a9c..0000000
--- a/prod-tests/tests/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="easymock"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/tf-prod-tests"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/tradefederation"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
-	<classpathentry kind="var" path="TRADEFED_ROOT/out/host/common/obj/JAVA_LIBRARIES/host-libprotobuf-java-full_intermediates/classes.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/prod-tests/tests/.project b/prod-tests/tests/.project
deleted file mode 100644
index b371502..0000000
--- a/prod-tests/tests/.project
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>tf-prod-tests-tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-	<linkedResources>
-		<link>
-			<name>easymock</name>
-			<type>2</type>
-			<location>TRADEFED_ROOT/external/easymock/src</location>
-		</link>
-	</linkedResources>
-</projectDescription>
diff --git a/prod-tests/tests/Android.mk b/prod-tests/tests/Android.mk
deleted file mode 100644
index cc059be..0000000
--- a/prod-tests/tests/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2012 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)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-#LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_JAVACFLAGS += -g -Xlint
-
-LOCAL_MODULE := tf-prod-metatests
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed tf-prod-tests easymock
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# makefile rules to copy jars to HOST_OUT/tradefed
-# so tradefed.sh can automatically add to classpath
-
-DEST_JAR := $(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar
-$(DEST_JAR): $(LOCAL_BUILT_MODULE)
-	$(copy-file-to-new-target)
-
-# this dependency ensure the above rule will be executed if module is built
-$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/prod-tests/tests/MANIFEST.mf b/prod-tests/tests/MANIFEST.mf
deleted file mode 100644
index 19d17b0..0000000
--- a/prod-tests/tests/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Implementation-Version: default
diff --git a/prod-tests/tests/src/com/android/build/tests/ImageStatsTest.java b/prod-tests/tests/src/com/android/build/tests/ImageStatsTest.java
deleted file mode 100644
index c8b8885..0000000
--- a/prod-tests/tests/src/com/android/build/tests/ImageStatsTest.java
+++ /dev/null
@@ -1,149 +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.
- */
-
-package com.android.build.tests;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.ByteArrayInputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Unit tests for {@link ImageStats}
- */
-@RunWith(JUnit4.class)
-public class ImageStatsTest {
-
-    // data obtained from build 4597696, taimen-userdebug_fastbuild_linux
-    private static final String TEST_DATA =
-            "   164424453  /system/app/WallpapersBReel2017/WallpapersBReel2017.apk\n"
-            + "   124082279  /system/app/Chrome/Chrome.apk\n"
-            + "    92966112  /system/priv-app/Velvet/Velvet.apk\n"
-            + "     1790897  /system/framework/ext.jar\n"
-            + "      505436  /system/fonts/NotoSansEgyptianHieroglyphs-Regular.ttf\n"
-            + "      500448  /system/bin/ip6tables\n"
-            + "      500393  /system/usr/share/zoneinfo/tzdata\n"
-            + "      500380  /system/fonts/NotoSansCuneiform-Regular.ttf\n"
-            + "      126391  /system/framework/core-oj.jar\n"
-            + "      122641  /system/framework/com.quicinc.cne.jar\n";
-    private static final Map<String, Long> PARSED_TEST_DATA = new HashMap<>();
-    static {
-        PARSED_TEST_DATA.put("/system/app/WallpapersBReel2017/WallpapersBReel2017.apk",
-                164424453L);
-        PARSED_TEST_DATA.put("/system/app/Chrome/Chrome.apk",
-                124082279L);
-        PARSED_TEST_DATA.put("/system/priv-app/Velvet/Velvet.apk",
-                92966112L);
-        PARSED_TEST_DATA.put("/system/framework/ext.jar",
-                1790897L);
-        PARSED_TEST_DATA.put("/system/fonts/NotoSansEgyptianHieroglyphs-Regular.ttf",
-                505436L);
-        PARSED_TEST_DATA.put("/system/bin/ip6tables",
-                500448L);
-        PARSED_TEST_DATA.put("/system/usr/share/zoneinfo/tzdata",
-                500393L);
-        PARSED_TEST_DATA.put("/system/fonts/NotoSansCuneiform-Regular.ttf",
-                500380L);
-        PARSED_TEST_DATA.put("/system/framework/core-oj.jar",
-                126391L);
-        PARSED_TEST_DATA.put("/system/framework/com.quicinc.cne.jar",
-                122641L);
-    }
-
-    private ImageStats mImageStats = null;
-
-    @Before
-    public void setup() throws Exception {
-        mImageStats = new ImageStats();
-    }
-
-    @Test
-    public void testParseFileSizes() throws Exception {
-        Map<String, Long> ret = mImageStats.parseFileSizes(
-                new ByteArrayInputStream(TEST_DATA.getBytes()));
-        Assert.assertEquals("parsed test file sizes mismatches expectations",
-                PARSED_TEST_DATA, ret);
-    }
-
-    /** Verifies that regular matching pattern without capturing group works as expected */
-    @Test
-    public void testGetAggregationLabel_regular() throws Exception {
-        String fileName = "/system/app/WallpapersBReel2017/WallpapersBReel2017.apk";
-        Pattern pattern = Pattern.compile("^.+\\.apk$");
-        final String label = "foobar";
-        Assert.assertEquals("unexpected label transformation output",
-                label,  mImageStats.getAggregationLabel(pattern.matcher(fileName), label));
-    }
-
-    /** Verifies that matching pattern with corresponding capturing groups works as expected */
-    @Test
-    public void testGetAggregationLabel_capturingGroups() throws Exception {
-        String fileName = "/system/app/WallpapersBReel2017/WallpapersBReel2017.apk";
-        Pattern pattern = Pattern.compile("^/system/(.+?)/.+\\.(.+)$");
-        final String label = "folder-\\1-ext-\\2";
-        Matcher m = pattern.matcher(fileName);
-        Assert.assertTrue("this shouldn't fail unless test case isn't written correctly",
-                m.matches());
-        Assert.assertEquals("unexpected label transformation output",
-                "folder-app-ext-apk",
-                mImageStats.getAggregationLabel(m, label));
-    }
-
-    /**
-     * Verifies that matching pattern with capturing groups but partial back references works
-     * as expected
-     **/
-    @Test
-    public void testGetAggregationLabel_capturingGroups_partialBackReference() throws Exception {
-        String fileName = "/system/app/WallpapersBReel2017/WallpapersBReel2017.apk";
-        Pattern pattern = Pattern.compile("^/system/(.+?)/.+\\.(.+)$");
-        final String label = "ext-\\2";
-        Matcher m = pattern.matcher(fileName);
-        Assert.assertTrue("this shouldn't fail unless test case isn't written correctly",
-                m.matches());
-        Assert.assertEquals("unexpected label transformation output",
-                "ext-apk",
-                mImageStats.getAggregationLabel(m, label));
-    }
-
-    /**
-     * Verifies that aggregating the sample input with patterns works as expected
-     */
-    @Test
-    public void testPerformAggregation() throws Exception {
-        Map<Pattern, String> mapping = new HashMap<>();
-        mapping.put(Pattern.compile("^.+\\.(.+)"), "ext-\\1"); // aggregate by extension
-        mapping.put(Pattern.compile("^/system/(.+?)/.+$"), "folder-\\1"); // aggregate by folder
-        Map<String, String> ret = mImageStats.performAggregation(PARSED_TEST_DATA, mapping);
-        Assert.assertEquals("failed to verify aggregated size for category 'ext-apk'",
-                "381472844", ret.get("ext-apk"));
-        Assert.assertEquals("failed to verify aggregated size for category 'ext-jar'",
-                "2039929", ret.get("ext-jar"));
-        Assert.assertEquals("failed to verify aggregated size for category 'ext-ttf'",
-                "1005816", ret.get("ext-ttf"));
-        Assert.assertEquals("failed to verify aggregated size for category 'uncategorized'",
-                "0", ret.get("uncategorized"));
-        Assert.assertEquals("failed to verify aggregated size for category 'total'",
-                "385519430", ret.get("total"));
-    }
-}
diff --git a/prod-tests/tests/src/com/android/continuous/SmokeTestFailureReporterTest.java b/prod-tests/tests/src/com/android/continuous/SmokeTestFailureReporterTest.java
deleted file mode 100644
index c05f938..0000000
--- a/prod-tests/tests/src/com/android/continuous/SmokeTestFailureReporterTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.continuous;
-
-import com.android.tradefed.build.BuildInfo;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.invoker.InvocationContext;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.util.IEmail;
-import com.android.tradefed.util.IEmail.Message;
-
-import junit.framework.TestCase;
-
-import org.easymock.Capture;
-import org.easymock.EasyMock;
-
-import java.util.HashMap;
-
-/** Unit tests for {@link SmokeTestFailureReporter} */
-public class SmokeTestFailureReporterTest extends TestCase {
-    private SmokeTestFailureReporter mReporter = null;
-    private IEmail mMailer = null;
-
-    private static final String TAG = "DeviceSmokeTests";
-    private static final String BID = "123456";
-    private static final String TARGET = "target?";
-    private static final String FLAVOR = "generic-userdebug";
-    private static final String BRANCH = "git_master";
-
-    @Override
-    public void setUp() {
-        mMailer = EasyMock.createMock(IEmail.class);
-        mReporter = new SmokeTestFailureReporter(mMailer);
-    }
-
-    public void testSingleFail() throws Exception {
-        final String expSubject =
-                "DeviceSmokeTests SmokeFAST failed on: BuildInfo{bid=123456, "
-                        + "target=target?, build_flavor=generic-userdebug, branch=git_master}";
-        final String expBodyStart = "FooTest#testFoo failed\nStack trace:\nthis is a trace\n";
-
-        final HashMap<String, Metric> emptyMap = new HashMap<>();
-        final TestDescription testId = new TestDescription("FooTest", "testFoo");
-        final String trace = "this is a trace";
-
-        final Capture<Message> msgCapture = new Capture<Message>();
-        mMailer.send(EasyMock.capture(msgCapture));
-        EasyMock.replay(mMailer);
-
-        final IBuildInfo build = new BuildInfo(BID, TARGET);
-        build.setBuildFlavor(FLAVOR);
-        build.setBuildBranch(BRANCH);
-        IInvocationContext context = new InvocationContext();
-        context.addDeviceBuildInfo("serial", build);
-        context.setTestTag(TAG);
-
-        mReporter.addDestination("dest.ination@email.com");
-        mReporter.invocationStarted(context);
-        mReporter.testRunStarted("testrun", 1);
-        mReporter.testStarted(testId);
-        mReporter.testFailed(testId, trace);
-        mReporter.testEnded(testId, emptyMap);
-        mReporter.testRunEnded(2, emptyMap);
-        mReporter.invocationEnded(1);
-
-        EasyMock.verify(mMailer);
-
-        assertTrue(msgCapture.hasCaptured());
-        final Message msg = msgCapture.getValue();
-        final String subj = msg.getSubject();
-        final String body = msg.getBody();
-        CLog.i("subject: %s", subj);
-        CLog.i("body:\n%s", body);
-        assertEquals(expSubject, subj);
-        assertTrue(String.format(
-                "Expected body to start with \"\"\"%s\"\"\".  Body was actually: %s\n",
-                expBodyStart, body), body.startsWith(expBodyStart));
-
-    }
-
-    public void testTwoPassOneFail() throws Exception {
-        final String expSubject =
-                "DeviceSmokeTests SmokeFAST failed on: BuildInfo{bid=123456, "
-                        + "target=target?, build_flavor=generic-userdebug, branch=git_master}";
-        final String expBodyStart = "FooTest#testFail failed\nStack trace:\nthis is a trace\n";
-
-        final HashMap<String, Metric> emptyMap = new HashMap<>();
-        final String trace = "this is a trace";
-        final TestDescription testFail = new TestDescription("FooTest", "testFail");
-        final TestDescription testPass1 = new TestDescription("FooTest", "testPass1");
-        final TestDescription testPass2 = new TestDescription("FooTest", "testPass2");
-
-        final Capture<Message> msgCapture = new Capture<Message>();
-        mMailer.send(EasyMock.capture(msgCapture));
-        EasyMock.replay(mMailer);
-
-        IBuildInfo build = new BuildInfo(BID, TARGET);
-        build.setBuildFlavor(FLAVOR);
-        build.setBuildBranch(BRANCH);
-        IInvocationContext context = new InvocationContext();
-        context.addDeviceBuildInfo("serial", build);
-        context.setTestTag(TAG);
-
-        mReporter.addDestination("dest.ination@email.com");
-        mReporter.invocationStarted(context);
-        mReporter.testRunStarted("testrun", 1);
-        mReporter.testStarted(testPass1);
-        mReporter.testEnded(testPass1, emptyMap);
-
-        mReporter.testStarted(testFail);
-        mReporter.testFailed(testFail, trace);
-        mReporter.testEnded(testFail, emptyMap);
-
-        mReporter.testStarted(testPass2);
-        mReporter.testEnded(testPass2, emptyMap);
-        mReporter.testRunEnded(2, emptyMap);
-        mReporter.invocationEnded(1);
-
-        EasyMock.verify(mMailer);
-
-        assertTrue(msgCapture.hasCaptured());
-        final Message msg = msgCapture.getValue();
-        final String subj = msg.getSubject();
-        final String body = msg.getBody();
-        CLog.i("subject: %s", subj);
-        CLog.i("body:\n%s", body);
-        assertEquals(expSubject, subj);
-        assertTrue(String.format(
-                "Expected body to start with \"\"\"%s\"\"\".  Body was actually: %s\n",
-                expBodyStart, body), body.startsWith(expBodyStart));
-    }
-}
diff --git a/prod-tests/tests/src/com/android/continuous/SmokeTestTest.java b/prod-tests/tests/src/com/android/continuous/SmokeTestTest.java
deleted file mode 100644
index 8863b64..0000000
--- a/prod-tests/tests/src/com/android/continuous/SmokeTestTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.continuous;
-
-import com.android.continuous.SmokeTest.TrimListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-
-/**
- * Unit tests for {@link SmokeTest}.
- */
-public class SmokeTestTest extends TestCase {
-    private ITestInvocationListener mListener = null;
-
-    @Override
-    public void setUp() {
-        mListener = EasyMock.createMock(ITestInvocationListener.class);
-    }
-
-    public void testRewrite() {
-        TrimListener trim = new TrimListener(mListener);
-        TestDescription in =
-                new TestDescription(
-                        "com.android.smoketest.SmokeTestRunner$3",
-                        "com.android.voicedialer.VoiceDialerActivity");
-        TestDescription out =
-                new TestDescription("SmokeFAST", "com.android.voicedialer.VoiceDialerActivity");
-        mListener.testStarted(EasyMock.eq(out));
-
-        EasyMock.replay(mListener);
-        trim.testStarted(in);
-        EasyMock.verify(mListener);
-    }
-}
-
diff --git a/prod-tests/tests/src/com/android/monkey/MonkeyBaseTest.java b/prod-tests/tests/src/com/android/monkey/MonkeyBaseTest.java
deleted file mode 100644
index 571d6a0..0000000
--- a/prod-tests/tests/src/com/android/monkey/MonkeyBaseTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.monkey;
-
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.util.ArrayUtil;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Unit tests for {@link MonkeyBase}
- */
-public class MonkeyBaseTest extends TestCase {
-
-    /**
-     * Test that {@link MonkeyBase#setSubtract(Collection, Collection)} returns same object if
-     * exclude is empty.
-     */
-    public void testSetSubtract_noExclude() {
-        Collection<String> haystack = ArrayUtil.list("a", "b", "c");
-        Collection<String> needles = new ArrayList<String>();
-        // double-checking comparison assumptions
-        assertFalse(haystack == needles);
-        Collection<String> output = MonkeyBase.setSubtract(haystack, needles);
-        assertTrue(haystack == output);
-    }
-
-    /**
-     * Test that {@link MonkeyBase#setSubtract(Collection, Collection)} returns the set subtraction
-     * if exclude is not empty.
-     */
-    public void testSetSubtract() {
-        Collection<String> haystack = ArrayUtil.list("a", "b", "c");
-        Collection<String> needles = ArrayUtil.list("b");
-        Collection<String> output = MonkeyBase.setSubtract(haystack, needles);
-        assertEquals(2, output.size());
-        assertTrue(output.contains("a"));
-        assertFalse(output.contains("b"));
-        assertTrue(output.contains("c"));
-    }
-
-    /**
-     * Test success case for {@link MonkeyBase#getUptime()}.
-     */
-    public void testUptime() throws Exception {
-        MonkeyBase monkey = new MonkeyBase();
-        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
-        monkey.setDevice(mockDevice);
-        EasyMock.expect(mockDevice.executeShellCommand("cat /proc/uptime")).andReturn(
-                "5278.73 1866.80");
-        EasyMock.replay(mockDevice);
-        assertEquals("5278.73", monkey.getUptime());
-    }
-
-    /**
-     * Test case for {@link MonkeyBase#getUptime()} where device is initially unresponsive.
-     */
-    public void testUptime_fail() throws Exception {
-        MonkeyBase monkey = new MonkeyBase();
-        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
-        monkey.setDevice(mockDevice);
-        EasyMock.expect(mockDevice.getSerialNumber()).andStubReturn("serial");
-        EasyMock.expect(mockDevice.executeShellCommand("cat /proc/uptime")).andReturn(
-                "");
-        EasyMock.expect(mockDevice.executeShellCommand("cat /proc/uptime")).andReturn(
-                "5278.73 1866.80");
-        EasyMock.replay(mockDevice);
-        assertEquals("5278.73", monkey.getUptime());
-    }
-}
-
diff --git a/prod-tests/tests/src/com/android/tradefed/prodtests/UnitTests.java b/prod-tests/tests/src/com/android/tradefed/prodtests/UnitTests.java
deleted file mode 100644
index 4aec898..0000000
--- a/prod-tests/tests/src/com/android/tradefed/prodtests/UnitTests.java
+++ /dev/null
@@ -1,47 +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.
- */
-package com.android.tradefed.prodtests;
-
-import com.android.build.tests.ImageStatsTest;
-import com.android.continuous.SmokeTestFailureReporterTest;
-import com.android.continuous.SmokeTestTest;
-import com.android.monkey.MonkeyBaseTest;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-/**
- * A test suite for all Trade Federation unit tests running under Junit4.
- *
- * <p>All tests listed here should be self-contained, and should not require any external
- * dependencies.
- */
-@RunWith(Suite.class)
-@SuiteClasses({
-    // build.tests
-    ImageStatsTest.class,
-
-    // Continuous
-    SmokeTestFailureReporterTest.class,
-    SmokeTestTest.class,
-
-    // monkey
-    MonkeyBaseTest.class
-})
-public class UnitTests {
-    // empty of purpose
-}
diff --git a/src/com/android/tradefed/result/InvocationStatus.java b/src/com/android/tradefed/result/InvocationStatus.java
index 3de082c..7f8e39b 100644
--- a/src/com/android/tradefed/result/InvocationStatus.java
+++ b/src/com/android/tradefed/result/InvocationStatus.java
@@ -20,15 +20,4 @@
  */
 public enum InvocationStatus {
     SUCCESS, FAILED, BUILD_ERROR;
-
-    Throwable mThrowable = null;
-
-
-    public void setThrowable(Throwable t) {
-        mThrowable = t;
-    }
-
-    public Throwable getThrowable() {
-        return mThrowable;
-    }
 }
diff --git a/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java b/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java
index 960fb1b..0ebe9c6 100644
--- a/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java
+++ b/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java
@@ -30,6 +30,12 @@
 public class TestRecordProtoUtil {
 
     /**
+     * Pick a 4MB default size to allow the buffer to grow for big protobuf. The default value could
+     * fail in some cases.
+     */
+    private static final int DEFAULT_SIZE_BYTES = 4 * 1024 * 1024;
+
+    /**
      * Read {@link TestRecord} from a file and return it.
      *
      * @param protoFile The {@link File} containing the record
@@ -42,12 +48,14 @@
         try (InputStream stream = new FileInputStream(protoFile)) {
             CodedInputStream is = CodedInputStream.newInstance(stream);
             is.setSizeLimit(Integer.MAX_VALUE);
-            ByteArrayList data = new ByteArrayList();
+            ByteArrayList data = new ByteArrayList(DEFAULT_SIZE_BYTES);
             while (!is.isAtEnd()) {
                 int size = is.readRawVarint32();
-                data.addAll(is.readRawBytes(size));
+                byte[] dataByte = is.readRawBytes(size);
+                data.addAll(dataByte);
             }
             record = TestRecord.parseFrom(data.getContents());
+            data.clear();
         }
         return record;
     }
