Revert submission 9940985-qpr1-dev merge

Reason for revert: broke tests b/146476630
Bug: 146476630
Reverted Changes: I3c5098c02a0f045463ef01c62b99f1006f7b5831

Change-Id: Ia57bbbc28377d999673b286ec89b66f1795ce2b9
Exclude merging into branches containing the latest aosp change included in this merge.
Merged-In: f61d0985958c7ec8f17e4540d9a6437e52e9b8a2
diff --git a/.classpath b/.classpath
index c597d5e..90d68f4 100644
--- a/.classpath
+++ b/.classpath
@@ -7,6 +7,5 @@
 	<classpathentry kind="var" path="TRADEFED_ROOT/out/host/common/obj/JAVA_LIBRARIES/host-libprotobuf-java-full_intermediates/classes.jar"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/loganalysis"/>
 	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/tools/tradefederation/core/tradefed-protos/linux_glibc_common/combined/tradefed-protos.jar"/>
-	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/external/guava/guava-jre/linux_glibc_common/combined/guava-jre.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index df0fc80..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,35 +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.
-
-
-tradefed_java_library_host {
-    name: "tradefed-contrib",
-    defaults: ["tradefed_errorprone_defaults"],
-
-    // Only compile source java files in this lib.
-    srcs: ["src/**/*.java"],
-
-    java_resource_dirs: ["res"],
-
-    javacflags: [
-        "-g",
-        "-Xlint",
-    ],
-
-    libs: [
-        "tradefed",
-        "loganalysis",
-        "tools-common-prebuilt",
-    ],
-}
diff --git a/OWNERS b/OWNERS
deleted file mode 100644
index d9ac483..0000000
--- a/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Owners for modifying any build rules related to the contrib folder
-per-file Android.bp,Android.mk = guangzhu@google.com,jdesprez@google.com,tsu@google.com
diff --git a/Android.mk b/build/Android.mk
similarity index 60%
rename from Android.mk
rename to build/Android.mk
index 7d30491..dbb6487 100644
--- a/Android.mk
+++ b/build/Android.mk
@@ -14,17 +14,33 @@
 
 LOCAL_PATH := $(call my-dir)
 COMPATIBILITY.tradefed_tests_dir := \
-  $(COMPATIBILITY.tradefed_tests_dir) $(LOCAL_PATH)/res/config
+  $(COMPATIBILITY.tradefed_tests_dir) $(LOCAL_PATH)/../res/config
+
+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 := tradefed-contrib
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_JAVA_LIBRARIES := tradefed loganalysis tools-common-prebuilt
+
+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/tradefed-contrib.jar
-BUILT_JAR := $(call intermediates-dir-for,JAVA_LIBRARIES,tradefed-contrib,HOST)/javalib.jar
-$(DEST_JAR): $(BUILT_JAR)
+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
-$(HOST_OUT_JAVA_LIBRARIES)/tradefed-contrib.jar : $(DEST_JAR)
+$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
 
 # Build all sub-directories
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/build/OWNERS b/build/OWNERS
new file mode 100644
index 0000000..dd703a5
--- /dev/null
+++ b/build/OWNERS
@@ -0,0 +1,4 @@
+# Owners for modifying any build rules related to the contrib folder
+guangzhu@google.com
+jdesprez@google.com
+tsu@google.com
diff --git a/res/config/framework/preloaded-classes.xml b/res/config/framework/preloaded-classes.xml
new file mode 100644
index 0000000..38332d3
--- /dev/null
+++ b/res/config/framework/preloaded-classes.xml
@@ -0,0 +1,24 @@
+<?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/res/config/google/test/framework/media/audio-loopback-stress.xml b/res/config/google/test/framework/media/audio-loopback-stress.xml
index a15d9d9..cf189a9 100644
--- a/res/config/google/test/framework/media/audio-loopback-stress.xml
+++ b/res/config/google/test/framework/media/audio-loopback-stress.xml
@@ -13,7 +13,7 @@
   </target_preparer>
 
   <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup">
-    <option name="apk-path" value="gs://tradefed_test_resources/teams/tradefed/testdata/media/apps/Loopback.apk" />
+    <option name="apk-path" value="/google/data/ro/teams/tradefed/testdata/media/apps/Loopback.apk" />
   </target_preparer>
 
   <test class="com.android.media.tests.AudioLoopbackTest">
