diff --git a/tools/tradefed-host/res/config/cts.xml b/tools/tradefed-host/res/config/cts.xml
index a5665be..3f89630 100644
--- a/tools/tradefed-host/res/config/cts.xml
+++ b/tools/tradefed-host/res/config/cts.xml
@@ -20,7 +20,6 @@
     <build_provider class="com.android.cts.tradefed.build.CtsBuildProvider" />
     <device_recovery class="com.android.tradefed.device.WaitDeviceRecovery" />
     <target_preparer class="com.android.cts.tradefed.targetprep.DevicePreconditionPreparer" />
-    <target_preparer class="com.android.cts.tradefed.targetprep.HostPreconditionPreparer" />
     <test class="com.android.cts.tradefed.testtype.CtsTest" />
     <logger class="com.android.tradefed.log.FileLogger" />
     <result_reporter class="com.android.cts.tradefed.result.CtsXmlResultReporter" />
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparer.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparer.java
deleted file mode 100644
index 5a868ce..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparer.java
+++ /dev/null
@@ -1,525 +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.cts.tradefed.targetprep;
-
-import com.android.ddmlib.IDevice;
-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.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.ZipUtil;
-
-import java.awt.Dimension;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.zip.ZipFile;
-
-/**
- * A {@link ITargetPreparer} that performs steps on the host-side to meet the preconditions of CTS.
- * <p/>
- * This class is intended for runs of CTS against a device running a user build.
- * <p/>
- * This class performs checks to verify that the location services are on, WiFi is connected,
- * the device locale is set to 'en-US', and that the device runs a user build. The class also
- * performs automation to ensure that 3rd party app installs are enabled, the 'Stay Awake' setting
- * is turned on, and that the appropriate media files are pushed to the device for the media tests.
- * Additionally, options are provided for automatically connecting to a specific WiFi network.
- */
-@OptionClass(alias="host-precondition-preparer")
-public class HostPreconditionPreparer implements ITargetPreparer {
-
-    /* This option also exists in the DevicePreconditionPreparer */
-    @Option(name = "skip-preconditions",
-            description = "Whether to skip precondition checks and automation")
-    protected boolean mSkipPreconditions = false;
-
-    @Option(name = "wifi-ssid", description = "Name of the WiFi network with which to connect")
-    protected String mWifiSsid = null;
-
-    @Option(name = "wifi-psk", description = "The WPA-PSK associated with option 'wifi-ssid'")
-    protected String mWifiPsk = null;
-
-    @Option(name = "skip-media-download",
-            description = "Whether to skip verifying/downloading media files")
-    protected boolean mSkipMediaDownload = false;
-
-    @Option(name = "local-media-path",
-            description = "Absolute path of the media files directory on the host, containing" +
-            "'bbb_short' and 'bbb_full' directories")
-    protected String mLocalMediaPath = null;
-
-    private static final String LOG_TAG = HostPreconditionPreparer.class.getSimpleName();
-
-    /* Constants found in android.provider.Settings */
-    protected static final String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
-    protected static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
-    protected static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs";
-    protected static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
-    /* Constant from android.os.BatteryManager */
-    private static final int BATTERY_PLUGGED_USB = 2;
-
-    /* Name and expected value of the device's locale property */
-    private static final String LOCALE_PROPERTY_STRING = "ro.product.locale";
-    private static final String US_EN_LOCALE_STRING = "en-US";
-    /* Name and expected value of the device's build type property */
-    private static final String BUILD_TYPE_PROPERTY_STRING = "ro.build.type";
-    private static final String USER_BUILD_STRING = "user";
-
-    /* Logged if the preparer fails to identify the device's maximum video playback resolution */
-    private static final String MAX_PLAYBACK_RES_FAILURE_MSG =
-            "Unable to parse maximum video playback resolution, pushing all media files";
-
-    /*
-     * The URL from which to download the compressed media files
-     * TODO: Find a way to retrieve this programmatically
-     */
-    private static final String MEDIA_URL_STRING =
-            "https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip";
-
-    /*
-     * A default name for the local directory into which media files will be downloaded, if option
-     * "local-media-path" is not provided. This name is intentionally predetermined and final, so
-     * that when running CTS repeatedly, media files downloaded to the host in a previous run of
-     * CTS can be found in this directory, which will live inside the local temp directory.
-     */
-    private static final String MEDIA_FOLDER_NAME = "android-cts-media";
-
-    /* Constants identifying video playback resolutions of the media files to be copied */
-    protected static final int RES_176_144 = 0; // 176x144 resolution
-    protected static final int RES_DEFAULT = 1; // 480x360, the default max playback resolution
-    protected static final int RES_720_480 = 2; // 720x480 resolution
-    protected static final int RES_1280_720 = 3; // 1280x720 resolution
-    protected static final int RES_1920_1080 = 4; // 1920x1080 resolution
-
-    /* Array of Dimensions aligning with and corresponding to the resolution constants above */
-    protected static final Dimension[] resolutions = {
-            new Dimension(176, 144),
-            new Dimension(480, 360),
-            new Dimension(720, 480),
-            new Dimension(1280, 720),
-            new Dimension(1920, 1080)
-    };
-
-    /*********************************************************************************************
-     * HELPER METHODS
-     *********************************************************************************************/
-
-    /* Helper that logs a message with LogLevel.INFO */
-    private static void printInfo(String msg) {
-        LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, msg);
-    }
-
-    /* Helper that logs a message with LogLevel.WARN */
-    private static void printWarning(String msg) {
-        LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, msg);
-    }
-
-    /*
-     * Returns a string representation of the dimension
-     * For dimension of width = 480 and height = 360, the resolution string is "480x360"
-     */
-    protected static String resolutionString(Dimension resolution) {
-        return String.format("%dx%d", resolution.width, resolution.height);
-    }
-
-    /*
-     * Returns the device's absolute path to the directory containing 'short' media files, given
-     * a resolution. The instance of ITestDevice is used to identify the mount point for
-     * external storage.
-     */
-    protected String getDeviceShortDir(ITestDevice device, Dimension resolution) {
-        String mountPoint = device.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        return String.format("%s/test/bbb_short/%s", mountPoint, resolutionString(resolution));
-    }
-
-    /*
-     * Returns the device's absolute path to the directory containing 'full' media files, given
-     * a resolution. The instance of ITestDevice is used to identify the mount point for
-     * external storage.
-     */
-    protected String getDeviceFullDir(ITestDevice device, Dimension resolution) {
-        String mountPoint = device.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
-        return String.format("%s/test/bbb_full/%s", mountPoint, resolutionString(resolution));
-    }
-
-    /*
-     * Loops through the predefined maximum video playback resolutions from largest to smallest,
-     * And returns the greatest resolution that is strictly smaller than the width and height
-     * provided in the arguments.
-     */
-    private Dimension getMaxVideoPlaybackResolution(int width, int height) {
-        for (int resIndex = resolutions.length - 1; resIndex >= RES_DEFAULT; resIndex--) {
-            Dimension resolution = resolutions[resIndex];
-            if (width >= resolution.width && height >= resolution.height) {
-                return resolution;
-            }
-        }
-        return resolutions[RES_DEFAULT];
-    }
-
-    /**
-     * Returns the maximum video playback resolution of the device, in the form of a Dimension
-     * object. This method parses dumpsys output to find resolutions listed under the
-     * 'mBaseDisplayInfo' field. The value of the 'smallest app' field is used as an estimate for
-     * maximum video playback resolution, and is rounded down to the nearest dimension in the
-     * resolutions array.
-     */
-    protected Dimension getMaxVideoPlaybackResolution(ITestDevice device)
-            throws DeviceNotAvailableException{
-        String dumpsysOutput =
-                device.executeShellCommand("dumpsys display | grep mBaseDisplayInfo");
-        Pattern pattern = Pattern.compile("smallest app (\\d+) x (\\d+)");
-        Matcher matcher = pattern.matcher(dumpsysOutput);
-        if(!matcher.find()) {
-            // could not find resolution in dumpsysOutput, return largest max playback resolution
-            // so that preparer copies all media files
-            printInfo(MAX_PLAYBACK_RES_FAILURE_MSG);
-            return resolutions[RES_1920_1080];
-        }
-
-        int first;
-        int second;
-        try {
-            first = Integer.parseInt(matcher.group(1));
-            second = Integer.parseInt(matcher.group(2));
-        } catch (NumberFormatException e) {
-            // match was found, but not an identifiable resolution
-            printInfo(MAX_PLAYBACK_RES_FAILURE_MSG);
-            return resolutions[RES_1920_1080];
-        }
-        // ensure that the larger of the two values found is assigned to 'width'
-        int height = Math.min(first, second);
-        int width = Math.max(first, second);
-        return getMaxVideoPlaybackResolution(width, height);
-    }
-
-    /*
-     * After downloading and unzipping the media files, mLocalMediaPath must be the path to the
-     * directory containing 'bbb_short' and 'bbb_full' directories, as it is defined in its
-     * description as an option.
-     * After extraction, this directory exists one level below the the directory 'mediaFolder'.
-     * If the 'mediaFolder' contains anything other than exactly one subdirectory, a
-     * TargetSetupError is thrown. Otherwise, the mLocalMediaPath variable is set to the path of
-     * this subdirectory.
-     */
-    private void updateLocalMediaPath(File mediaFolder) throws TargetSetupError {
-        String[] subDirs = mediaFolder.list();
-        if (subDirs.length != 1) {
-            throw new TargetSetupError(String.format(
-                    "Unexpected contents in directory %s", mLocalMediaPath));
-        }
-        File newMediaFolder = new File(mediaFolder, subDirs[0]);
-        mLocalMediaPath = newMediaFolder.toString();
-    }
-
-    /*
-     * Copies the media files to the host from predefined url MEDIA_URL_STRING.
-     * The compressed file is downloaded and unzipped into mLocalMediaPath.
-     */
-    private void downloadMediaToHost() throws TargetSetupError {
-
-        URL url;
-        try {
-            url = new URL(MEDIA_URL_STRING);
-        } catch (MalformedURLException e) {
-            throw new TargetSetupError(
-                    String.format("Trouble finding android media files at %s", MEDIA_URL_STRING));
-        }
-
-        File mediaFolder = new File(mLocalMediaPath);
-        File mediaFolderZip = new File(mediaFolder.getAbsolutePath() + ".zip");
-        try {
-
-            mediaFolder.mkdirs();
-            mediaFolderZip.createNewFile();
-
-            URLConnection conn = url.openConnection();
-            InputStream in = conn.getInputStream();
-            BufferedOutputStream out =
-                    new BufferedOutputStream(new FileOutputStream(mediaFolderZip));
-            byte[] buffer = new byte[1024];
-            int count;
-            printInfo("Downloading media files to host");
-            while ((count = in.read(buffer)) >= 0) {
-                out.write(buffer, 0, count);
-            }
-            out.flush();
-            out.close();
-            in.close();
-
-            printInfo("Unzipping media files");
-            ZipUtil.extractZip(new ZipFile(mediaFolderZip), mediaFolder);
-
-        } catch (IOException e) {
-            FileUtil.recursiveDelete(mediaFolder);
-            FileUtil.recursiveDelete(mediaFolderZip);
-            throw new TargetSetupError("Failed to open media files on host");
-        }
-    }
-
-    /**
-     * Pushes directories containing media files to the device for all directories that:
-     * - are not already present on the device
-     * - contain video files of a resolution less than or equal to the device's
-     *       max video playback resolution
-     */
-    protected void copyMediaFiles(ITestDevice device, Dimension mvpr)
-            throws DeviceNotAvailableException {
-
-        int resIndex = RES_176_144;
-        while (resIndex <= RES_1920_1080) {
-            Dimension copiedResolution = resolutions[resIndex];
-            String resString = resolutionString(copiedResolution);
-            if (copiedResolution.width > mvpr.width || copiedResolution.height > mvpr.height) {
-                printInfo(String.format(
-                        "Device cannot support resolutions %s and larger, media copying complete",
-                        resString));
-                return;
-            }
-            String deviceShortFilePath = getDeviceShortDir(device, copiedResolution);
-            String deviceFullFilePath = getDeviceFullDir(device, copiedResolution);
-            if (!device.doesFileExist(deviceShortFilePath) ||
-                    !device.doesFileExist(deviceFullFilePath)) {
-                printInfo(String.format("Copying files of resolution %s to device", resString));
-                String localShortDirName = "bbb_short/" + resString;
-                String localFullDirName = "bbb_full/" + resString;
-                File localShortDir = new File(mLocalMediaPath, localShortDirName);
-                File localFullDir = new File(mLocalMediaPath, localFullDirName);
-                // push short directory of given resolution, if not present on device
-                if(!device.doesFileExist(deviceShortFilePath)) {
-                    device.pushDir(localShortDir, deviceShortFilePath);
-                }
-                // push full directory of given resolution, if not present on device
-                if(!device.doesFileExist(deviceFullFilePath)) {
-                    device.pushDir(localFullDir, deviceFullFilePath);
-                }
-            }
-            resIndex++;
-        }
-    }
-
-    /*
-     * Returns true if all media files of a resolution less than or equal to 'mvpr' exist on the
-     * device, and otherwise returns false.
-     */
-    private boolean mediaFilesExistOnDevice(ITestDevice device, Dimension mvpr)
-            throws DeviceNotAvailableException{
-        int resIndex = RES_176_144;
-        while (resIndex <= RES_1920_1080) {
-            Dimension copiedResolution = resolutions[resIndex];
-            if (copiedResolution.width > mvpr.width || copiedResolution.height > mvpr.height) {
-                break; // we don't need to check for resolutions greater than or equal to this
-            }
-            String deviceShortFilePath = getDeviceShortDir(device, copiedResolution);
-            String deviceFullFilePath = getDeviceFullDir(device, copiedResolution);
-            if (!device.doesFileExist(deviceShortFilePath) ||
-                    !device.doesFileExist(deviceFullFilePath)) {
-                // media files of valid resolution not found on the device, and must be pushed
-                return false;
-            }
-            resIndex++;
-        }
-        return true;
-    }
-
-    /* Static method that returns a directory called 'dirName' in the system's temp directory */
-    private static File createSimpleTempDir(String dirName) throws IOException {
-        // find system's temp directory
-        File throwaway = File.createTempFile(dirName, null);
-        String systemTempDir = throwaway.getParent();
-        // create directory with simple name within temp directory
-        File simpleTempDir = new File(systemTempDir, dirName);
-        // delete file used to find temp directory
-        throwaway.delete();
-        return simpleTempDir;
-    }
-
-    /* Method that creates a local media path, and ensures that the necessary media files live
-     * within that path */
-    private void createLocalMediaPath() throws TargetSetupError {
-        File mediaFolder;
-        try {
-            mediaFolder = createSimpleTempDir(MEDIA_FOLDER_NAME);
-        } catch (IOException e) {
-            throw new TargetSetupError("Unable to create host temp directory for media files");
-        }
-        mLocalMediaPath = mediaFolder.getAbsolutePath();
-        if (!mediaFolder.exists()) {
-            // directory has not been created or filled by previous runs of MediaPreparer
-            downloadMediaToHost(); //download media into mLocalMediaPath
-        }
-        updateLocalMediaPath(mediaFolder);
-    }
-
-    /*********************************************************************************************
-     * PRECONDITION METHODS
-     *********************************************************************************************/
-
-    /**
-     * Allows installations of apps from sources other than the Play Store
-     */
-    protected void enableThirdPartyInstalls(ITestDevice device)
-            throws DeviceNotAvailableException {
-        String shellCmd = String.format("settings put secure %s 1", INSTALL_NON_MARKET_APPS);
-        device.executeShellCommand(shellCmd);
-    }
-
-    /**
-     * Prevents the screen from sleeping while charging via USB
-     */
-    protected void enableStayAwakeSetting(ITestDevice device) throws DeviceNotAvailableException {
-        String shellCmd = String.format("settings put global %s %d",
-                STAY_ON_WHILE_PLUGGED_IN, BATTERY_PLUGGED_USB);
-        device.executeShellCommand(shellCmd);
-    }
-
-    /**
-     * Prevents package verification on apps installed through ADB/ADT/USB
-     */
-    protected void disableAdbAppVerification(ITestDevice device)
-            throws DeviceNotAvailableException {
-        String shellCmd = String.format("settings put global %s 0", PACKAGE_VERIFIER_INCLUDE_ADB);
-        device.executeShellCommand(shellCmd);
-    }
-
-    /**
-     * Prevents the keyguard from re-emerging during the CTS test, which can cause some failures
-     * Note: the shell command run here is not supported on L
-     */
-    protected void disableKeyguard(ITestDevice device) throws DeviceNotAvailableException {
-        device.executeShellCommand("wm disable-keyguard");
-    }
-
-    /**
-     * Throws a TargetSetupError if location services are not enabled by gps or a network
-     */
-    protected void checkLocationServices(ITestDevice device)
-            throws DeviceNotAvailableException, TargetSetupError {
-        String shellCmd = String.format("settings get secure %s", LOCATION_PROVIDERS_ALLOWED);
-        String locationServices = device.executeShellCommand(shellCmd);
-        if (!locationServices.contains("gps") && !locationServices.contains("network")) {
-            // location services are not enabled by gps nor by the network
-            throw new TargetSetupError(
-                    "Location services must be enabled for several CTS test packages");
-        }
-    }
-
-    /**
-     * Prints a warning if the device's locale is something other than US English, as some tests
-     * may pass or fail depending on the 'en-US' locale.
-     */
-    protected void verifyLocale(ITestDevice device) throws DeviceNotAvailableException {
-        String locale = device.getProperty(LOCALE_PROPERTY_STRING);
-        if (!locale.equalsIgnoreCase(US_EN_LOCALE_STRING)) {
-            printWarning(String.format("Expected locale en-US, detected locale \"%s\"", locale));
-        }
-    }
-
-    /**
-     * Prints a warning if the device is not running a user build. This is not allowed for
-     * testing production devices, but should not block testers from running CTS on a userdebug
-     * build.
-     */
-    protected void verifyUserBuild(ITestDevice device) throws DeviceNotAvailableException {
-        String buildType = device.getProperty(BUILD_TYPE_PROPERTY_STRING);
-        if (!buildType.equalsIgnoreCase(USER_BUILD_STRING)) {
-            printWarning(String.format("Expected user build, detected type \"%s\"", buildType));
-        }
-    }
-
-    /**
-     * Throws a TargetSetupError if the device is not connected to a WiFi network. Testers can
-     * optionally supply a 'wifi-ssid' and 'wifi-psk' (in the options above) to attempt connection
-     * to a specific network.
-     */
-    protected void runWifiPrecondition(ITestDevice device)
-            throws TargetSetupError, DeviceNotAvailableException {
-
-        if(!device.connectToWifiNetworkIfNeeded(mWifiSsid, mWifiPsk)) {
-            throw new TargetSetupError("Unable to find or create network connection, some " +
-                    "modules of CTS require an active network connection");
-        }
-
-        if(mWifiSsid == null) {
-            // no connection to create, check for existing connectivity
-            if (!device.checkConnectivity()) {
-                throw new TargetSetupError("Device has no network connection, no ssid provided");
-            }
-        } else {
-            // network provided in options, attempt to create new connection if needed
-            if (!device.connectToWifiNetworkIfNeeded(mWifiSsid, mWifiPsk)) {
-                throw new TargetSetupError("Unable to establish network connection," +
-                        "some CTS packages require an active network connection");
-            }
-        }
-    }
-
-    /**
-     * Checks that media files for the mediastress tests are present on the device, and if not,
-     * pushes them onto the device.
-     */
-    protected void runMediaPrecondition(ITestDevice device)
-            throws TargetSetupError, DeviceNotAvailableException {
-        if (mSkipMediaDownload) {
-            return; // skip this precondition
-        }
-        Dimension mvpr = getMaxVideoPlaybackResolution(device);
-        if (mediaFilesExistOnDevice(device, mvpr)) {
-            return; // media files already found on the device
-        }
-        if (mLocalMediaPath == null) {
-            createLocalMediaPath(); // make new path on host containing media files
-        }
-        printInfo(String.format("Media files located on host at: %s", mLocalMediaPath));
-        copyMediaFiles(device, mvpr);
-    }
-
-    public void setUp(ITestDevice device, IBuildInfo buildInfo)
-            throws TargetSetupError, BuildError, DeviceNotAvailableException {
-        if (mSkipPreconditions) {
-            return; // skipping host-side preconditions
-        }
-
-        /* run each host-side precondition */
-        enableThirdPartyInstalls(device);
-        enableStayAwakeSetting(device);
-        disableAdbAppVerification(device);
-        disableKeyguard(device);
-        checkLocationServices(device);
-        verifyLocale(device);
-        verifyUserBuild(device);
-        runWifiPrecondition(device);
-        runMediaPrecondition(device);
-    }
-
-}
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
index 54a2ea6..29c1324 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
@@ -22,7 +22,6 @@
 import com.android.cts.tradefed.result.TestSummaryXmlTest;
 import com.android.cts.tradefed.result.TestTest;
 import com.android.cts.tradefed.result.TestLogTest;