diff --git a/res/config/google/test/framework/media/audio-loopback.xml b/res/config/google/test/framework/media/audio-loopback.xml
index 6d99589..2031f51 100644
--- a/res/config/google/test/framework/media/audio-loopback.xml
+++ b/res/config/google/test/framework/media/audio-loopback.xml
@@ -9,7 +9,7 @@
     <option name="google-device-setup:setprop" value="audio.safemedia.bypass=1"/>
 
     <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup">
-        <option name="apk-path" value="gs://tradefed_test_resources/teams/tradefed/testdata/media/apps/Loopback.apk" />
+        <option name="apk-path" value="/google/data/ro/teams/tradefed/testdata/media/apps/Loopback.apk" />
     </target_preparer>
 
     <test class="com.android.media.tests.AudioLoopbackTest" />
diff --git a/res/config/longevity/metrics-collectors.xml b/res/config/longevity/metrics-collectors.xml
new file mode 100644
index 0000000..3c328b7
--- /dev/null
+++ b/res/config/longevity/metrics-collectors.xml
@@ -0,0 +1,48 @@
+<?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/res/config/template/atest_local_min.xml b/res/config/longevity/preparers.xml
similarity index 63%
rename from res/config/template/atest_local_min.xml
rename to res/config/longevity/preparers.xml
index 3cde23f..5168a62 100644
--- a/res/config/template/atest_local_min.xml
+++ b/res/config/longevity/preparers.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
+<!-- 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.
@@ -13,8 +13,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<!-- Common configuration for atest's local runs with minimum overhead. -->
-<configuration description="Common configuration for atest's local runs with minimum overhead">
-    <log_saver class="com.android.tradefed.result.ATestFileSystemLogSaver" />
-    <include name="template/local_min_base" />
+<!-- 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/res/config/longevity/test.xml b/res/config/longevity/test.xml
new file mode 100644
index 0000000..754ea35
--- /dev/null
+++ b/res/config/longevity/test.xml
@@ -0,0 +1,34 @@
+<?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/res/config/monkey/app-metrics.xml b/res/config/monkey/app-metrics.xml
index 2fdcec0..76b8cee 100644
--- a/res/config/monkey/app-metrics.xml
+++ b/res/config/monkey/app-metrics.xml
@@ -27,5 +27,6 @@
         <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>
+</configuration>
\ No newline at end of file
diff --git a/res/config/monkey/application.xml b/res/config/monkey/application.xml
index cdbc227..711538d 100644
--- a/res/config/monkey/application.xml
+++ b/res/config/monkey/application.xml
@@ -27,6 +27,7 @@
         <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>
+</configuration>
\ No newline at end of file
diff --git a/res/config/template/local.xml b/res/config/template/local.xml
index 3261e6e..6520e72 100644
--- a/res/config/template/local.xml
+++ b/res/config/template/local.xml
@@ -17,6 +17,10 @@
 <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" />
diff --git a/res/config/template/local_min.xml b/res/config/template/local_min.xml
index 9ad2534..3a5609c 100644
--- a/res/config/template/local_min.xml
+++ b/res/config/template/local_min.xml
@@ -13,8 +13,24 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<!-- Common configuration for local runs with minimum overhead. -->
-<configuration description="Common configuration for local runs with minimum overhead">
+<!-- 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" />
-    <include name="template/local_min_base"/>
+    <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
+    <result_reporter class="com.android.tradefed.result.suite.SuiteResultReporter" />
+    <template-include name="reporters" default="empty" />
+    <template-include name="metrics_collector" default="empty" />
 </configuration>
diff --git a/res/config/template/local_min_base.xml b/res/config/template/local_min_base.xml
deleted file mode 100644
index f4f33e1..0000000
--- a/res/config/template/local_min_base.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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" />
-
-    <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>
-    <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
-    <result_reporter class="com.android.tradefed.result.suite.SuiteResultReporter" />
-    <template-include name="reporters" default="empty" />
-    <template-include name="metrics_collector" default="empty" />
-</configuration>
diff --git a/res/config/template/preparers/ae-profile.xml b/res/config/template/preparers/ae-profile.xml
deleted file mode 100644
index b6ed4fd..0000000
--- a/res/config/template/preparers/ae-profile.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 Google Inc. All Rights Reserved -->
-<configuration description="Configuration to create an Android Enterprise managed profile." >
-    <target_preparer class="com.android.aetest.tradefed.targetprep.AeTestManagedProfileCreator">
-        <!-- Disabled by default; can be enabled on a test-by-test basis. -->
-        <option name="disable" value="true" />
-    </target_preparer>
-</configuration>
diff --git a/res/config/template/preparers/switch-user.xml b/res/config/template/preparers/switch-user.xml
deleted file mode 100644
index 22f848c..0000000
--- a/res/config/template/preparers/switch-user.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 Google Inc. All Rights Reserved -->
-<configuration description="A preparer for switching to a different user.">
-    <!-- By default it does not switch. -->
-    <target_preparer class="com.android.tradefed.targetprep.SwitchUserTargetPreparer" />
-</configuration>
\ No newline at end of file
diff --git a/src/com/android/aetest/tradefed/targetprep/AeTestManagedProfileCreator.java b/src/com/android/aetest/tradefed/targetprep/AeTestManagedProfileCreator.java
deleted file mode 100644
index 499f114..0000000
--- a/src/com/android/aetest/tradefed/targetprep/AeTestManagedProfileCreator.java
+++ /dev/null
@@ -1,162 +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.aetest.tradefed.targetprep;
-
-import static com.android.tradefed.util.BuildTestsZipUtils.getApkFile;
-
-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.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.targetprep.AltDirBehavior;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.ITargetCleaner;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A {@link ITargetPreparer} that creates a managed profile in the testing device.
- *
- * <p>This was forked off Android Enterprise team's target preparer, where its method of resolving
- * the test APK was substituted with the platform's implementation. It is also modified to use the
- * standard TradeFed way of disabling a preparer. The two classes are otherwise the same.
- */
-@OptionClass(alias = "ae-test-create-managed-profile")
-public class AeTestManagedProfileCreator extends BaseTargetPreparer implements ITargetCleaner {
-
-    @Option(
-            name = "profile-owner-component",
-            description = "Profile owner component to set; optional")
-    private String mProfileOwnerComponent = null;
-
-    @Option(name = "profile-owner-apk", description = "Profile owner apk path; optional")
-    private String mProfileOwnerApk = null;
-
-    @Option(
-            name = "alt-dir",
-            description =
-                    "Alternate directory to look for the apk if the apk is not in the tests "
-                            + "zip file. For each alternate dir, will look in //, //data/app, "
-                            + "//DATA/app, //DATA/app/apk_name/ and //DATA/priv-app/apk_name/. "
-                            + "Can be repeated. Look for apks in last alt-dir first.")
-    private List<File> mAltDirs = new ArrayList<>();
-
-    @Option(
-            name = "alt-dir-behavior",
-            description =
-                    "The order of alternate directory to be used "
-                            + "when searching for apks to install")
-    private AltDirBehavior mAltDirBehavior = AltDirBehavior.FALLBACK;
-
-    /** UserID for user in managed profile. */
-    private int mManagedProfileUserId;
-
-    /** {@inheritDoc} */
-    @Override
-    public void setUp(ITestDevice device, IBuildInfo buildInfo)
-            throws TargetSetupError, DeviceNotAvailableException {
-        String pmCommand =
-                "pm create-user --profileOf 0 --managed "
-                        + "TestProfile_"
-                        + System.currentTimeMillis();
-        String pmCommandOutput = device.executeShellCommand(pmCommand);
-
-        // Extract the id of the new user.
-        String[] pmCmdTokens = pmCommandOutput.split("\\s+");
-        if (!pmCmdTokens[0].contains("Success:")) {
-            throw new TargetSetupError("Managed profile creation failed.");
-        }
-        mManagedProfileUserId = Integer.parseInt(pmCmdTokens[pmCmdTokens.length - 1]);
-
-        // Start managed profile user.
-        device.startUser(mManagedProfileUserId);
-
-        CLog.i(String.format("New user created: %d", mManagedProfileUserId));
-
-        if (mProfileOwnerComponent != null && mProfileOwnerApk != null) {
-            device.installPackageForUser(
-                    getApk(device, buildInfo, mProfileOwnerApk), true, mManagedProfileUserId);
-            String command =
-                    String.format(
-                            "dpm set-profile-owner --user %d %s",
-                            mManagedProfileUserId, mProfileOwnerComponent);
-            String commandOutput = device.executeShellCommand(command);
-            String[] cmdTokens = commandOutput.split("\\s+");
-            if (!cmdTokens[0].contains("Success:")) {
-                throw new RuntimeException(
-                        String.format(
-                                "Fail to setup %s as profile owner.", mProfileOwnerComponent));
-            }
-
-            CLog.i(
-                    String.format(
-                            "%s was set as profile owner of user %d",
-                            mProfileOwnerComponent, mManagedProfileUserId));
-        }
-
-        // Reboot device to create the apps in managed profile.
-        device.reboot();
-        device.waitForDeviceAvailable();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void tearDown(ITestDevice testDevice, IBuildInfo buildInfo, Throwable throwable)
-            throws DeviceNotAvailableException {
-        testDevice.removeUser(mManagedProfileUserId);
-    }
-
-    /**
-     * Get the {@link File} object that refers to the APK to install.
-     *
-     * <p>This is a replacement of the method with a similar signature in the original class's super
-     * class, so that the above code can align as closely to the original class as possible.
-     */
-    private File getApk(ITestDevice device, IBuildInfo buildInfo, String fileName)
-            throws TargetSetupError {
-        try {
-            File apkFile =
-                    getApkFile(
-                            buildInfo,
-                            mProfileOwnerApk,
-                            mAltDirs,
-                            mAltDirBehavior,
-                            false /* use resource as fallback */,
-                            null /* device signing key */);
-            if (apkFile == null) {
-                throw new TargetSetupError(
-                        String.format("Test app %s was not found.", mProfileOwnerApk),
-                        device.getDeviceDescriptor());
-            }
-            return apkFile;
-        } catch (IOException e) {
-            throw new TargetSetupError(
-                    String.format(
-                            "failed to resolve apk path for apk %s in build %s",
-                            mProfileOwnerApk, buildInfo.toString()),
-                    e,
-                    device.getDeviceDescriptor());
-        }
-    }
-}
diff --git a/src/com/android/app/tests/AppLaunchTest.java b/src/com/android/app/tests/AppLaunchTest.java
index 35ebd30..af34c7a 100644
--- a/src/com/android/app/tests/AppLaunchTest.java
+++ b/src/com/android/app/tests/AppLaunchTest.java
@@ -18,8 +18,6 @@
 import com.android.tradefed.build.IAppBuildInfo;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.build.VersionedFile;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
@@ -45,13 +43,11 @@
  * <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, IConfigurationReceiver {
+public class AppLaunchTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
 
     private static final String RUN_NAME = "AppLaunch";
     private ITestDevice mDevice;
     private IBuildInfo mBuild;
-    private IConfiguration mConfiguration;
 
     /** {@inheritDoc} */
     @Override
@@ -71,12 +67,6 @@
         mBuild = buildInfo;
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public void setConfiguration(IConfiguration config) {
-        mConfiguration = config;
-    }
-
     /**
      * 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
@@ -139,7 +129,6 @@
         i.setPackageName("com.android.applaunchtest");
         i.setRunnerName("com.android.applaunchtest.AppLaunchRunner");
         i.setDevice(getDevice());
-        i.setConfiguration(mConfiguration);
         i.addInstrumentationArg("packageName", packageName);
         i.run(listener);
         try (InputStreamSource s = getDevice().getScreenshot()) {
diff --git a/src/com/android/build/tests/KernelImageCheck.java b/src/com/android/build/tests/KernelImageCheck.java
index ccd2809..b4d5248 100644
--- a/src/com/android/build/tests/KernelImageCheck.java
+++ b/src/com/android/build/tests/KernelImageCheck.java
@@ -26,7 +26,6 @@
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 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 org.junit.Before;
@@ -42,7 +41,6 @@
 public class KernelImageCheck extends BaseHostJUnit4Test {
 
     private static final String KERNEL_IMAGE_NAME = "vmlinux";
-    private static final String KERNEL_IMAGE_REPO = "common";
     private static final int CMD_TIMEOUT = 1000000;
 
     @Option(
@@ -66,7 +64,8 @@
 
     @Option(
         name = "kernel-abi-file",
-        description = "The file path of kernel ABI file"
+        description = "The file path of kernel ABI file",
+        mandatory = true
     )
     private File mKernelAbiFile = null;
 
@@ -75,22 +74,9 @@
 
     @Before
     public void setUp() throws Exception {
-        if (mKernelImageCheckTool == null || !mKernelImageCheckTool.exists()) {
+        if (!mKernelImageCheckTool.exists()) {
             throw new IOException("Cannot find kernel image tool at: " + mKernelImageCheckTool);
         }
-
-        // If --kernel-abi-file has not been specified, try to find 'abi.xml'
-        // within the downloaded files from the build.
-        if (mKernelAbiFile == null) {
-            mKernelAbiFile = getBuild().getFile("abi.xml");
-        }
-
-        // If there was not any 'abi.xml' and --kernel-abi-file was not set to
-        // point at an external one, throw that.
-        if (mKernelAbiFile == null) {
-            throw new IOException("Cannot find abi.xml within the build results.");
-        }
-
         if (!mKernelAbiFile.exists()) {
             throw new IOException("Cannot find kernel ABI representation at: " + mKernelAbiFile);
         }
@@ -112,37 +98,16 @@
     /** Test that kernel ABI is not different from the given ABI representation */
     @Test
     public void test_stable_abi() throws Exception {
-        // Figure out location of Linux source tree by inspecting vmlinux.
-        String[] cmd = new String[] {"strings", mKernelImageFile.getPath(), "-d"};
-        CommandResult result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
-        assertEquals(CommandStatus.SUCCESS, result.getStatus());
-
-        String vmlinuxStrings = result.getStdout();
-        File vmlinuxStringsFile = FileUtil.createTempFile("vmlinuxStrings", ".txt");
-        FileUtil.writeToFile(vmlinuxStrings, vmlinuxStringsFile);
-
-        cmd = new String[] {"grep", "-m", "1", "init/main.c", vmlinuxStringsFile.getAbsolutePath()};
-        result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
-        assertEquals(CommandStatus.SUCCESS, result.getStatus());
-
-        String repoRootDir = result.getStdout();
-        // Source file absolute path is /repoRootDir/KERNEL_IMAGE_REPO/location-in-linux-tree.
-        repoRootDir = repoRootDir.split("/" + KERNEL_IMAGE_REPO + "/", 2)[0];
-
         // Generate kernel ABI
-        cmd =
+        String[] cmd =
                 new String[] {
                     mKernelImageCheckTool.getAbsolutePath() + "/abidw",
-                    // omit various sources of indeterministic abidw output
-                    "--no-corpus-path",
-                    "--no-comp-dir-path",
-                    // the path containing vmlinux and *.ko
                     "--linux-tree",
                     mKernelImageFile.getParent(),
                     "--out-file",
-                    "abi-new.xml"
+                    "abi-new.out"
                 };
-        result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
+        CommandResult result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
         CLog.i("Result stdout: %s", result.getStdout());
         // TODO: differentiate non-zero exit codes.
         if (result.getExitCode() != 0) {
@@ -151,30 +116,12 @@
         }
         assertEquals(CommandStatus.SUCCESS, result.getStatus());
 
-        // Sanitize abi-new.xml by removing any occurences of the kernel path.
-        cmd =
-                new String[] {
-                    "sed",
-                    "-i",
-                    "s#" + repoRootDir + "/" + KERNEL_IMAGE_REPO + "/##g",
-                    "abi-new.xml"
-                };
-        result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
-        assertEquals(CommandStatus.SUCCESS, result.getStatus());
-
-        cmd = new String[] {"sed", "-i", "s#" + repoRootDir + "/##g", "abi-new.xml"};
-        result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
-        assertEquals(CommandStatus.SUCCESS, result.getStatus());
-
         // Diff kernel ABI with the given ABI file
         cmd =
                 new String[] {
                     mKernelImageCheckTool.getAbsolutePath() + "/abidiff",
-                    "--impacted-interfaces",
-                    "--leaf-changes-only",
-                    "--dump-diff-tree",
-                    mKernelAbiFile.getAbsolutePath(),
-                    "abi-new.xml"
+                    "abi-new.out",
+                    mKernelAbiFile.getAbsolutePath()
                 };
         result = RunUtil.getDefault().runTimedCmd(CMD_TIMEOUT, cmd);
         CLog.i("Result stdout: %s", result.getStdout());
@@ -182,9 +129,6 @@
             CLog.e("Result stderr: %s", result.getStderr());
             CLog.e("Result exit code: %d", result.getExitCode());
         }
-        assertEquals(
-                "Kernel's ABI has changed. See go/kernel-abi-monitoring for details.\n",
-                CommandStatus.SUCCESS,
-                result.getStatus());
+        assertEquals(CommandStatus.SUCCESS, result.getStatus());
     }
 }