-import com.android.cts.tradefed.targetprep.HostPreconditionPreparerTest;
 import com.android.cts.tradefed.testtype.Abi;
 import com.android.cts.tradefed.testtype.CtsTestTest;
 import com.android.cts.tradefed.testtype.DeqpTestRunnerTest;
@@ -60,9 +59,6 @@
         addTestSuite(TestTest.class);
         addTestSuite(TestLogTest.class);
 
-        // targetprep package
-        addTestSuite(HostPreconditionPreparerTest.class);
-
         // testtype package
         addTestSuite(CtsTestTest.class);
         addTestSuite(DeqpTestRunnerTest.class);
@@ -73,7 +69,6 @@
         addTestSuite(TestPackageXmlParserTest.class);
         addTestSuite(TestPlanTest.class);
         addTestSuite(WrappedGTestResultParserTest.class);
-
     }
 
     public static Test suite() {
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparerTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparerTest.java
deleted file mode 100644
index 05e743f..0000000
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparerTest.java
+++ /dev/null
@@ -1,190 +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.cts.tradefed.targetprep;
-
-import com.android.ddmlib.IDevice;
-import com.android.tradefed.config.OptionSetter;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.TargetSetupError;
-
-import java.awt.Dimension;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-
-/**
- * Unit tests for {@link HostPreconditionPreparer}.
- */
-public class HostPreconditionPreparerTest extends TestCase {
-
-    private HostPreconditionPreparer mHostPreconditionPreparer;
-    private ITestDevice mMockDevice;
-    private OptionSetter mOptionSetter;
-
-    private final Dimension DEFAULT_DIMENSION =
-            HostPreconditionPreparer.resolutions[HostPreconditionPreparer.RES_DEFAULT];
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mHostPreconditionPreparer = new HostPreconditionPreparer();
-        mMockDevice = EasyMock.createMock(ITestDevice.class);
-        mOptionSetter = new OptionSetter(mHostPreconditionPreparer);
-
-        EasyMock.expect(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).andReturn(
-                "/sdcard").anyTimes();
-    }
-
-    public void testLocationServicesOnGpsNetwork() throws Exception {
-        String shellCmd = String.format(
-                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
-
-        // expect location to be enabled by both gps and network
-        EasyMock.expect(
-                mMockDevice.executeShellCommand(shellCmd)).andReturn("\ngps,network\n").once();
-        EasyMock.replay(mMockDevice);
-        mHostPreconditionPreparer.checkLocationServices(mMockDevice);
-    }
-
-    public void testLocationServicesOnGps() throws Exception {
-        String shellCmd = String.format(
-                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
-
-        // expect location to be enabled by gps only
-        EasyMock.expect(
-                mMockDevice.executeShellCommand(shellCmd)).andReturn("\ngps\n").once();
-        EasyMock.replay(mMockDevice);
-        mHostPreconditionPreparer.checkLocationServices(mMockDevice);
-    }
-
-    public void testLocationServicesOnNetwork() throws Exception {
-        String shellCmd = String.format(
-                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
-
-        // expect location to be enabled by network only
-        EasyMock.expect(
-                mMockDevice.executeShellCommand(shellCmd)).andReturn("\nnetwork\n").once();
-        EasyMock.replay(mMockDevice);
-        mHostPreconditionPreparer.checkLocationServices(mMockDevice);
-    }
-
-    public void testLocationServicesOff() throws Exception {
-        String shellCmd = String.format(
-                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
-
-        // expect location to be disabled
-        EasyMock.expect(
-                mMockDevice.executeShellCommand(shellCmd)).andReturn("\n\n").once();
-        EasyMock.replay(mMockDevice);
-        try {
-            mHostPreconditionPreparer.checkLocationServices(mMockDevice);
-            fail("TargetSetupError expected");
-        } catch (TargetSetupError e) {
-            // Expected
-        }
-    }
-
-    public void testWifiConnected() throws Exception {
-        EasyMock.expect(mMockDevice.checkConnectivity()).andReturn(true).once();
-        EasyMock.replay(mMockDevice);
-        mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
-    }
-
-    public void testWifiDisconnected() throws Exception {
-        EasyMock.expect(mMockDevice.checkConnectivity()).andReturn(false).once();
-        EasyMock.replay(mMockDevice);
-        try {
-            mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
-            fail("TargetSetupError expected");
-        } catch (TargetSetupError e) {
-            // Expected
-        }
-    }
-
-    public void testWifiConnectionSuccessful() throws Exception {
-        EasyMock.expect(
-                mMockDevice.connectToWifiNetwork("wifi-ssid", "wifi-psk")).andReturn(true).once();
-        mOptionSetter.setOptionValue("wifi-ssid", "wifi-ssid");
-        mOptionSetter.setOptionValue("wifi-psk", "wifi-psk");
-        EasyMock.replay(mMockDevice);
-        mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
-    }
-
-    public void testWifiConnectionUnuccessful() throws Exception {
-        EasyMock.expect(
-                mMockDevice.connectToWifiNetwork("wifi-ssid", "wifi-psk")).andReturn(false).once();
-        mOptionSetter.setOptionValue("wifi-ssid", "wifi-ssid");
-        mOptionSetter.setOptionValue("wifi-psk", "wifi-psk");
-        EasyMock.replay(mMockDevice);
-        try {
-            mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
-            fail("TargetSetupError expected");
-        } catch (TargetSetupError e) {
-            // Expected
-        }
-    }
-
-    public void testResolutionString() throws Exception {
-        assertEquals("480x360", mHostPreconditionPreparer.resolutionString(DEFAULT_DIMENSION));
-    }
-
-    public void testGetDeviceDirs() throws Exception {
-        EasyMock.replay(mMockDevice);
-        String shortDir =
-                mHostPreconditionPreparer.getDeviceShortDir(mMockDevice, DEFAULT_DIMENSION);
-        String fullDir =
-                mHostPreconditionPreparer.getDeviceFullDir(mMockDevice, DEFAULT_DIMENSION);
-        assertEquals(shortDir, "/sdcard/test/bbb_short/480x360");
-        assertEquals(fullDir, "/sdcard/test/bbb_full/480x360");
-    }
-
-    public void testGetMaxVideoPlaybackResolutionFound() throws Exception {
-        // set "smallest app" field to DEFAULT_DIMENSION
-        String mockDumpsysOutput = "mBaseDisplayInfo=DisplayInfo{\"Built-in Screen\", uniqueId " +
-                "\"local:0\", app 1440 x 2560, real 1440 x 2560, largest app 1440 x 2560, " +
-                "smallest app 360 x 480, mode 1, defaultMode 1, modes [{id=1, width=1440, " +
-                "height=2560, fps=60.0}], rotation 0, density 560 (494.27 x 492.606) dpi, " +
-                "layerStack 0, appVsyncOff 2500000, presDeadline 17666667, type BUILT_IN, state " +
-                "ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}\n";
-        EasyMock.expect(mMockDevice.executeShellCommand(
-                "dumpsys display | grep mBaseDisplayInfo")).andReturn(mockDumpsysOutput).once();
-        EasyMock.replay(mMockDevice);
-        Dimension result = mHostPreconditionPreparer.getMaxVideoPlaybackResolution(mMockDevice);
-        assertEquals(result, DEFAULT_DIMENSION);
-    }
-
-    public void testGetMaxVideoPlaybackResolutionNotFound() throws Exception {
-        String mockDumpsysOutput = "incorrect output";
-        EasyMock.expect(mMockDevice.executeShellCommand(
-                "dumpsys display | grep mBaseDisplayInfo")).andReturn(mockDumpsysOutput).once();
-        EasyMock.replay(mMockDevice);
-        Dimension result = mHostPreconditionPreparer.getMaxVideoPlaybackResolution(mMockDevice);
-        Dimension maxRes =
-                HostPreconditionPreparer.resolutions[HostPreconditionPreparer.RES_1920_1080];
-        assertEquals(result,maxRes);
-    }
-
-    public void testSkipMediaDownload() throws Exception {
-        mOptionSetter.setOptionValue("skip-media-download", "true");
-        EasyMock.replay();
-        mHostPreconditionPreparer.runMediaPrecondition(mMockDevice);
-    }
-
-}