diff --git a/src/com/android/framework/tests/PreloadedClassesTest.java b/src/com/android/framework/tests/PreloadedClassesTest.java
new file mode 100644
index 0000000..32c543e
--- /dev/null
+++ b/src/com/android/framework/tests/PreloadedClassesTest.java
@@ -0,0 +1,254 @@
+/*
+ * 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/src/com/android/media/tests/CameraTestBase.java b/src/com/android/media/tests/CameraTestBase.java
index da7fed6..41db51c 100644
--- a/src/com/android/media/tests/CameraTestBase.java
+++ b/src/com/android/media/tests/CameraTestBase.java
@@ -188,7 +188,6 @@
 
         InstrumentationTest instr = new InstrumentationTest();
         instr.setDevice(getDevice());
-        instr.setConfiguration(mConfiguration);
         instr.setPackageName(getTestPackage());
         instr.setRunnerName(getTestRunner());
         instr.setClassName(getTestClass());
diff --git a/src/com/android/monkey/MonkeyBase.java b/src/com/android/monkey/MonkeyBase.java
index 215577b..baf2b91 100644
--- a/src/com/android/monkey/MonkeyBase.java
+++ b/src/com/android/monkey/MonkeyBase.java
@@ -40,6 +40,7 @@
 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;
@@ -68,7 +69,7 @@
 import java.util.concurrent.TimeUnit;
 
 /** Runner for stress tests which use the monkey command. */
-public class MonkeyBase implements IDeviceTest, IRemoteTest {
+public class MonkeyBase implements IDeviceTest, IRemoteTest, IRetriableTest {
 
     public static final String MONKEY_LOG_NAME = "monkey_log";
     public static final String BUGREPORT_NAME = "bugreport";
@@ -230,8 +231,6 @@
                             + "flags and parameters as launched from Launcher. May be repeated")
     private List<String> mLaunchComponents = new ArrayList<>();
 
-    /** @deprecated b/139751666 */
-    @Deprecated
     @Option(name = "retry-on-failure", description = "Retry the test on failure")
     private boolean mRetryOnFailure = false;
 
@@ -704,6 +703,18 @@
         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);
diff --git a/src/com/android/scenario/AppSetup.java b/src/com/android/scenario/AppSetup.java
index 09f1867..1f4eb3c 100644
--- a/src/com/android/scenario/AppSetup.java
+++ b/src/com/android/scenario/AppSetup.java
@@ -41,12 +41,6 @@
     )
     private List<String> mAppsToKillWhenFinished = new ArrayList<>();
 
-    @Option(
-            name = "disable",
-            description = "Set it to true to disable AppSetup test."
-        )
-    private boolean mDisable = false;
-
     static final String DROP_CACHE_COMMAND = "echo 3 > /proc/sys/vm/drop_caches";
     static final String KILL_APP_COMMAND_TEMPLATE = "am force-stop %s";
 
@@ -62,9 +56,6 @@
      */
     @Override
     public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
-        if(mDisable) {
-            return;
-        }
         runTest(listener);
 
         // TODO(harrytczhang@): Switch to a solution based on test rule injection after b/123281375.
diff --git a/src/com/android/tradefed/presubmit/TestMappingsValidation.java b/src/com/android/tradefed/presubmit/TestMappingsValidation.java
index 4c1d1cf..408f136 100644
--- a/src/com/android/tradefed/presubmit/TestMappingsValidation.java
+++ b/src/com/android/tradefed/presubmit/TestMappingsValidation.java
@@ -252,12 +252,17 @@
      * @param name A {@code String} name of the test.
      * @param keywords A {@code Set<String>} keywords of the test.
      * @return true if name exists in module-info.json and matches either "general-tests" or
-     *     "device-tests", or name doesn't exist in module-info.json.
+     *     "device-tests", or name doesn't exist but has keywords attribute set.
      */
     private boolean validateSuiteSetting(String name, Set<String> keywords) throws JSONException {
         if (!moduleInfo.has(name)) {
-            CLog.w("Test Module: %s can't be found in module-info.json. Ignore checking...", name);
-            return true;
+            if (!keywords.isEmpty()) {
+                CLog.d("Test Module: %s can't be found in module-info.json, but it has " +
+                        "keyword setting. Ignore checking...", name);
+                return true;
+            }
+            CLog.w("Test Module: %s can't be found in module-info.json.", name);
+            return false;
         }
         JSONArray compatibilitySuites = moduleInfo.getJSONObject(name).
                 getJSONArray(LOCAL_COMPATIBILITY_SUITES);
diff --git a/tests/.classpath b/tests/.classpath
index f2cba3b..120dbb6 100644
--- a/tests/.classpath
+++ b/tests/.classpath
@@ -12,6 +12,5 @@
 	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/external/mockito/mockito-byte-buddy-agent/linux_glibc_common/combined/mockito-byte-buddy-agent.jar"/>
 	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/external/mockito/mockito-byte-buddy/linux_glibc_common/combined/mockito-byte-buddy.jar"/>
 	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/tools/tradefederation/core/tradefed-protos/linux_glibc_common/combined/tradefed-protos.jar"/>
-	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/external/guava/guava-jre/linux_glibc_common/combined/guava-jre.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tests/Android.bp b/tests/Android.bp
deleted file mode 100644
index 108d346..0000000
--- a/tests/Android.bp
+++ /dev/null
@@ -1,35 +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.
-
-tradefed_java_library_host {
-    name: "tf-contrib-tests",
-
-    // Only compile source java files in this lib.
-    srcs: ["src/**/*.java"],
-
-    //resource_dirs: ["res"],
-
-    javacflags: [
-        "-g",
-        "-Xlint",
-    ],
-
-    libs: [
-        "tradefed",
-        "tradefed-contrib",
-        "easymock",
-        "mockito",
-        "objenesis",
-    ],
-}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index d4a90ba..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,24 +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.
-
-# makefile rules to copy jars to HOST_OUT/tradefed
-# so tradefed.sh can automatically add to classpath
-
-DEST_JAR := $(HOST_OUT)/tradefed/tf-contrib-tests.jar
-BUILT_JAR := $(call intermediates-dir-for,JAVA_LIBRARIES,tf-contrib-tests,HOST)/javalib.jar
-$(DEST_JAR): $(BUILT_JAR)
-	$(copy-file-to-new-target)
-
-# this dependency ensure the above rule will be executed if module is built
-$(HOST_OUT_JAVA_LIBRARIES)/tf-contrib-tests.jar : $(DEST_JAR)
diff --git a/tests/OWNERS b/tests/OWNERS
deleted file mode 100644
index 96b7872..0000000
--- a/tests/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Owners for modifying any build rules related to the contrib folder
-per-file Android.bp = guangzhu@google.com,jdesprez@google.com,tsu@google.com
diff --git a/tests/build/Android.mk b/tests/build/Android.mk
new file mode 100644
index 0000000..89f2bab
--- /dev/null
+++ b/tests/build/Android.mk
@@ -0,0 +1,43 @@
+# 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-contrib-tests
+LOCAL_MODULE_TAGS := optional
+LOCAL_JAVA_LIBRARIES := tradefed tradefed-contrib easymock mockito objenesis
+
+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/tests/build/OWNERS b/tests/build/OWNERS
new file mode 100644
index 0000000..dd703a5
--- /dev/null
+++ b/tests/build/OWNERS
@@ -0,0 +1,4 @@
+# Owners for modifying any build rules related to the contrib folder
+guangzhu@google.com
+jdesprez@google.com
+tsu@google.com
diff --git a/tests/src/com/android/scenario/AppSetupTest.java b/tests/src/com/android/scenario/AppSetupTest.java
index 35870fd..084bb1a 100644
--- a/tests/src/com/android/scenario/AppSetupTest.java
+++ b/tests/src/com/android/scenario/AppSetupTest.java
@@ -86,12 +86,4 @@
         verify(mTestDevice, times(1))
                 .executeShellCommand(eq(String.format(AppSetup.KILL_APP_COMMAND_TEMPLATE, "app2")));
     }
-
-    /** Test setting disable option exits from the run method early.*/
-    @Test
-    public void testDisableOption() throws Exception {
-        mOptionSetter.setOptionValue("disable", String.valueOf(true));
-        mAppSetup.run(mListener);
-        verify(mAppSetup, times(0)).runTest(any());
-    }
 }