Mark ab/6881855 as merged

Bug: 172690556
Change-Id: I492622ab5bb2632ca4b0d52f190b1a09a63aa791
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
deleted file mode 100644
index 1204431..0000000
--- a/PREUPLOAD.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-[Builtin Hooks]
-clang_format = true
-
-[Builtin Hooks Options]
-clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp,java
-
-[Hook Scripts]
-test_framework_unittests = ${REPO_ROOT}/test/framework/script/run-unittest.sh
diff --git a/README.md b/README.md
deleted file mode 100644
index 60cfc7e..0000000
--- a/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Android Vendor Test Suite (VTS) Lab
-
-VTS Lab is an open source test serving infrastructure that can be used
-to streamline VTS and CTS-on-GSI (General System Image) tests.
diff --git a/build/Android.mk b/build/Android.mk
deleted file mode 100644
index 82b1883..0000000
--- a/build/Android.mk
+++ /dev/null
@@ -1,152 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-VTF_MK := $(LOCAL_PATH)/vtf.mk
-VTF_PACKAGE_MK := test/vts/tools/build/tasks/framework/vtf_package.mk
-
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/tasks/list/vtslab_apk_package_list.mk
-include $(LOCAL_PATH)/tasks/list/vtslab_bin_package_list.mk
-include $(LOCAL_PATH)/tasks/list/vtslab_lib_package_list.mk
-
-VTSLAB_OUT_ROOT := $(HOST_OUT)/vtslab
-VTSLAB_TESTCASES_OUT := $(VTSLAB_OUT_ROOT)/android-vtslab/testcases
-VTSLAB_TOOLS_OUT := $(VTSLAB_OUT_ROOT)/android-vtslab/tools
-VTSLAB_BIN_LIB_OUT := $(VTSLAB_OUT_ROOT)/android-vtslab/
-VTSLAB_TIMESTAMP := $(shell git -C $(LOCAL_PATH) log -s -n 1 --format="%cd" \
-  --date=format:"%Y%m%d_%H%M%S" 2>/dev/null)
-VTSLAB_SHORTHASH := $(shell git -C $(LOCAL_PATH) rev-parse --short HEAD 2>/dev/null)
-VTSLAB_VERSION := $(VTSLAB_TIMESTAMP):$(VTSLAB_SHORTHASH)
-
-# Packaging rule for android-vtslab.zip
-test_suite_name := vtslab
-test_suite_readme := test/framework/README.md
-
-include $(LOCAL_PATH)/package.mk
-include $(LOCAL_PATH)/utils/vtslab_package_utils.mk
-
-# TODO: instead of an alias, deprecate vtslab build target
-.PHONY: lab
-lab: vtslab
-.PHONY: vtslab
-vtslab: $(compatibility_zip)
-$(call dist-for-goals, vtslab, $(compatibility_zip))
-
-# Packaging rule for android-vtslab.zip's testcases dir (DATA subdir).
-vtslab_apk_modules := \
-  $(vtslab_apk_packages) \
-
-vtslab_apk_modules_copy_pairs := \
-  $(call target-native-copy-pairs,$(vtslab_apk_modules),$(VTSLAB_TESTCASES_OUT))
-
-# host controller files.
-host_hc_files := \
-  $(call find-files-in-subdirs,test/framework/harnesses/host_controller,"*.py" -and -type f,.) \
-
-host_hc_copy_pairs := \
-  $(foreach f,$(host_hc_files),\
-      test/framework/harnesses/host_controller/$(f):$(VTSLAB_TESTCASES_OUT)/host_controller/$(f))
-
-# gsi security patch scripts.
-host_hc_gsispl_files := \
-  $(call find-files-in-subdirs,test/framework/harnesses/host_controller/gsi,"*.sh" -and -type f,.) \
-
-host_hc_gsispl_copy_pairs := \
-  $(foreach f,$(host_hc_gsispl_files),\
-    test/framework/harnesses/host_controller/gsi/$(f):$(VTSLAB_BIN_LIB_OUT)/bin/$(f))
-
-# host controller scripts.
-host_hc_extra_copy_pairs := \
-  test/framework/tools/host_controller/run:$(VTSLAB_TOOLS_OUT)/run \
-  test/framework/tools/host_controller/make_screen:$(VTSLAB_TOOLS_OUT)/make_screen \
-  test/vts/script/diagnose.py:$(VTSLAB_BIN_LIB_OUT)/bin/diagnose.py \
-  test/vts/script/pip_requirements.txt:$(VTSLAB_BIN_LIB_OUT)/bin/pip_requirements.txt \
-  test/vts/script/setup.sh:$(VTSLAB_BIN_LIB_OUT)/bin/setup.sh \
-
-host_acloud_files := \
-  $(call find-files-in-subdirs,tools/acloud,"*.py" -and -type f,.) \
-  $(call find-files-in-subdirs,tools/acloud,"*.config" -and -type f,.)
-
-host_acloud_copy_pairs := \
-  $(foreach f,$(host_acloud_files),\
-    tools/acloud/$(f):$(VTSLAB_TESTCASES_OUT)/acloud/$(f))
-
-host_vti_dashboard_proto_files := \
-  $(call find-files-in-subdirs,test/vti/dashboard/proto,"*.py" -and -type f,.)
-
-host_vti_test_serving_proto_files := \
-  $(call find-files-in-subdirs,test/vti/test_serving/proto,"*.py" -and -type f,.)
-
-host_vti_copy_pairs := \
-  $(foreach f,$(host_vti_test_serving_proto_files),\
-    test/vti/test_serving/proto/$(f):$(VTSLAB_TESTCASES_OUT)/vti/test_serving/proto/$(f)) \
-  $(foreach f,$(host_vti_dashboard_proto_files),\
-    test/vti/dashboard/proto/$(f):$(VTSLAB_TESTCASES_OUT)/vti/dashboard/proto/$(f)) \
-  test/vti/dashboard/__init__.py:$(VTSLAB_TESTCASES_OUT)/vti/dashboard/__init__.py \
-  test/vti/test_serving/__init__.py:$(VTSLAB_TESTCASES_OUT)/vti/test_serving/__init__.py \
-
-$(VTSLAB_TESTCASES_OUT)/vti/__init__.py:
-	@mkdir -p $(VTSLAB_TESTCASES_OUT)/vti
-	@touch $(VTSLAB_TESTCASES_OUT)/vti/__init__.py
-
-host_vti_extra_copy_pairs := \
-  $(VTSLAB_TESTCASES_OUT)/vti/__init__.py \
-
-vts_host_python_files := \
-  $(call find-files-in-subdirs,test/vts,"*.py" -and -type f,.)
-
-vts_host_python_copy_pairs := \
-  $(foreach f,$(vts_host_python_files),\
-    test/vts/$(f):$(VTSLAB_TESTCASES_OUT)/vts/$(f))
-
-# Packaging rule for host-controller's dependencies
-host_hc_bin_lib := \
-  $(vtslab_bin_packages) \
-  $(vtslab_lib_packages) \
-
-host_hc_bin_lib_copy_pairs := \
-  $(call host-native-copy-pairs,$(host_hc_bin_lib),$(VTSLAB_BIN_LIB_OUT))
-
-vtslab_copy_pairs := \
-  $(call copy-many-files,$(vtslab_apk_modules_copy_pairs)) \
-  $(call copy-many-files,$(host_hc_copy_pairs)) \
-  $(call copy-many-files,$(host_hc_gsispl_copy_pairs)) \
-  $(call copy-many-files,$(host_hc_extra_copy_pairs)) \
-  $(call copy-many-files,$(host_acloud_copy_pairs)) \
-  $(call copy-many-files,$(host_vti_copy_pairs)) \
-  $(call copy-many-files,$(vts_host_python_copy_pairs)) \
-  $(call copy-many-files,$(host_hc_bin_lib_copy_pairs)) \
-  $(host_vti_extra_copy_pairs) \
-
-$(compatibility_zip): $(vtslab_copy_pairs) $(VTSLAB_TESTCASES_OUT)/version.txt
-
-$(VTSLAB_TESTCASES_OUT)/version.txt:
-	@rm -f $@
-	@echo $(VTSLAB_VERSION) > $@
-
-# for VTF (Vendor Test Framework)
-VTF_OUT_ROOT := $(HOST_OUT)/vtf
-VTF_TESTCASES_OUT := $(VTF_OUT_ROOT)/android-vtf/testcases
-VTF_TOOLS_OUT := $(VTF_OUT_ROOT)/android-vtf/tools
-VTF_EXTRA_SCRIPTS := vtf
-
-include $(VTF_PACKAGE_MK)
-include $(VTF_MK)
-
-# clears local vars
-VTF_MK :=
-VTF_PACKAGE_MK :=
diff --git a/build/package.mk b/build/package.mk
deleted file mode 100644
index d04b159..0000000
--- a/build/package.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Package up a compatibility test suite in a zip file.
-#
-# Input variables:
-#   test_suite_name: the name of this test suite eg. cts
-#   test_suite_readme: the path to a README file for this test suite
-#   test_suite_prebuilt_tools: the set of prebuilt tools to be included directly
-#                         in the 'tools' subdirectory of the test suite.
-#   test_suite_tools: the set of tools for this test suite
-#
-# Output variables:
-#   compatibility_zip: the path to the output zip file.
-
-out_dir := $(HOST_OUT)/$(test_suite_name)/android-$(test_suite_name)
-test_artifacts := $(COMPATIBILITY.$(test_suite_name).FILES)
-test_tools := $(test_suite_readme)
-test_tools += $(test_suite_tools)
-
-compatibility_zip := $(out_dir).zip
-$(compatibility_zip): PRIVATE_NAME := android-$(test_suite_name)
-$(compatibility_zip): PRIVATE_OUT_DIR := $(out_dir)
-$(compatibility_zip): PRIVATE_TOOLS := $(test_tools) $(test_suite_prebuilt_tools)
-$(compatibility_zip): PRIVATE_SUITE_NAME := $(test_suite_name)
-$(compatibility_zip): $(test_artifacts) $(test_tools) $(test_suite_prebuilt_tools) $(SOONG_ZIP) | $(ADB) $(ACP)
-# Make dir structure
-	$(hide) mkdir -p $(PRIVATE_OUT_DIR)/tools $(PRIVATE_OUT_DIR)/testcases
-# Copy tools
-	$(hide) $(ACP) -fp $(PRIVATE_TOOLS) $(PRIVATE_OUT_DIR)/tools
-	$(hide) find $(dir $@)/$(PRIVATE_NAME) | sort >$@.list
-	$(hide) $(SOONG_ZIP) -d -o $@ -C $(dir $@) -l $@.list
-
-# Reset all input variables
-test_suite_name :=
-test_suite_dynamic_config :=
-test_suite_readme :=
-test_suite_prebuilt_tools :=
-test_suite_tools :=
diff --git a/build/tasks/list/vtslab_apk_package_list.mk b/build/tasks/list/vtslab_apk_package_list.mk
deleted file mode 100644
index fc842aa..0000000
--- a/build/tasks/list/vtslab_apk_package_list.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-vtslab_apk_packages := \
-    WifiUtil \
diff --git a/build/tasks/list/vtslab_bin_package_list.mk b/build/tasks/list/vtslab_bin_package_list.mk
deleted file mode 100644
index 664c7fe..0000000
--- a/build/tasks/list/vtslab_bin_package_list.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-vtslab_bin_packages := \
-    aapt \
-    adb \
-    fastboot \
-    img2simg \
-    mke2fs \
-    mkuserimg_mke2fs \
-    simg2img \
diff --git a/build/tasks/list/vtslab_lib_package_list.mk b/build/tasks/list/vtslab_lib_package_list.mk
deleted file mode 100644
index 5f4740c..0000000
--- a/build/tasks/list/vtslab_lib_package_list.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-vtslab_lib_packages := \
-    libc++ \
diff --git a/build/utils/vtslab_package_utils.mk b/build/utils/vtslab_package_utils.mk
deleted file mode 100644
index e4ea608..0000000
--- a/build/utils/vtslab_package_utils.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# $(1): List of target native files to copy.
-# $(2): Copy destination directory.
-# Evaluates to a list of ":"-separated pairs src:dst.
-define target-native-copy-pairs
-$(foreach m,$(1),\
-  $(eval _built_files := $(strip $(ALL_MODULES.$(m).BUILT_INSTALLED)\
-  $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).BUILT_INSTALLED)))\
-  $(foreach i, $(_built_files),\
-    $(eval bui_ins := $(subst :,$(space),$(i)))\
-    $(eval ins := $(word 2,$(bui_ins)))\
-    $(if $(filter $(TARGET_OUT_ROOT)/%,$(ins)),\
-      $(eval bui := $(word 1,$(bui_ins)))\
-      $(eval my_copy_dest := $(patsubst data/%,DATA/%,\
-                               $(patsubst system/%,DATA/%,\
-                                   $(patsubst $(PRODUCT_OUT)/%,%,$(ins)))))\
-      $(bui):$(2)/$(my_copy_dest))))
-endef
-
-# $(1): List of host native files to copy.
-# $(2): Copy destination directory.
-# Evaluates to a list of ":"-separated pairs src:dst.
-define host-native-copy-pairs
-$(foreach m,$(1),\
-  $(eval _built_files := $(strip $(ALL_MODULES.$(m).BUILT_INSTALLED)\
-  $(ALL_MODULES.$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX).BUILT_INSTALLED)))\
-  $(foreach i, $(_built_files),\
-    $(eval bui_ins := $(subst :,$(space),$(i)))\
-    $(eval ins := $(word 2,$(bui_ins)))\
-    $(if $(filter $(HOST_OUT)/% $(HOST_CROSS_OUT)/%,$(ins)),\
-      $(eval bui := $(word 1,$(bui_ins)))\
-      $(eval my_copy_dest := $(patsubst $(HOST_OUT)/%,%,\
-                               $(patsubst $(HOST_CROSS_OUT)/%,%,$(ins))))\
-      $(bui):$(2)/$(my_copy_dest))))
-endef
diff --git a/build/vtf.mk b/build/vtf.mk
deleted file mode 100644
index 069b6b2..0000000
--- a/build/vtf.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Build rules for VTF (Vendor Test Framework).
-LOCAL_PATH := $(call my-dir)
-
-vtf_tradefed_modules := \
-  compatibility-common-util-tests \
-  compatibility-host-util \
-  compatibility-host-util-tests \
-  compatibility-tradefed-tests \
-  host-libprotobuf-java-full \
-  loganalysis \
-  tradefed \
-  vts-tradefed \
-  vts10-tradefed \
-  vts10-tradefed-tests \
-
-vtf_tradefed_copy_pairs := \
-  $(foreach f,$(vtf_tradefed_modules),\
-    $(HOST_OUT)/framework/$(f).jar:$(VTF_TOOLS_OUT)/$(f).jar)
-
-vtf_tradefed_additional_deps_copy_pairs := \
-  test/vts/tools/vts-tradefed/etc/vts10-tradefed:$(VTF_TOOLS_OUT)/vts10-tradefed
-
-vtf_tradefed_additional_deps_copy_pairs += \
-  $(foreach f,$(VTF_COPY_VTF_BINARY),\
-    test/vts/tools/vts-tradefed/etc/$(f):$(VTF_TESTCASES_OUT)/$(f))
-
-vtf_package_copy_pairs := \
-  $(call copy-many-files,$(vtf_tradefed_copy_pairs)) \
-  $(call copy-many-files,$(vtf_tradefed_additional_deps_copy_pairs)) \
-
-.PHONY: vtf
-vtf: $(vtf_copy_pairs) $(vtf_package_copy_pairs)
diff --git a/harnesses/Android.bp b/harnesses/Android.bp
deleted file mode 100644
index 93e059b..0000000
--- a/harnesses/Android.bp
+++ /dev/null
@@ -1,20 +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.
-//
-
-java_import_host {
-    name: "tradefed-cts-prebuilt",
-    jars: ["cts-tradefed/tradefed-cts-prebuilt.jar"],
-}
diff --git a/harnesses/README.md b/harnesses/README.md
deleted file mode 100644
index a8c5fde..0000000
--- a/harnesses/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-To build a new CTS TF prebuilt binary
-
-`$ lunch aosp_arm64`
-`$ make cts-tradefed -j
-
-To release to TEST
-`$ cp out/host/linux-x86/testcases/cts-tradefed/cts-tradefed.jar test/framework/harnesses/cts-tradefed/tradefed-cts-prebuilt-staging.jar`
-
-To release to PROD
-`$ cp test/framework/harnesses/cts-tradefed/tradefed-cts-prebuilt-staging.jar test/framework/harnesses/cts-tradefed/tradefed-cts-prebuilt.jar`
-
-To test a test suite which uses that prebuilt binary
-
-`$ make vts -j32`
-
diff --git a/harnesses/cts-tradefed/tradefed-cts-prebuilt.jar b/harnesses/cts-tradefed/tradefed-cts-prebuilt.jar
deleted file mode 100644
index 7e728bf..0000000
--- a/harnesses/cts-tradefed/tradefed-cts-prebuilt.jar
+++ /dev/null
Binary files differ
diff --git a/harnesses/host_controller/__init__.py b/harnesses/host_controller/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/acloud/__init__.py b/harnesses/host_controller/acloud/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/acloud/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/acloud/acloud_client.py b/harnesses/host_controller/acloud/acloud_client.py
deleted file mode 100644
index 5bcd85e..0000000
--- a/harnesses/host_controller/acloud/acloud_client.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import getpass
-import json
-import logging
-import os
-from os.path import expanduser
-import re
-import shutil
-import tempfile
-
-from acloud.public import acloud_main
-from host_controller.acloud import acloud_config
-from vts.utils.python.common import cmd_utils
-
-DEFAULT_BRANCH = 'git_master'
-DEFAULT_BUILD_TARGET = 'gce_x86_phone-userdebug_fastbuild3c_linux'
-
-#TODO(yuexima): add full support to multiple instances per host
-
-
-class ACloudClient(object):
-    '''Helper class to manage access to the acloud module.'''
-
-    def __init__(self):
-        tmpdir_base = os.path.join(os.getcwd(), "tmp")
-        if not os.path.exists(tmpdir_base):
-            os.mkdir(tmpdir_base)
-        self._tmpdir = tempfile.mkdtemp(dir=tmpdir_base)
-
-    def __del__(self):
-        """Deletes the temp dir if still set."""
-        if self._tmpdir:
-            shutil.rmtree(self._tmp_dirpath)
-            self._tmpdir = None
-
-    def GetCreateCmd(self,
-                     build_id,
-                     branch=None,
-                     build_target=None,
-                     num=1):
-        '''Get acould create command with given build id.
-
-        Args:
-            build_id: string, build_id.
-            branch: string, build branch
-            build_target: string, build target
-            num: int, number of instances to build
-
-        Returns:
-            string, acloud create command.
-        '''
-        if not branch:
-            branch = DEFAULT_BRANCH
-
-        if not build_target:
-            build_target = DEFAULT_BUILD_TARGET
-
-        #TODO latest build id (in the caller class of this function).
-        #TODO use unique log and tmp file location
-        cmd = ('create '
-            '--branch {branch} '
-            '--build_target {build_target} '
-            '--build_id {build_id} '
-            '--config_file {config_file} '
-            '--report_file {report_file} '
-            '--log_file {log_file} '
-            '--email {email} '
-            '--num {num}').format(
-            branch = branch,
-            build_target = build_target,
-            build_id = build_id,
-            config_file = os.path.join(self._tmpdir, 'acloud.config'),
-            report_file = os.path.join(self._tmpdir, 'acloud_report.json'),
-            log_file = os.path.join(self._tmpdir, 'acloud.log'),
-            #TODO use host email address
-            email = getpass.getuser() + '@google.com',
-            num = num
-        )
-        return cmd
-
-    def GetDeleteCmd(self, instance_names):
-        '''Get Acould delete command with given instance names.
-
-        Args:
-            instance_names: list of string, instance names.
-
-        Returns:
-            string, acloud create command.
-        '''
-        cmd = ('delete '
-            '--instance_names {instance_names} '
-            '--config_file {config_file} '
-            '--report_file {report_file} '
-            '--log_file {log_file} '
-            '--email {email}').format(
-            instance_names = ' '.join(instance_names),
-            config_file = os.path.join(self._tmpdir, 'acloud.config'),
-            report_file = os.path.join(self._tmpdir, 'acloud_report.json'),
-            log_file = os.path.join(self._tmpdir, 'acloud.log'),
-            email = getpass.getuser() + '@google.com'
-        )
-        return cmd
-
-    def CreateInstance(self, build_id):
-        '''Create Acould instance with given build id.
-
-        Args:
-            build_id: string, build_id.
-        '''
-        cmd = self.GetCreateCmd(build_id)
-        acloud_main.main(cmd.split())
-
-        report_file = os.path.join(self._tmpdir, 'acloud_report.json')
-        with open(report_file, 'r') as f:
-            report = json.load(f)
-
-        return report['status']=='SUCCESS'
-
-    def PrepareConfig(self, file_path):
-        '''Prepare acloud Acloud config file.
-
-        Args:
-            file_path: string, path to acloud config file.
-        '''
-        config = acloud_config.ACloudConfig()
-        config.Load(file_path)
-        if not config.Validate():
-            logging.error('Failed to prepare acloud config.')
-            return
-
-        config.Save(os.path.join(self._tmpdir, 'acloud.config'))
-
-    def GetInstanceIP(self):
-        '''Get an Acloud instance ip'''
-        #TODO support ip addresses when num > 1 (json parser)
-        report_file = os.path.join(self._tmpdir, 'acloud_report.json')
-
-        with open(report_file, 'r') as f:
-            report = json.load(f)
-
-        return report['data']['devices'][0]['ip']
-
-    def GetInstanceName(self):
-        '''Get an Acloud instance name'''
-        report_file = os.path.join(self._tmpdir, 'acloud_report.json')
-
-        with open(report_file, 'r') as f:
-            report = json.load(f)
-
-        return report['data']['devices'][0]['instance_name']
-
-    def ConnectInstanceToAdb(self, ip=None):
-        '''Connect an Acloud instance to adb
-
-        Args:
-            ip: string, ip address
-        '''
-        if not ip:
-            ip = self.GetInstanceIP()
-
-        cmds = [('ssh -i ~/.ssh/acloud_rsa -o UserKnownHostsFile=/dev/null '
-                 '-o StrictHostKeyChecking=no -L 40000:127.0.0.1:6444 -L '
-                 '30000:127.0.0.1:5555 -N -f -l root %s') % ip,
-                 'adb connect 127.0.0.1:30000']
-
-        for cmd in cmds:
-            print cmd
-            results = cmd_utils.ExecuteShellCommand(cmd)
-            if any(results[cmd_utils.EXIT_CODE]):
-                logging.error("Fail to execute command: %s\nResult:%s" % (cmd,
-                                                                        results))
-                return
-            print 'Acloud instance created and connected to local port 127.0.0.1:30000'
-
-    def DeleteInstance(self, instance_names=None):
-        '''Delete an Acloud instance
-
-        Args:
-            instance_names: string, instance name
-        '''
-        cmd = self.GetDeleteCmd(instance_names)
-        acloud_main.main(cmd.split())
-
-        report_file = os.path.join(self._tmpdir, 'acloud_report.json')
-        with open(report_file, 'r') as f:
-            report = json.load(f)
-
-        return report['status']=='SUCCESS'
diff --git a/harnesses/host_controller/acloud/acloud_config.py b/harnesses/host_controller/acloud/acloud_config.py
deleted file mode 100644
index 0ceab47..0000000
--- a/harnesses/host_controller/acloud/acloud_config.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-
-
-# In fact, all fields are required. The fields listed below are used
-# to check whether the config class has been properly initialized before
-# generating config file
-REQUIRED_KEYS = [
-    'ssh_public_key_path',
-    'ssh_private_key_path',
-    'project',
-    'client_id',
-    'client_secret'
-    ]
-
-
-class ACloudConfig(object):
-    '''For ACloud configuration file operations.
-
-    Attributes:
-        configs: dict of string:string, configuration keys and values.
-        has_error: bool, whether error occurred.
-    '''
-    configs = {}
-    has_error = False
-
-    def Validate(self):
-        '''Validate config class.
-
-        Check whether required fields has been set.
-        Check whether loading configuration file is success.
-
-        Returns:
-            bool, True if validated.
-        '''
-        for key in REQUIRED_KEYS:
-            if key not in self.configs:
-                logging.error('Required key %s is not '
-                              'set for acloud config' % key)
-                return False
-
-        return not self.has_error
-
-    def Load(self, file_path):
-        '''Load configs from a file.
-
-        Args:
-            file_path: string, path to config file.
-        '''
-        if not os.path.isfile(file_path):
-            logging.error('Failed to read acloud config file %s' % file_path)
-            self.has_error = True
-            return
-
-        separator = ': "'
-
-        with open(file_path, 'r') as f:
-            for line in f:
-                line = line.strip()
-                # Skip empty line and comments
-                if not line or line.startswith('#'):
-                    continue
-
-                idx = line.find(separator)
-
-                if idx < 1 or not line.endswith('"'):
-                    logging.error('Error parsing line %s from '
-                                  'acloud config file %s' % (line, file_path))
-                    self.has_error = True
-                    return
-
-                key = line[:idx]
-                val = line[len(separator) + idx : -1]
-
-                self.configs[key] = val
-
-    def Save(self, file_path):
-        '''Save config to a file.
-
-        Args:
-            file_path: string, path to config file.
-        '''
-        separator = ':'
-
-        with open(file_path, 'w') as f:
-            for key in self.configs:
-                f.write(key + separator + '"%s"' % self.configs[key])
\ No newline at end of file
diff --git a/harnesses/host_controller/build/README.md b/harnesses/host_controller/build/README.md
deleted file mode 100644
index f97f372..0000000
--- a/harnesses/host_controller/build/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# To set up client_secrets.json (once only)
-
-* Go to https://console.cloud.google.com/projectselector/apis/credentials/consent
- and create a new project if needed.
-* Once on the consent screen, set the product name to anything and save.
-* Click "Create credentials" and select "OAuth client ID"
-* Under "Application type", select "Other". Click "Create".
-* Click the download button for the client you just created,
- and save the resulting file at client_secrets.json
-
-# Running unit tests
-    python build_provider_pab_test.py
\ No newline at end of file
diff --git a/harnesses/host_controller/build/__init__.py b/harnesses/host_controller/build/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/build/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/build/build_flasher.py b/harnesses/host_controller/build/build_flasher.py
deleted file mode 100644
index a920d93..0000000
--- a/harnesses/host_controller/build/build_flasher.py
+++ /dev/null
@@ -1,364 +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.
-#
-"""Class to flash build artifacts onto devices"""
-
-import hashlib
-import logging
-import os
-import resource
-import sys
-import tempfile
-import time
-
-from host_controller import common
-from vts.utils.python.common import cmd_utils
-from vts.utils.python.controllers import android_device
-
-
-class BuildFlasher(object):
-    """Client that manages build flashing.
-
-    Attributes:
-        device: AndroidDevice, the device associated with the client.
-    """
-
-    def __init__(self, serial="", customflasher_path=""):
-        """Initialize the client.
-
-        If serial not provided, find single device connected. Error if
-        zero or > 1 devices connected.
-
-        Args:
-            serial: optional string, serial number for the device.
-            customflasher_path: optional string, set device to use specified
-                                binary to flash a device
-        """
-        if serial != "":
-            self.device = android_device.AndroidDevice(
-                serial, device_callback_port=-1)
-        else:
-            serials = android_device.list_adb_devices()
-            if len(serials) == 0:
-                serials = android_device.list_fastboot_devices()
-                if len(serials) == 0:
-                    raise android_device.AndroidDeviceError(
-                        "ADB and fastboot could not find any target devices.")
-            if len(serials) > 1:
-                logging.info("ADB or fastboot found more than one device: %s",
-                             serials)
-            self.device = android_device.AndroidDevice(
-                serials[0], device_callback_port=-1)
-            if customflasher_path:
-                self.device.SetCustomFlasherPath(customflasher_path)
-
-    def SetSerial(self, serial):
-        """Sets device serial.
-
-        Args:
-            serial: string, a device serial.
-
-        Returns:
-            True if successful; False otherwise.
-        """
-        if not serial:
-            logging.error("no serial is given to BuildFlasher.SetSerial.")
-            return False
-
-        self.device = android_device.AndroidDevice(
-            serial, device_callback_port=-1)
-        return True
-
-    def FlashGSI(self,
-                 system_img,
-                 vbmeta_img=None,
-                 skip_check=False,
-                 skip_vbmeta=False):
-        """Flash the Generic System Image to the device.
-
-        Args:
-            system_img: string, path to GSI
-            vbmeta_img: string, optional, path to vbmeta image for new devices
-            skip_check: boolean, set True to skip adb-based checks when
-                        the DUT is already running its bootloader.
-            skip_vbmeta: bool, whether to skip flashing the vbmeta.img or not.
-                         If the device has the vbmeta slot then flash vbmeta.img
-                         even if the skip_vbmeta is set to True.
-        """
-        if not os.path.exists(system_img):
-            raise ValueError("Couldn't find system image at %s" % system_img)
-        if not skip_check:
-            self.device.adb.wait_for_device()
-            if not self.device.isBootloaderMode:
-                self.device.log.info(self.device.adb.reboot_bootloader())
-        if vbmeta_img is not None:
-            if skip_vbmeta == False or self.device.hasVbmetaSlot:
-                self.device.log.info(
-                    self.device.fastboot.flash('vbmeta', vbmeta_img))
-        self.device.log.info(self.device.fastboot.erase('system'))
-        self.device.log.info(self.device.fastboot.flash('system', system_img))
-        self.device.log.info(self.device.fastboot.erase('metadata'))
-        self.device.log.info(self.device.fastboot._w())
-        self.device.log.info(self.device.fastboot.reboot())
-
-    def Flashall(self, directory):
-        """Flash all images in a directory to the device using flashall.
-
-        Generally the directory is the result of unzipping the .zip from AB.
-        Args:
-            directory: string, path to directory containing images
-        """
-        # fastboot flashall looks for imgs in $ANDROID_PRODUCT_OUT
-        os.environ['ANDROID_PRODUCT_OUT'] = directory
-        self.device.adb.wait_for_device()
-        if not self.device.isBootloaderMode:
-            self.device.log.info(self.device.adb.reboot_bootloader())
-        self.device.log.info(self.device.fastboot.flashall())
-
-    def Flash(self, device_images, skip_vbmeta=False):
-        """Flash the Generic System Image to the device.
-
-        Args:
-            device_images: dict, where the key is partition name and value is
-                           image file path.
-            skip_vbmeta: bool, whether to skip flashing the vbmeta.img or not.
-
-        Returns:
-            True if succesful; False otherwise
-        """
-        if not device_images:
-            logging.warn("Flash skipped because no device image is given.")
-            return False
-
-        if not self.device.isBootloaderMode:
-            self.device.adb.wait_for_device()
-            logging.info("rebooting to bootloader")
-            self.device.log.info(self.device.adb.reboot_bootloader())
-
-        logging.info("checking to flash bootloader.img and radio.img")
-        for partition in ["bootloader", "radio"]:
-            if partition in device_images:
-                image_path = device_images[partition]
-                self.device.log.info("fastboot flash %s %s", partition,
-                                     image_path)
-                self.device.log.info(
-                    self.device.fastboot.flash(partition, image_path))
-                self.device.log.info("fastboot reboot_bootloader")
-                self.device.log.info(self.device.fastboot.reboot_bootloader())
-
-        logging.info("starting to flash vendor and other images...")
-        full_zipfile = False
-        if common.FULL_ZIPFILE in device_images:
-            logging.info("fastboot update %s --skip-reboot",
-                         (device_images[common.FULL_ZIPFILE]))
-            self.device.log.info(
-                self.device.fastboot.update(device_images[common.FULL_ZIPFILE],
-                                            "--skip-reboot"))
-            full_zipfile = True
-
-        for partition, image_path in device_images.iteritems():
-            if partition in (common.FULL_ZIPFILE, common.FULL_ZIPFILE_DIR,
-                             "system", "vbmeta", "bootloader", "radio",
-                             "metadata", "userdata"):
-                continue
-            if full_zipfile and partition in ("vendor", "boot"):
-                logging.info("%s skipped because full zipfile was updated.",
-                             partition)
-                continue
-            if not image_path:
-                self.device.log.warning("%s image is empty", partition)
-                continue
-            self.device.log.info("fastboot flash %s %s", partition, image_path)
-            self.device.log.info(
-                self.device.fastboot.flash(partition, image_path))
-
-        logging.info("starting to flash system and other images...")
-        if "system" in device_images and device_images["system"]:
-            system_img = device_images["system"]
-            vbmeta_img = device_images["vbmeta"] if (
-                "vbmeta" in device_images
-                and device_images["vbmeta"]) else None
-            self.FlashGSI(
-                system_img,
-                vbmeta_img,
-                skip_check=True,
-                skip_vbmeta=skip_vbmeta)
-        else:
-            self.device.log.info(self.device.fastboot.reboot())
-        return True
-
-    def FlashImage(self, device_images, image_partition=None, reboot=False):
-        """Flash specified image(s) to the device.
-
-        Args:
-            device_images: dict, where the key is partition name and value is
-                           image file path.
-            image_partition: string, set to flash only an image in a specified
-                             partition.
-            reboot: boolean, true to reboot the device.
-
-        Returns:
-            True if successful, False otherwise
-        """
-        if not device_images:
-            logging.warn("Flash skipped because no device image is given.")
-            return False
-
-        if not self.device.isBootloaderMode:
-            self.device.adb.wait_for_device()
-            self.device.log.info(self.device.adb.reboot_bootloader())
-
-        for partition, image_path in device_images.iteritems():
-            if image_partition and image_partition != partition:
-                continue
-            if partition.endswith(".img"):
-                partition = partition[:-4]
-            self.device.log.info(
-                self.device.fastboot.flash(partition, image_path))
-        if reboot:
-            self.device.log.info(self.device.fastboot.reboot())
-        return True
-
-    def WaitForDevice(self, timeout_secs=600):
-        """Waits for the device to boot completely.
-
-        Args:
-            timeout_secs: integer, the maximum timeout value for this
-                          operation (unit: seconds).
-
-        Returns:
-            True if device is booted successfully; False otherwise.
-        """
-        return self.device.waitForBootCompletion(timeout=timeout_secs)
-
-    def FlashUsingCustomBinary(self,
-                               device_images,
-                               reboot_mode,
-                               flasher_args,
-                               timeout_secs_for_reboot=900):
-        """Flash the customized image to the device.
-
-        Args:
-            device_images: dict, where the key is partition name and value is
-                           image file path.
-            reboot_mode: string, decides which mode device will reboot into.
-                         ("bootloader"/"download").
-            flasher_args: list of strings, arguments that will be passed to the
-                          flash binary.
-            timeout_secs_for_reboot: integer, the maximum timeout value for
-                                     reboot to flash-able mode(unit: seconds).
-
-        Returns:
-            True if successful; False otherwise.
-        """
-        if not device_images:
-            logging.warn("Flash skipped because no device image is given.")
-            return False
-
-        if not flasher_args:
-            logging.error("No arguments.")
-            return False
-
-        if not self.device.isBootloaderMode:
-            self.device.adb.wait_for_device()
-            logging.info("rebooting to %s mode", reboot_mode)
-            self.device.log.info(self.device.adb.reboot(reboot_mode))
-
-        start = time.time()
-        while not self.device.customflasher._l():
-            if time.time() - start >= timeout_secs_for_reboot:
-                logging.error(
-                    "Timeout while waiting for %s mode boot completion.",
-                    reboot_mode)
-                return False
-            time.sleep(1)
-
-        flasher_output = self.device.customflasher.ExecCustomFlasherCmd(
-            flasher_args[0],
-            " ".join(flasher_args[1:] + [device_images["img"]]))
-        self.device.log.info(flasher_output)
-
-        return True
-
-    def RepackageArtifacts(self, device_images, repackage_form):
-        """Repackage artifacts into a given format.
-
-        Once repackaged, device_images becomes
-        {"img": "path_to_repackaged_image"}
-
-        Args:
-            device_images: dict, where the key is partition name and value is
-                           image file path.
-            repackage_form: string, format to repackage.
-
-        Returns:
-            True if succesful; False otherwise.
-        """
-        if not device_images:
-            logging.warn("Repackage skipped because no device image is given.")
-            return False
-
-        if repackage_form == "tar.md5":
-            tmp_file_name = next(tempfile._get_candidate_names()) + ".tar"
-            tmp_dir_path = os.path.dirname(
-                device_images[device_images.keys()[0]])
-            for img in device_images:
-                if os.path.dirname(device_images[img]) != tmp_dir_path:
-                    os.rename(device_images[img],
-                              os.path.join(tmp_dir_path, img))
-                    device_images[img] = os.path.join(tmp_dir_path, img)
-
-            current_dir = os.getcwd()
-            os.chdir(tmp_dir_path)
-
-            if sys.platform == "linux2":
-                tar_cmd = "tar -cf %s %s" % (tmp_file_name, ' '.join(
-                    (device_images.keys())))
-            else:
-                logging.error("Unsupported OS for the given repackage form.")
-                return False
-            logging.info(tar_cmd)
-            std_out, std_err, err_code = cmd_utils.ExecuteOneShellCommand(
-                tar_cmd)
-            if err_code:
-                logging.error(std_err)
-                return False
-
-            hash_md5 = hashlib.md5()
-            try:
-                with open(tmp_file_name, "rb") as file:
-                    data_chunk = 0
-                    chunk_size = resource.getpagesize()
-                    while data_chunk != b'':
-                        data_chunk = file.read(chunk_size)
-                        hash_md5.update(data_chunk)
-                    hash_ret = hash_md5.hexdigest()
-                with open(tmp_file_name, "a") as file:
-                    file.write("%s  %s" % (hash_ret, tmp_file_name))
-            except IOError as e:
-                logging.error(e.strerror)
-                return False
-
-            device_images.clear()
-            device_images["img"] = os.path.join(tmp_dir_path, tmp_file_name)
-
-            os.chdir(current_dir)
-        else:
-            logging.error(
-                "Please specify correct repackage form: --repackage=%s",
-                repackage_form)
-            return False
-
-        return True
diff --git a/harnesses/host_controller/build/build_flasher_test.py b/harnesses/host_controller/build/build_flasher_test.py
deleted file mode 100644
index 21e81b3..0000000
--- a/harnesses/host_controller/build/build_flasher_test.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import sys
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller.build import build_flasher
-
-
-class BuildFlasherTest(unittest.TestCase):
-    """Tests for Build Flasher"""
-
-    @mock.patch(
-        "host_controller.build.build_flasher.android_device")
-    @mock.patch("host_controller.build.build_flasher.os")
-    def testFlashGSIBadPath(self, mock_os, mock_class):
-        flasher = build_flasher.BuildFlasher("thisismyserial")
-        mock_os.path.exists.return_value = False
-        with self.assertRaises(ValueError) as cm:
-            flasher.FlashGSI("notexists.img")
-        self.assertEqual("Couldn't find system image at notexists.img",
-                         str(cm.exception))
-
-    @mock.patch(
-        "host_controller.build.build_flasher.android_device")
-    @mock.patch("host_controller.build.build_flasher.os")
-    def testFlashGSISystemOnly(self, mock_os, mock_class):
-        mock_device = mock.Mock()
-        mock_class.AndroidDevice.return_value = mock_device
-        flasher = build_flasher.BuildFlasher("thisismyserial")
-        mock_os.path.exists.return_value = True
-        flasher.FlashGSI("exists.img")
-        mock_device.fastboot.erase.assert_any_call('system')
-        mock_device.fastboot.flash.assert_any_call('system', 'exists.img')
-        mock_device.fastboot.erase.assert_any_call('metadata')
-
-    @mock.patch(
-        "host_controller.build.build_flasher.android_device")
-    def testFlashall(self, mock_class):
-        mock_device = mock.Mock()
-        mock_class.AndroidDevice.return_value = mock_device
-        flasher = build_flasher.BuildFlasher("thisismyserial")
-        flasher.Flashall("path/to/dir")
-        mock_device.fastboot.flashall.assert_called_with()
-
-    @mock.patch(
-        "host_controller.build.build_flasher.android_device")
-    def testEmptySerial(self, mock_class):
-        mock_class.list_adb_devices.return_value = ['oneserial']
-        flasher = build_flasher.BuildFlasher(serial="")
-        mock_class.AndroidDevice.assert_called_with(
-            "oneserial", device_callback_port=-1)
-
-    @mock.patch(
-        "host_controller.build.build_flasher.android_device")
-    def testFlashUsingCustomBinary(self, mock_class):
-        """Test for FlashUsingCustomBinary().
-
-            Tests if the method passes right args to customflasher
-            and the execution path of the method.
-        """
-        mock_device = mock.Mock()
-        mock_class.AndroidDevice.return_value = mock_device
-        flasher = build_flasher.BuildFlasher("mySerial", "myCustomBinary")
-
-        mock_device.isBootloaderMode = False
-        device_images = {"img": "my/image/path"}
-        flasher.FlashUsingCustomBinary(device_images, "reboottowhatever",
-                                       ["myarg"])
-        mock_device.adb.reboot.assert_called_with("reboottowhatever")
-        mock_device.customflasher.ExecCustomFlasherCmd.assert_called_with(
-            "myarg", "my/image/path")
-
-        mock_device.reset_mock()
-        mock_device.isBootloaderMode = True
-        device_images["img"] = "my/other/image/path"
-        flasher.FlashUsingCustomBinary(device_images, "reboottowhatever",
-                                       ["myarg"])
-        mock_device.adb.reboot.assert_not_called()
-        mock_device.customflasher.ExecCustomFlasherCmd.assert_called_with(
-            "myarg", "my/other/image/path")
-
-    @mock.patch("host_controller.build.build_flasher.android_device")
-    @mock.patch("host_controller.build.build_flasher.logging")
-    @mock.patch("host_controller.build.build_flasher.cmd_utils")
-    @mock.patch("host_controller.build.build_flasher.os")
-    @mock.patch("host_controller.build.build_flasher.open",
-                new_callable=mock.mock_open)
-    def testRepackageArtifacts(self, mock_open, mock_os, mock_cmd_utils,
-                               mock_logger, mock_class):
-        """Test for RepackageArtifacts().
-
-            Tests if the method executes in correct path regarding
-            given arguments.
-        """
-        mock_device = mock.Mock()
-        mock_class.AndroidDevice.return_value = mock_device
-        flasher = build_flasher.BuildFlasher("serial")
-        device_images = {
-            "system.img": "/my/tmp/path/system.img",
-            "vendor.img": "/my/tmp/path/vendor.img"
-        }
-        mock_cmd_utils.ExecuteOneShellCommand.return_value = "", "", 0
-        ret = flasher.RepackageArtifacts(device_images, "tar.md5")
-        self.assertEqual(ret, True)
-        self.assertIsNotNone(device_images["img"])
-
-        ret = flasher.RepackageArtifacts(device_images, "incorrect")
-        self.assertFalse(ret)
-        mock_logger.error.assert_called_with(
-            "Please specify correct repackage form: --repackage=%s" ,"incorrect")
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/build/build_info.py b/harnesses/host_controller/build/build_info.py
deleted file mode 100644
index 6be9e95..0000000
--- a/harnesses/host_controller/build/build_info.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import collections
-import logging
-import os
-import shutil
-
-
-class BuildInfo(dict):
-    """dict class for fetched device imgs, test suites, etc."""
-
-    def __init__(self):
-        super(BuildInfo, self).__init__()
-
-    def __setitem__(self, key, value):
-        """__setitem__ for BuildInfo dict.
-
-        Remove pre-fetched file which has the same use in HC
-        if the old one has different file name from the new one.
-
-        Args:
-            key: string, key for the path to the fetched file.
-            value: string, path to the newly fetched file.
-        """
-        if key in self and value != self[key]:
-            logging.info("Removing pre-fetched item: %s", self[key])
-            try:
-                if os.path.isfile(self[key]):
-                    os.remove(self[key])
-                elif os.path.isdir(self[key]):
-                    shutil.rmtree(self[key])
-                else:
-                    logging.error("%s is not found", self[key])
-            except OSError as e:
-                logging.error("ERROR: error on file remove %s", e)
-
-        super(BuildInfo, self).__setitem__(key, value)
-
-    def update(self, other=None, **kwargs):
-        """Overrides update() in order to call BuildInfo.__setitem__().
-
-        Args:
-            other: dict or iterable of key/value pairs. Update self
-                   using this argument
-            **kwargs: The optional attributes.
-        """
-        if other is not None:
-            for k, v in other.items() if isinstance(
-                    other, collections.Mapping) else other:
-                self[k] = v
-        for k, v in kwargs.items():
-            self[k] = v
-
-        dict_keys = self.keys()
-        for key in dict_keys:
-            if not os.path.exists(self[key]):
-                logging.info(
-                    "Removing path info %s from build info", self.pop(key))
diff --git a/harnesses/host_controller/build/build_provider.py b/harnesses/host_controller/build/build_provider.py
deleted file mode 100644
index 17ba0bd..0000000
--- a/harnesses/host_controller/build/build_provider.py
+++ /dev/null
@@ -1,323 +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.
-#
-
-import logging
-import os
-import re
-import shutil
-import tempfile
-import zipfile
-
-from host_controller import common
-from vts.runners.host import utils
-
-
-class BuildProvider(object):
-    """The base class for build provider.
-
-    Attributes:
-        _IMAGE_FILE_EXTENSIONS: a list of strings which are common image file
-                                extensions.
-        _BASIC_IMAGE_FILE_NAMES: a list of strings which are the image names in
-                                 an artifact zip.
-        _CONFIG_FILE_EXTENSION: string, the config file extension.
-        _additional_files: a dict containing additionally fetched files that
-                           custom features may need. The key is the path
-                           relative to temporary directory and the value is the
-                           full path.
-        _configs: dict where the key is config type and value is the config file
-                  path.
-        _device_images: dict where the key is image file name and value is the
-                        path.
-        _test_suites: dict where the key is test suite type and value is the
-                      test suite package file path.
-        _host_controller_package: dict where the key is a host controller
-                                  package and the value is the path
-                                  to a package file.
-        _tmp_dirpath: string, the temp dir path created to keep artifacts.
-        _last_fetched_artifact_type: string, stores the type of the last
-                                     artifact fetched.
-    """
-    _CONFIG_FILE_EXTENSION = ".zip"
-    _IMAGE_FILE_EXTENSIONS = [".img", ".bin"]
-    _BASIC_IMAGE_FILE_NAMES = ["boot.img", "system.img", "vendor.img"]
-
-    def __init__(self):
-        self._additional_files = {}
-        self._device_images = {}
-        self._test_suites = {}
-        self._host_controller_package = {}
-        self._configs = {}
-        self._last_fetched_artifact_type = None
-        tempdir_base = os.path.join(os.getcwd(), "tmp")
-        if not os.path.exists(tempdir_base):
-            os.mkdir(tempdir_base)
-        self._tmp_dirpath = tempfile.mkdtemp(dir=tempdir_base)
-
-    def __del__(self):
-        """Deletes the temp dir if still set."""
-        if self._tmp_dirpath:
-            shutil.rmtree(self._tmp_dirpath)
-            self._tmp_dirpath = None
-
-    @property
-    def tmp_dirpath(self):
-        return self._tmp_dirpath
-
-    def CreateNewTmpDir(self):
-        return tempfile.mkdtemp(dir=self._tmp_dirpath)
-
-    def SetDeviceImage(self, name, path):
-        """Sets device image `path` for the specified `name`."""
-        self._device_images[name] = path
-        self._last_fetched_artifact_type = common._ARTIFACT_TYPE_DEVICE
-
-    def _IsFullDeviceImage(self, namelist):
-        """Returns true if given namelist list has all common device images."""
-        for image_file in self._BASIC_IMAGE_FILE_NAMES:
-            if image_file not in namelist:
-                return False
-        return True
-
-    def _IsImageFile(self, file_path):
-        """Returns whether a file is an image.
-
-        Args:
-            file_path: string, the file path.
-
-        Returns:
-            boolean, whether the file is an image.
-        """
-        return any(file_path.endswith(ext)
-                   for ext in self._IMAGE_FILE_EXTENSIONS)
-
-    def SetDeviceImageZip(self, path, full_device_images=False):
-        """Sets device image(s) using files in a given zip file.
-
-        It extracts image files inside the given zip file and selects
-        known Android image files.
-
-        Args:
-            path: string, the path to a zip file.
-        """
-        dest_path = path + ".dir"
-        fetch_type = None
-        with zipfile.ZipFile(path, 'r') as zip_ref:
-            if full_device_images or self._IsFullDeviceImage(zip_ref.namelist()):
-                self.SetDeviceImage(common.FULL_ZIPFILE, path)
-                dir_key = common.FULL_ZIPFILE_DIR
-                fetch_type = common._ARTIFACT_TYPE_DEVICE
-            else:
-                self.SetDeviceImage("gsi-zipfile", path)
-                dir_key = common.GSI_ZIPFILE_DIR  # "gsi-zipfile-dir"
-                fetch_type = common._ARTIFACT_TYPE_GSI
-            if os.path.exists(dest_path):
-                shutil.rmtree(dest_path)
-                logging.info("%s %s deleted", dir_key, dest_path)
-            zip_ref.extractall(dest_path)
-            self.SetFetchedDirectory(dest_path)
-            self.SetDeviceImage(dir_key, dest_path)
-
-        self._last_fetched_artifact_type = fetch_type
-
-    def GetDeviceImage(self, name=None):
-        """Returns device image info."""
-        if name is None:
-            return self._device_images
-        return self._device_images[name]
-
-    def RemoveDeviceImage(self, name):
-        """Removes certain device image info.
-
-        Args:
-            name: string, the name of the device image file
-                  that needs to be removed.
-        """
-        if name in self._device_images:
-            self._device_images.pop(name)
-
-    def SetTestSuitePackage(self, test_suite, path):
-        """Sets test suite package `path` for the specified `type`.
-
-        Args:
-            test_suite: string, test suite type such as 'vts' or 'cts', etc.
-            path: string, the path of a file. if a file is a zip file,
-                  it's unziped and its main binary is set.
-        """
-        if re.match("[vcgs]ts", test_suite):
-            suite_name = "android-%s" % test_suite
-            tradefed_name = "%s-tradefed" % test_suite
-            dest_path = os.path.join(self.tmp_dirpath, suite_name)
-            if os.path.exists(dest_path):
-                shutil.rmtree(dest_path)
-                logging.info("test suite %s deleted", dest_path)
-            with zipfile.ZipFile(path, 'r') as zip_ref:
-                zip_ref.extractall(dest_path)
-                bin_path = os.path.join(dest_path, suite_name,
-                                        "tools", tradefed_name)
-                os.chmod(bin_path, 0766)
-                path = bin_path
-        else:
-            logging.info("unsupported zip file %s", path)
-        self._test_suites[test_suite] = path
-        self._last_fetched_artifact_type = common._ARTIFACT_TYPE_TEST_SUITE
-
-    def GetTestSuitePackage(self, type=None):
-        """Returns test suite package info."""
-        if type is None:
-            return self._test_suites
-        return self._test_suites[type]
-
-    def SetHostControllerPackage(self, package_type, path):
-        """Sets host controller package `path` for the specified `type`.
-
-        Args:
-            package_type: string, host controller type such as 'vtslab'.
-            path: string, the path of a package file.
-        """
-        self._host_controller_package[package_type] = path
-        self._last_fetched_artifact_type = common._ARTIFACT_TYPE_INFRA
-
-    def GetHostControllerPackage(self, package_type=None):
-        """Returns host controller package info.
-
-        Args:
-            package_type: string, key value to self._host_controller_package
-                          dict.
-
-        Returns:
-            the whole dict if package_type is None, otherwise a string which is
-            the path to the fetched host controller package.
-        """
-        if package_type is None:
-            return self._host_controller_package
-        return self._host_controller_package[package_type]
-
-    def SetConfigPackage(self, config_type, path):
-        """Sets test suite package `path` for the specified `type`.
-
-        All valid config files have .zip extension.
-
-        Args:
-            config_type: string, config type such as 'prod' or 'test'.
-            path: string, the path of a config file.
-        """
-        if path.endswith(self._CONFIG_FILE_EXTENSION):
-            dest_path = os.path.join(
-                self.tmp_dirpath, os.path.basename(path) + ".dir")
-            with zipfile.ZipFile(path, 'r') as zip_ref:
-                zip_ref.extractall(dest_path)
-                path = dest_path
-        else:
-            logging.info("unsupported config package file %s", path)
-        self._configs[config_type] = path
-        self._last_fetched_artifact_type = common._ARTIFACT_TYPE_INFRA
-
-    def GetConfigPackage(self, config_type=None):
-        """Returns config package info."""
-        if config_type is None:
-            return self._configs
-        return self._configs[config_type]
-
-    def SetAdditionalFile(self, rel_path, full_path):
-        """Sets the key and value of additionally fetched files.
-
-        Args:
-            rel_path: the file path relative to temporary directory.
-            abs_path: the file path that this process can access.
-        """
-        self._additional_files[rel_path] = full_path
-        self._last_fetched_artifact_type = common._ARTIFACT_TYPE_INFRA
-
-    def GetAdditionalFile(self, rel_path=None):
-        """Returns the paths to fetched files."""
-        if rel_path is None:
-            return self._additional_files
-        return self._additional_files[rel_path]
-
-    def SetFetchedDirectory(self,
-                            dir_path,
-                            root_path=None,
-                            full_device_images=False):
-        """Adds every file in a directory to one of the dictionaries.
-
-        This method follows symlink to file, but skips symlink to directory.
-
-        Args:
-            dir_path: string, the directory to find files in.
-            root_path: string, the temporary directory that dir_path is in.
-                       The default value is dir_path.
-        """
-        for dir_name, file_name in utils.iterate_files(dir_path):
-            full_path = os.path.join(dir_name, file_name)
-            self.SetFetchedFile(full_path, (root_path
-                                            if root_path else dir_path),
-                                full_device_images)
-
-    def SetFetchedFile(self,
-                       file_path,
-                       root_dir=None,
-                       full_device_images=False,
-                       set_suite_as=None):
-        """Adds a file to one of the dictionaries.
-
-        Args:
-            file_path: string, the path to the file.
-            root_dir: string, the temporary directory that file_path is in.
-                      The default value is file_path if file_path is a
-                      directory. Otherwise, the default value is file_path's
-                      parent directory.
-            set_suite_as: string, the test suite name to use for the given
-                          artifact. Used when the file name does not follow
-                          the standard "android-*ts.zip" file name pattern.
-        """
-        file_name = os.path.basename(file_path)
-        if os.path.isdir(file_path):
-            self.SetFetchedDirectory(file_path, root_dir, full_device_images)
-        elif self._IsImageFile(file_path):
-            self.SetDeviceImage(file_name, file_path)
-        elif re.match("android-[vcgs]ts.zip", file_name):
-            test_suite = (file_name.split("-")[-1]).split(".")[0]
-            self.SetTestSuitePackage(test_suite, file_path)
-        elif file_name == "android-vtslab.zip":
-            self.SetHostControllerPackage("vtslab", file_path)
-        elif file_name.startswith("vti-global-config"):
-            self.SetConfigPackage(
-                "prod" if "prod" in file_name else "test", file_path)
-        elif set_suite_as:
-            self.SetTestSuitePackage(set_suite_as, file_path)
-        elif file_path.endswith(".zip"):
-            self.SetDeviceImageZip(file_path, full_device_images)
-        else:
-            rel_path = (os.path.relpath(file_path, root_dir) if root_dir else
-                        os.path.basename(file_path))
-            self.SetAdditionalFile(rel_path, file_path)
-
-    def PrintDeviceImageInfo(self):
-        """Prints device image info."""
-        logging.info(self.GetDeviceImage())
-
-    def PrintGetTestSuitePackageInfo(self):
-        """Prints test suite package info."""
-        logging.info(self.GetTestSuitePackage())
-
-    def GetFetchedArtifactType(self):
-        """Gets the most recently fetched artifact type.
-
-        Returns:
-            string, type of the artifact.
-        """
-        return self._last_fetched_artifact_type
diff --git a/harnesses/host_controller/build/build_provider_ab.py b/harnesses/host_controller/build/build_provider_ab.py
deleted file mode 100644
index 3debdb4..0000000
--- a/harnesses/host_controller/build/build_provider_ab.py
+++ /dev/null
@@ -1,94 +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.
-#
-
-import logging
-import os
-
-from host_controller.build import build_provider
-from vts.utils.python.build.api import artifact_fetcher
-
-
-class BuildProviderAB(build_provider.BuildProvider):
-    """A build provider for Android Build (AB)."""
-
-    def __init__(self):
-        super(BuildProviderAB, self).__init__()
-        if 'run_ab_key' in os.environ:
-            logging.info(
-                "For AB, use the key at %s", os.environ['run_ab_key'])
-            self._artifact_fetcher = artifact_fetcher.AndroidBuildClient(
-                os.environ['run_ab_key'])
-        else:
-            self._artifact_fetcher = None
-
-    def GetLatestBuildId(self, branch, target):
-        """Get the latest build id.
-
-        Args:
-            branch: string, android branch to pull resource from.
-            target: string, build target name.
-
-        Returns:
-            string, latest build id. None if _artifact_fetcher is not initialized.
-        """
-        if not self._artifact_fetcher:
-            return None
-
-        recent_build_ids = self._artifact_fetcher.ListBuildIds(
-            branch, target)
-
-        return recent_build_ids[0]
-
-    def Fetch(self,
-              branch,
-              target,
-              artifact_name,
-              build_id="latest",
-              full_device_images=False):
-        """Fetches Android device artifact file(s) from Android Build.
-
-        Args:
-            branch: string, android branch to pull resource from.
-            target: string, build target name.
-            artifact_name: string, file name.
-            build_id: string, ID of the build or latest.
-
-        Returns:
-            a dict containing the device image info.
-            a dict containing the test suite package info.
-            a dict containing the artifact info.
-        """
-        fetch_info = {}
-        fetch_info["build_id"] = None
-
-        if not self._artifact_fetcher:
-            return self.GetDeviceImage(), self.GetTestSuitePackage(), fetch_info
-
-        if build_id == "latest":
-            build_id = self.GetLatestBuildId(branch, target)
-        fetch_info["build_id"] = build_id
-
-        if "{build_id}" in artifact_name:
-            artifact_name = artifact_name.replace("{build_id}", build_id)
-
-        dest_filepath = os.path.join(self.tmp_dirpath, artifact_name)
-        self._artifact_fetcher.DownloadArtifactToFile(
-            branch, target, build_id, artifact_name,
-            dest_filepath=dest_filepath)
-
-        self.SetFetchedFile(dest_filepath, full_device_images)
-
-        return self.GetDeviceImage(), self.GetTestSuitePackage(), fetch_info
diff --git a/harnesses/host_controller/build/build_provider_gcs.py b/harnesses/host_controller/build/build_provider_gcs.py
deleted file mode 100644
index 0dc8f5a..0000000
--- a/harnesses/host_controller/build/build_provider_gcs.py
+++ /dev/null
@@ -1,113 +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.
-#
-
-import logging
-import os
-import re
-import zipfile
-
-from host_controller.build import build_provider
-from host_controller.utils.gcp import gcs_utils
-from vts.utils.python.common import cmd_utils
-
-_GCLOUD_AUTH_ENV_KEY = "run_gcs_key"
-
-
-class BuildProviderGCS(build_provider.BuildProvider):
-    """A build provider for GCS (Google Cloud Storage)."""
-
-    def __init__(self):
-        super(BuildProviderGCS, self).__init__()
-        if _GCLOUD_AUTH_ENV_KEY in os.environ:
-            gcloud_path = BuildProviderGCS.GetGcloudPath()
-            if gcloud_path is not None:
-                auth_cmd = "%s auth activate-service-account --key-file=%s" % (
-                    gcloud_path, os.environ[_GCLOUD_AUTH_ENV_KEY])
-                _, stderr, ret_code = cmd_utils.ExecuteOneShellCommand(
-                    auth_cmd)
-                if ret_code == 0:
-                    logging.info(stderr)
-                else:
-                    logging.error(stderr)
-
-    @staticmethod
-    def GetGcloudPath():
-        """Returns the gcloud file path if found; None otherwise."""
-        sh_stdout, _, ret_code = cmd_utils.ExecuteOneShellCommand(
-            "which gcloud")
-        if ret_code == 0:
-            return sh_stdout.strip()
-        else:
-            logging.error("`gcloud` doesn't exist on the host; "
-                          "please install Google Cloud SDK before retrying.")
-            return None
-
-    def Fetch(self, path, full_device_images=False, set_suite_as=None):
-        """Fetches Android device artifact file(s) from GCS.
-
-        Args:
-            path: string, the path of a directory which keeps artifacts.
-            set_suite_as: string, the test suite name to use for the given
-                          artifact. Used when the file name does not follow
-                          the standard "android-*ts.zip" file name pattern.
-
-        Returns:
-            a dict containing the device image info.
-            a dict containing the test suite package info.
-            a dict containing the info about custom tool files.
-        """
-        if not path.startswith("gs://"):
-            path = "gs://" + re.sub("^/*", "", path)
-        path = re.sub("/*$", "", path)
-        gsutil_path = gcs_utils.GetGsutilPath()
-        if gsutil_path:
-            temp_dir_path = self.CreateNewTmpDir()
-            # IsGcsFile returns False if path is directory or doesn't exist.
-            # cp command returns non-zero if path doesn't exist.
-            if not gcs_utils.IsGcsFile(gsutil_path, path):
-                dest_path = temp_dir_path
-                if "latest.zip" in path:
-                    gsutil_ls_path = re.sub("latest.zip", "*.zip", path)
-                    lines_gsutil_ls = gcs_utils.List(gsutil_path, gsutil_ls_path)
-                    if lines_gsutil_ls:
-                        lines_gsutil_ls.sort()
-                        path = lines_gsutil_ls[-1]
-                        copy_command = "%s cp %s %s" % (gsutil_path, path,
-                                                        temp_dir_path)
-                    else:
-                        logging.error(
-                            "There is no file(s) that matches the URL %s.",
-                            path)
-                        return (self.GetDeviceImage(),
-                                self.GetTestSuitePackage(),
-                                self.GetAdditionalFile())
-                else:
-                    copy_command = "%s cp -r %s/* %s" % (gsutil_path, path,
-                                                         temp_dir_path)
-            else:
-                dest_path = os.path.join(temp_dir_path, os.path.basename(path))
-                copy_command = "%s cp %s %s" % (gsutil_path, path,
-                                                temp_dir_path)
-
-            _, _, ret_code = cmd_utils.ExecuteOneShellCommand(copy_command)
-            if ret_code == 0:
-                self.SetFetchedFile(dest_path, temp_dir_path,
-                                    full_device_images, set_suite_as)
-            else:
-                logging.error("Error in copy file from GCS (code %s).",
-                              ret_code)
-        return (self.GetDeviceImage(), self.GetTestSuitePackage(),
-                self.GetAdditionalFile())
diff --git a/harnesses/host_controller/build/build_provider_local_fs.py b/harnesses/host_controller/build/build_provider_local_fs.py
deleted file mode 100644
index afcf429..0000000
--- a/harnesses/host_controller/build/build_provider_local_fs.py
+++ /dev/null
@@ -1,40 +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.
-#
-
-from host_controller.build import build_provider
-
-
-class BuildProviderLocalFS(build_provider.BuildProvider):
-    """A build provider for local file system (fs)."""
-
-    def __init__(self):
-        super(BuildProviderLocalFS, self).__init__()
-
-    def Fetch(self, path, full_device_images=False):
-        """Fetches Android device artifact file(s) from a local path.
-
-        Args:
-            path: string, the path of the artifacts.
-
-        Returns:
-            a dict containing the device image info.
-            a dict containing the test suite package info.
-        """
-        if path.endswith(".tar.md5"):
-            self.SetDeviceImage("img", path)
-        else:
-            self.SetFetchedFile(path, full_device_images=full_device_images)
-        return self.GetDeviceImage(), self.GetTestSuitePackage()
diff --git a/harnesses/host_controller/build/build_provider_pab.py b/harnesses/host_controller/build/build_provider_pab.py
deleted file mode 100644
index 9d932b6..0000000
--- a/harnesses/host_controller/build/build_provider_pab.py
+++ /dev/null
@@ -1,728 +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.
-#
-"""Module to fetch artifacts from Partner Android Build server."""
-
-import argparse
-import getpass
-import httplib2
-import json
-import logging
-import os
-import requests
-import urlparse
-from posixpath import join as path_urljoin
-
-from oauth2client.client import flow_from_clientsecrets
-from oauth2client.file import Storage
-from oauth2client.tools import argparser
-from oauth2client.tools import run_flow
-
-from selenium import webdriver
-from selenium.webdriver.common.by import By
-from selenium.common.exceptions import TimeoutException
-from selenium.webdriver.support import expected_conditions as EC
-from selenium.webdriver.common.keys import Keys
-from selenium.webdriver.chrome.options import Options
-from selenium.webdriver.support.ui import WebDriverWait
-
-from host_controller.build import build_provider
-
-# constants for GET and POST endpoints
-GET = 'GET'
-POST = 'POST'
-
-# timeout seconds for requests
-REQUESTS_TIMEOUT_SECONDS = 60
-
-
-class BuildProviderPAB(build_provider.BuildProvider):
-    """Client that manages Partner Android Build downloading.
-
-    Attributes:
-        BAD_XSRF_CODE: int, error code for bad XSRF token error
-        BASE_URL: string, path to PAB entry point
-        BUILDARTIFACT_NAME_KEY: string, index in artifact containing name
-        BUILD_BUILDID_KEY: string, index in build containing build_id
-        BUILD_COMPLETED_STATUS: int, value of 'complete' build
-        BUILD_STATUS_KEY: string, index in build object containing status.
-        CHROME_DRIVER_LOCATION: string, path to chromedriver
-        CHROME_LOCATION: string, path to Chrome browser
-        CLIENT_STORAGE: string, path to store credentials.
-        DEFAULT_CHUNK_SIZE: int, number of bytes to download at a time.
-        DOWNLOAD_URL_KEY: string, index in downloadBuildArtifact containing url
-        EMAIL: string, email constant for userinfo JSON
-        EXPIRED_XSRF_CODE: int, error code for expired XSRF token error
-        GETBUILD_ARTIFACTS_KEY, string, index in build obj containing artifacts
-        GMS_DOWNLOAD_URL: string, base url for downloading artifacts.
-        LISTBUILD_BUILD_KEY: string, index in listBuild containing builds
-        PAB_URL: string, redirect url from Google sign-in to PAB
-        PASSWORD: string, password constant for userinfo JSON
-        SCOPE: string, URL for which to request access via oauth2.
-        SVC_URL: string, path to buildsvc RPC
-        XSRF_STORE: string, path to store xsrf token
-        _credentials : oauth2client credentials object
-        _userinfo_file: location of file containing email and password
-        _xsrf : string, XSRF token from PAB website. expires after 7 days.
-    """
-    _credentials = None
-    _userinfo_file = None
-    _xsrf = None
-    BAD_XSRF_CODE = -32000
-    BASE_URL = 'https://partner.android.com'
-    BUILDARTIFACT_NAME_KEY = '1'
-    BUILD_BUILDID_KEY = '1'
-    BUILD_COMPLETED_STATUS = 7
-    BUILD_STATUS_KEY = '7'
-    CHROME_DRIVER_LOCATION = '/usr/local/bin/chromedriver'
-    CHROME_LOCATION = '/usr/bin/google-chrome'
-    CLIENT_SECRETS = os.path.join(
-        os.path.dirname(__file__), 'client_secrets.json')
-    CLIENT_STORAGE = os.path.join(os.path.dirname(__file__), 'credentials')
-    DEFAULT_CHUNK_SIZE = 1024
-    DOWNLOAD_URL_KEY = '1'
-    EMAIL = 'email'
-    EXPIRED_XSRF_CODE = -32001
-    GETBUILD_ARTIFACTS_KEY = '2'
-    GMS_DOWNLOAD_URL = 'https://partnerdash.google.com/build/gmsdownload'
-    LISTBUILD_BUILD_KEY = '1'
-    PAB_URL = ('https://www.google.com/accounts/Login?&continue='
-               'https://partner.android.com/build/')
-    PASSWORD = 'password'
-    # need both of these scopes to access PAB downloader
-    scopes = ('https://www.googleapis.com/auth/partnerdash',
-              'https://www.googleapis.com/auth/alkali-base')
-    SCOPE = ' '.join(scopes)
-    SVC_URL = urlparse.urljoin(BASE_URL, 'build/u/0/_gwt/_rpc/buildsvc')
-    XSRF_STORE = os.path.join(os.path.dirname(__file__), 'xsrf')
-
-    def __init__(self):
-        """Creates a temp dir."""
-        super(BuildProviderPAB, self).__init__()
-
-    def Authenticate(self, userinfo_file=None, noauth_local_webserver=False,
-                     scopes=SCOPE):
-        """Authenticate using OAuth2.
-
-        Args:
-            userinfo_file: (optional) the path of a JSON file which has
-                           "email" and "password" string fields.
-            noauth_local_webserver: boolean, True if do not (or can not) use
-                                    a local web server.
-            scopes: string or iterable of strings, the scopes to request.
-        """
-        # this should be a JSON file with "email" and "password" string fields
-        self._userinfo_file = userinfo_file
-        logging.info('Parsing flags, use --noauth_local_webserver'
-                     ' if running on remote machine')
-
-        parser = argparse.ArgumentParser(parents=[argparser])
-        flags, unknown = parser.parse_known_args()
-        flags.noauth_local_webserver = noauth_local_webserver
-        logging.info('Preparing OAuth token')
-        flow = flow_from_clientsecrets(self.CLIENT_SECRETS, scope=scopes)
-        storage = Storage(self.CLIENT_STORAGE)
-        if self._credentials is None:
-            self._credentials = storage.get()
-        if self._credentials is None or self._credentials.invalid:
-            logging.info('Credentials not found, authenticating.')
-            self._credentials = run_flow(flow, storage, flags)
-
-        if self._credentials.access_token_expired:
-            logging.info('Access token expired, refreshing.')
-            self._credentials.refresh(http=httplib2.Http())
-
-        if self.XSRF_STORE is not None and os.path.isfile(self.XSRF_STORE):
-            with open(self.XSRF_STORE, 'r') as handle:
-                self._xsrf = handle.read()
-
-    def GetXSRFToken(self, email=None, password=None):
-        """Get XSRF token. Prompt if email/password not provided.
-
-        Args:
-            email: string, optional. Gmail account of user logging in
-            password: string, optional. Password of user logging in
-
-        Returns:
-            boolean, whether the token was accessed and stored
-
-        Raises:
-            ValueError if login fails or userinfo file is malformed.
-        """
-        if self._userinfo_file is not None:
-            with open(self._userinfo_file, 'r') as handle:
-                userinfo = json.load(handle)
-
-            if self.EMAIL not in userinfo or self.PASSWORD not in userinfo:
-                raise ValueError(
-                    'Malformed userinfo file: needs email and password')
-
-            email = userinfo[self.EMAIL]
-            password = userinfo[self.PASSWORD]
-
-        chrome_options = Options()
-        chrome_options.add_argument("--headless")
-
-        driver = webdriver.Chrome(
-            chrome_options=chrome_options)
-
-        driver.set_window_size(1080, 800)
-        wait = WebDriverWait(driver, 10)
-
-        driver.get(self.PAB_URL)
-
-        query = driver.find_element_by_id("identifierId")
-        if email is None:
-            email = raw_input("Email: ")
-        query.send_keys(email)
-        driver.find_element_by_id("identifierNext").click()
-
-        pw = wait.until(EC.element_to_be_clickable((By.NAME, "password")))
-        pw.clear()
-
-        if password is None:
-            pw.send_keys(getpass.getpass("Password: "))
-        else:
-            pw.send_keys(password)
-
-        driver.find_element_by_id("passwordNext").click()
-
-        try:
-            wait.until(EC.title_contains("Partner Android Build"))
-        except TimeoutException as e:
-            logging.exception(e)
-            raise ValueError('Wrong password or non-standard login flow')
-
-        self._xsrf = driver.execute_script("return clientConfig.XSRF_TOKEN;")
-        with open(self.XSRF_STORE, 'w') as handle:
-            handle.write(self._xsrf)
-
-        return True
-
-    def CallBuildsvc(self, method, params, account_id):
-        """Call the buildsvc RPC with given parameters.
-
-        Args:
-            method: string, name of method to be called in buildsvc
-            params: dict, parameters to RPC call
-            account_id: int, ID associated with the PAB account.
-
-        Returns:
-            dict, result from RPC call
-
-        Raises:
-            ValueError if RPC call returns an error or an unknown response.
-        """
-        if self._xsrf is None:
-            self.GetXSRFToken()
-        params = json.dumps(params)
-
-        data = {"method": method, "params": params, "xsrf": self._xsrf}
-        data = json.dumps(data)
-        headers = {}
-        self._credentials.apply(headers)
-        headers['Content-Type'] = 'application/json'
-        headers['x-alkali-account'] = account_id
-
-        try:
-            response = requests.post(self.SVC_URL, data=data, headers=headers,
-                                     timeout=REQUESTS_TIMEOUT_SECONDS)
-        except requests.exceptions.Timeout as e:
-            logging.exception(e)
-            raise ValueError("Request timeout.")
-
-        responseJSON = {}
-
-        try:
-            responseJSON = response.json()
-        except ValueError:
-            raise ValueError("Backend error -- check your account ID")
-
-        if 'result' in responseJSON:
-            return responseJSON['result']
-
-        if 'error' in responseJSON and 'code' in responseJSON['error']:
-            if responseJSON['error']['code'] == self.BAD_XSRF_CODE:
-                raise ValueError(
-                    "Bad XSRF token -- must be for the same account as your credentials")
-            if responseJSON['error']['code'] == self.EXPIRED_XSRF_CODE:
-                raise ValueError("Expired XSRF token -- please refresh")
-
-        raise ValueError("Unknown response from server -- %s" %
-                         json.dumps(responseJSON))
-
-    def GetBuildList(self,
-                     account_id,
-                     branch,
-                     target,
-                     page_token="",
-                     max_results=10,
-                     internal=True,
-                     method=GET,
-                     verify_signed=False):
-        """Get the list of builds for a given account, branch and target
-        Args:
-            account_id: int, ID associated with the PAB account.
-            branch: string, branch to pull resource from.
-            target: string, "latest" or a specific version.
-            page_token: string, token used for pagination
-            max_results: maximum build results the build list contains, e.g. 25
-            internal: bool, whether to query internal build
-            method: 'GET' or 'POST', which endpoint to query
-            verify_signed: bool, whether to verify signed build.
-
-        Returns:
-            list of dicts representing the builds, descending in time
-
-        Raises:
-            ValueError if build request returns an error or builds not found.
-        """
-        if method == POST:
-            params = {
-                "1": branch,
-                "2": target,
-                "3": page_token,
-                "4": max_results,
-                "7": int(internal)
-            }
-
-            result = self.CallBuildsvc("listBuild", params, account_id)
-            # in listBuild response, index '1' contains builds
-            if self.LISTBUILD_BUILD_KEY in result:
-                return result[self.LISTBUILD_BUILD_KEY]
-
-            if verify_signed:
-                logging.error("verify_signed does not support POST method.")
-
-            raise ValueError("Build list not found -- %s" % params)
-        elif method == GET:
-            headers = {}
-            self._credentials.apply(headers)
-
-            action = 'list-internal' if internal else 'list'
-            # PAB URL format expects something (anything) to be given as buildid
-            # and resource, even for action list
-            dummy = 'DUMMY'
-            url = path_urljoin(self.BASE_URL, 'build', 'builds', action,
-                               branch, target, dummy,
-                               dummy) + '?a=' + str(account_id)
-            try:
-                response = requests.get(url, headers=headers,
-                                        timeout=REQUESTS_TIMEOUT_SECONDS)
-                responseJSON = response.json()
-                builds = responseJSON['build']
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-                raise ValueError("Request timeout.")
-            except ValueError as e:
-                logging.exception(e)
-                raise ValueError("Backend error -- check your account ID")
-
-            if verify_signed:
-                for build in builds:
-                    artifact_name = "signed%2Fsigned-{}-img-{}.zip".format(
-                        target.split("-")[0], build["build_id"])
-                    logging.debug("Checking whether the build is signed for "
-                                  "build_target {} and build_id {}".format(
-                                      target, build["build_id"]))
-                    signed_build_url = self.GetArtifactURL(
-                        account_id=account_id,
-                        build_id=build["build_id"],
-                        target=target,
-                        artifact_name=artifact_name,
-                        branch=branch,
-                        internal=False,
-                        method=method)
-                    try:
-                        self.GetResponseWithURL(signed_build_url)
-                        logging.debug("The build is signed.")
-                        build["signed"] = True
-                    except requests.HTTPError:
-                        logging.debug("The build is not signed.")
-                        build["signed"] = False
-                    except requests.exceptions.Timeout as e:
-                        logging.debug("Server is not responding.")
-                        logging.exception(e)
-                        build["signed"] = False
-            return builds
-
-    def GetLatestBuildId(self, account_id, branch, target, method=GET):
-        """Get the most recent build_id for a given account, branch and target
-        Args:
-            account_id: int, ID associated with the PAB account.
-            branch: string, branch to pull resource from.
-            target: string, "latest" or a specific version.
-            method: 'GET' or 'POST', which endpoint to query
-
-        Returns:
-            string, most recent build id
-
-        Raises:
-            ValueError if complete builds are not found.
-        """
-        # TODO: support pagination, maybe?
-        build_list = self.GetBuildList(account_id=account_id,
-                                       branch=branch,
-                                       target=target,
-                                       method=method)
-        if len(build_list) == 0:
-            raise ValueError(
-                'No builds found for account_id=%s, branch=%s, target=%s' %
-                (account_id, branch, target))
-        for build in build_list:
-            if method == POST:
-                # get build status: 7 = completed build
-                if build.get(self.BUILD_STATUS_KEY,
-                             None) == self.BUILD_COMPLETED_STATUS:
-                    # return build id (index '1')
-                    return build[self.BUILD_BUILDID_KEY]
-            elif method == GET:
-                if build['build_attempt_status'] == "COMPLETE" and build[
-                        "successful"]:
-                    return build['build_id']
-        raise ValueError(
-            'No complete builds found: %s failed or incomplete builds found' %
-            len(build_list))
-
-    def GetBuildArtifacts(
-            self, account_id, build_id, branch, target, method=POST):
-        """Get the list of build artifacts.
-
-        For an account, build, target, branch.
-
-        Args:
-            account_id: int, ID associated with the PAB account.
-            build_id: string, ID of the build
-            branch: string, branch to pull resource from.
-            target: string, "latest" or a specific version.
-            method: 'GET' or 'POST', which endpoint to query
-
-        Returns:
-            list of build artifact objects
-
-        Raises:
-            NotImplementedError if method is 'GET', which is not supported yet.
-            ValueError if build artifacts are not found.
-        """
-        if method == GET:
-            raise NotImplementedError(
-                "GetBuildArtifacts not supported with GET")
-        params = {"1": build_id, "2": target, "3": branch}
-
-        result = self.CallBuildsvc("getBuild", params, account_id)
-        # in getBuild response, index '2' contains the artifacts
-        if self.GETBUILD_ARTIFACTS_KEY in result:
-            return result[self.GETBUILD_ARTIFACTS_KEY]
-        if len(result) == 0:
-            raise ValueError("Build artifacts not found -- %s" % params)
-
-    def GetArtifactURL(self,
-                       account_id,
-                       build_id,
-                       target,
-                       artifact_name,
-                       branch,
-                       internal,
-                       method=GET):
-        """Get the URL for an artifact on the PAB server, using buildsvc.
-
-        Args:
-            account_id: int, ID associated with the PAB account.
-            build_id: string/int, id of the build.
-            target: string, "latest" or a specific version.
-            artifact_name: string, simple file name (no parent dir or path).
-            branch: string, branch to pull resource from.
-            internal: int, whether the request is for an internal build artifact
-            method: 'GET' or 'POST', which endpoint to query
-
-        Returns:
-            string, The URL for the resource specified by the parameters
-
-        Raises:
-            ValueError if given parameters are incorrect or resource not found.
-        """
-        if method == POST:
-            params = {
-                "1": str(build_id),
-                "2": target,
-                "3": artifact_name,
-                "4": branch,
-                "5": "",  # release_candidate_name
-                "6": internal
-            }
-
-            result = self.CallBuildsvc(method='downloadBuildArtifact',
-                                       params=params,
-                                       account_id=account_id)
-
-            # in downloadBuildArtifact response, index '1' contains the url
-            if self.DOWNLOAD_URL_KEY in result:
-                return result[self.DOWNLOAD_URL_KEY]
-            if len(result) == 0:
-                raise ValueError("Resource not found -- %s" % params)
-        elif method == GET:
-            headers = {}
-            self._credentials.apply(headers)
-
-            action = 'get-internal' if internal else 'get'
-            get_url = path_urljoin(self.BASE_URL, 'build', 'builds', action,
-                                   branch, target, build_id,
-                                   artifact_name) + '?a=' + str(account_id)
-
-            try:
-                response = requests.get(get_url, headers=headers,
-                                        timeout=REQUESTS_TIMEOUT_SECONDS)
-                responseJSON = response.json()
-                return responseJSON['url']
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-                raise ValueError("Request timeout.")
-            except ValueError:
-                raise ValueError("Backend error -- check your account ID")
-
-    def DownloadArtifact(self, download_url, filename):
-        """Get artifact from Partner Android Build server.
-
-        Args:
-            download_url: location of resource that we want to download
-            filename: where the artifact gets downloaded locally.
-
-        Returns:
-            boolean, whether the file was successfully downloaded
-        """
-        try:
-            response = self.GetResponseWithURL(download_url)
-        except (requests.HTTPError, requests.exceptions.Timeout) as error:
-            logging.exception(error)
-            return False
-        logging.info('%s now downloading...', download_url)
-        with open(filename, 'wb') as handle:
-            for block in response.iter_content(self.DEFAULT_CHUNK_SIZE):
-                handle.write(block)
-        return True
-
-    def GetArtifact(self,
-                    account_id,
-                    branch,
-                    target,
-                    artifact_name,
-                    build_id='latest',
-                    method=GET,
-                    full_device_images=False):
-        """Get an artifact for an account, branch, target and name and build id.
-
-        If build_id not given, get latest.
-
-        Args:
-            account_id: int, ID associated with the PAB account.
-            branch: string, branch to pull resource from.
-            target: string, "latest" or a specific version.
-            artifact_name: name of artifact, e.g. aosp_arm64_ab-img-4353141.zip
-                ({id} will automatically get replaced with build ID)
-            build_id: string, build ID of an artifact to fetch (or 'latest').
-            method: 'GET' or 'POST', which endpoint to query.
-
-        Returns:
-            a dict containing the device image info.
-            a dict containing the test suite package info.
-            a dict containing the artifact info.
-            a dict containing the global config info.
-
-        Raises:
-            ValueError if artifacts are not found.
-        """
-        artifact_info = {}
-        if build_id == 'latest':
-            build_id = self.GetLatestBuildId(account_id=account_id,
-                                             branch=branch,
-                                             target=target,
-                                             method=method)
-            logging.info("latest build ID = %s", build_id)
-        artifact_info["build_id"] = build_id
-
-        if "build_id" in artifact_name:
-            artifact_name = artifact_name.format(build_id=build_id)
-
-        if method == POST:
-            artifacts = self.GetBuildArtifacts(account_id=account_id,
-                                               build_id=build_id,
-                                               branch=branch,
-                                               target=target,
-                                               method=method)
-
-            if len(artifacts) == 0:
-                raise ValueError(
-                    "No artifacts found for build_id=%s, branch=%s, target=%s"
-                    % (build_id, branch, target))
-
-            # in build artifact response, index '1' contains the name
-            artifact_names = [
-                artifact[self.BUILDARTIFACT_NAME_KEY] for artifact in artifacts
-            ]
-            if artifact_name not in artifact_names:
-                raise ValueError("%s not found in artifact list" %
-                                 artifact_name)
-
-        url = self.GetArtifactURL(account_id=account_id,
-                                  build_id=build_id,
-                                  target=target,
-                                  artifact_name=artifact_name,
-                                  branch=branch,
-                                  internal=False,
-                                  method=method)
-
-        if self.tmp_dirpath:
-            artifact_path = os.path.join(self.tmp_dirpath, artifact_name)
-        else:
-            artifact_path = artifact_name
-        self.DownloadArtifact(url, artifact_path)
-
-        self.SetFetchedFile(
-            artifact_path, full_device_images=full_device_images)
-
-        return (self.GetDeviceImage(), self.GetTestSuitePackage(),
-                artifact_info, self.GetConfigPackage())
-
-    def GetSignedBuildArtifact(self,
-                               account_id,
-                               branch,
-                               target,
-                               artifact_name,
-                               build_id='latest',
-                               method=GET,
-                               full_device_images=False):
-        """Get an signed build artifact from the PAB bulid list.
-
-        Args:
-            account_id: int, ID associated with the PAB account.
-            branch: string, branch to pull resource from.
-            target: string, "latest" or a specific version.
-            artifact_name: name of artifact, e.g. aosp_arm64_ab-img-4353141.zip
-                ({id} will automatically get replaced with build ID)
-            build_id: string, build ID of an artifact to fetch (or 'latest').
-            method: 'GET' or 'POST', which endpoint to query.
-
-        Returns:
-            a dict containing the device image info.
-            a dict containing the test suite package info.
-            a dict containing the artifact info.
-            a dict containing the global config info.
-        """
-        artifact_info = {}
-        build_ids = []
-        artifact_path = ""
-        if build_id == 'latest':
-            try:
-                build_list = self.GetBuildList(
-                    account_id=account_id,
-                    branch=branch,
-                    target=target,
-                    method=method)
-                for build in build_list:
-                    build_ids.append(build["build_id"])
-            except ValueError as e:
-                logging.exception(e)
-        else:
-            build_ids.append(build_id)
-
-        for build_id in build_ids:
-            _artifact_name = artifact_name
-            if "build_id" in _artifact_name:
-                _artifact_name = _artifact_name.format(build_id=build_id)
-            _artifact_name = "signed%2Fsigned-" + _artifact_name
-            try:
-                url = self.GetArtifactURL(
-                    account_id=account_id,
-                    build_id=build_id,
-                    target=target,
-                    artifact_name=_artifact_name,
-                    branch=branch,
-                    internal=False,
-                    method=method)
-            except ValueError as e:
-                logging.exception(e)
-                continue
-
-            if self.tmp_dirpath:
-                artifact_path = os.path.join(self.tmp_dirpath, _artifact_name)
-            else:
-                artifact_path = _artifact_name
-            ret = self.DownloadArtifact(url, artifact_path)
-
-            if ret:
-                artifact_info["build_id"] = build_id
-                break
-
-        self.SetFetchedFile(
-            artifact_path, full_device_images=full_device_images)
-
-        return (self.GetDeviceImage(), self.GetTestSuitePackage(),
-                artifact_info, self.GetConfigPackage())
-
-    def GetResponseWithURL(self, url):
-        """Gets the response content from the server connected with the url.
-
-        Args:
-            url: A string representing the server url.
-
-        Returns:
-            A Response object received from the server.
-
-        Raises:
-            requests.HTTPError if response.status_code is not 200.
-            requests.exceptions.Timeout if the server does not respond.
-        """
-        headers = {}
-        self._credentials.apply(headers)
-        response = requests.get(url, headers=headers, stream=True,
-                                timeout=REQUESTS_TIMEOUT_SECONDS)
-        response.raise_for_status()
-
-        return response
-
-    def FetchLatestBuiltHCPackage(self, account_id, branch, target):
-        """Fetchs the latest <artifact_name> file and return the path.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-
-        Returns:
-            path to the fetched file. None if the fetching has failed.
-        """
-        try:
-            listed_builds = self.GetBuildList(
-                account_id=account_id,
-                branch=branch,
-                target=target,
-                page_token="",
-                max_results=1,
-                method="GET")
-
-            if listed_builds and len(listed_builds) > 0:
-                for listed_build in listed_builds:
-                    if listed_build["successful"]:
-                        self.GetArtifact(
-                            account_id=account_id,
-                            branch=branch,
-                            target=target,
-                            artifact_name="android-vtslab.zip",
-                            build_id=listed_build["build_id"],
-                            method="GET")
-
-                        return self.GetHostControllerPackage("vtslab")
-        except ValueError as e:
-            logging.exception(e)
diff --git a/harnesses/host_controller/build/build_provider_pab_test.py b/harnesses/host_controller/build/build_provider_pab_test.py
deleted file mode 100644
index 95e83c9..0000000
--- a/harnesses/host_controller/build/build_provider_pab_test.py
+++ /dev/null
@@ -1,317 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import unittest
-from host_controller.build import build_provider_pab
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from requests.models import Response
-
-
-class BuildProviderPABTest(unittest.TestCase):
-    """Tests for Partner Android Build client."""
-
-    def setUp(self):
-        self.client = build_provider_pab.BuildProviderPAB()
-        self.client.XSRF_STORE = None
-
-    def tearDown(self):
-        del self.client
-
-    @mock.patch("build_provider_pab.flow_from_clientsecrets")
-    @mock.patch("build_provider_pab.run_flow")
-    @mock.patch("build_provider_pab.Storage.get")
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    def testAuthenticationNew(self, mock_creds, mock_storage_get, mock_rf,
-                              mock_ffc):
-        mock_creds.invalid = True
-        build_provider_pab.flow_from_clientsecrets = mock_ffc
-        build_provider_pab.run_flow = mock_rf
-        self.client.Authenticate()
-        mock_ffc.assert_called_once()
-        mock_storage_get.assert_called_once()
-        mock_rf.assert_called_once()
-
-    @mock.patch("build_provider_pab.flow_from_clientsecrets")
-    @mock.patch("build_provider_pab.run_flow")
-    @mock.patch("build_provider_pab.Storage.get")
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    def testAuthenticationStale(self, mock_creds, mock_storage_get, mock_rf,
-                                mock_ffc):
-        mock_creds.invalid = False
-        mock_creds.access_token_expired = True
-        build_provider_pab.flow_from_clientsecrets = mock_ffc
-        build_provider_pab.run_flow = mock_rf
-        mock_storage_get.return_value = mock_creds
-        self.client.Authenticate()
-        mock_ffc.assert_called_once()
-        mock_storage_get.assert_called_once()
-        mock_rf.assert_not_called()
-        mock_creds.refresh.assert_called_once()
-
-    @mock.patch("build_provider_pab.flow_from_clientsecrets")
-    @mock.patch("build_provider_pab.run_flow")
-    @mock.patch("build_provider_pab.Storage.get")
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    def testAuthenticationFresh(self, mock_creds, mock_storage_get, mock_rf,
-                                mock_ffc):
-        mock_creds.invalid = False
-        mock_creds.access_token_expired = False
-        build_provider_pab.flow_from_clientsecrets = mock_ffc
-        build_provider_pab.run_flow = mock_rf
-        mock_storage_get.return_value = mock_creds
-        self.client.Authenticate()
-        mock_ffc.assert_called_once()
-        mock_storage_get.assert_called_once()
-        mock_rf.assert_not_called()
-        mock_creds.refresh.assert_not_called()
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.get')
-    @mock.patch('__builtin__.open')
-    def testDownloadArtifact(self, mock_open, mock_get, mock_creds):
-        self.client._credentials = mock_creds
-        artifact_url = (
-            "https://partnerdash.google.com/build/gmsdownload/"
-            "f_companion/label/clockwork.companion_20170906_211311_RC00/"
-            "ClockworkCompanionGoogleWithGmsRelease_signed.apk?a=100621237")
-        self.client.DownloadArtifact(
-            artifact_url, 'ClockworkCompanionGoogleWithGmsRelease_signed.apk')
-        self.client._credentials.apply.assert_called_with({})
-        mock_get.assert_called_with(
-            artifact_url, headers={}, stream=True)
-        mock_open.assert_called_with(
-            'ClockworkCompanionGoogleWithGmsRelease_signed.apk', 'wb')
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetArtifactURL(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{ "result" : {"1": "this_url"}}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        url = self.client.GetArtifactURL(
-            100621237,
-            "4331445",
-            "darwin_mac",
-            "android-ndk-43345-darwin-x86_64.tar.bz2",
-            "aosp-master-ndk",
-            0,
-            method='POST')
-        mock_post.assert_called_with(
-            'https://partner.android.com/build/u/0/_gwt/_rpc/buildsvc',
-            data=mock.ANY,
-            headers={
-                'Content-Type': 'application/json',
-                'x-alkali-account': 100621237,
-            })
-        self.assertEqual(url, "this_url")
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetArtifactURLBackendError(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'not JSON'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        with self.assertRaises(ValueError) as cm:
-            self.client.GetArtifactURL(
-                100621237,
-                "4331445",
-                "darwin_mac",
-                "android-ndk-43345-darwin-x86_64.tar.bz2",
-                "aosp-master-ndk",
-                0,
-                method='POST')
-        expected = "Backend error -- check your account ID"
-        self.assertEqual(str(cm.exception), expected)
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetArtifactURLMissingResultError(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{"result": {}}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        with self.assertRaises(ValueError) as cm:
-            self.client.GetArtifactURL(
-                100621237,
-                "4331445",
-                "darwin_mac",
-                "android-ndk-43345-darwin-x86_64.tar.bz2",
-                "aosp-master-ndk",
-                0,
-                method='POST')
-        expected = "Resource not found"
-        self.assertIn(expected, str(cm.exception))
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetArtifactURLInvalidXSRFError(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{"error": {"code": -32000, "message":"Invalid"}}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        with self.assertRaises(ValueError) as cm:
-            self.client.GetArtifactURL(
-                100621237,
-                "4331445",
-                "darwin_mac",
-                "android-ndk-43345-darwin-x86_64.tar.bz2",
-                "aosp-master-ndk",
-                0,
-                method='POST')
-        self.assertIn('Bad XSRF token', str(cm.exception))
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetArtifactURLExpiredXSRFError(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{"error": {"code": -32001, "message":"Expired"}}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        with self.assertRaises(ValueError) as cm:
-            self.client.GetArtifactURL(
-                100621237,
-                "4331445",
-                "darwin_mac",
-                "android-ndk-43345-darwin-x86_64.tar.bz2",
-                "aosp-master-ndk",
-                0,
-                method='POST')
-        self.assertIn('Expired XSRF token', str(cm.exception))
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetArtifactURLUnknownError(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{"some_other_json": "foo"}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        with self.assertRaises(ValueError) as cm:
-            self.client.GetArtifactURL(
-                100621237,
-                "4331445",
-                "darwin_mac",
-                "android-ndk-43345-darwin-x86_64.tar.bz2",
-                "aosp-master-ndk",
-                0,
-                method='POST')
-        self.assertIn('Unknown response from server', str(cm.exception))
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetBuildListSuccess(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{"result": {"1": "foo"}}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        result = self.client.GetBuildList(
-            100621237,
-            "git_oc-treble-dev",
-            "aosp_arm64_ab-userdebug",
-            method='POST')
-        self.assertEqual(result, "foo")
-        mock_post.assert_called_with(
-            'https://partner.android.com/build/u/0/_gwt/_rpc/buildsvc',
-            data=mock.ANY,
-            headers={
-                'Content-Type': 'application/json',
-                'x-alkali-account': 100621237,
-            })
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('requests.post')
-    def testGetBuildListError(self, mock_post, mock_creds):
-        self.client._xsrf = 'disable'
-        response = Response()
-        response.status_code = 200
-        response._content = b'{"result": {"3": "foo"}}'
-        mock_post.return_value = response
-        self.client._credentials = mock_creds
-        with self.assertRaises(ValueError) as cm:
-            self.client.GetBuildList(
-                100621237,
-                "git_oc-treble-dev",
-                "aosp_arm64_ab-userdebug",
-                method='POST')
-        self.assertIn('Build list not found', str(cm.exception))
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('build_provider_pab.BuildProviderPAB.GetBuildList')
-    def testGetLatestBuildIdSuccess(self, mock_gbl, mock_creds):
-        self.client._xsrf = 'disable'
-        mock_gbl.return_value = [{'7': 5, '1': 'bad'}, {'7': 7, '1': 'good'}]
-        self.client.GetBuildList = mock_gbl
-        result = self.client.GetLatestBuildId(
-            100621237,
-            "git_oc-treble-dev",
-            "aosp_arm64_ab-userdebug",
-            method='POST')
-        self.assertEqual(result, 'good')
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('build_provider_pab.BuildProviderPAB.GetBuildList')
-    def testGetLatestBuildIdEmpty(self, mock_gbl, mock_creds):
-        self.client._xsrf = 'disable'
-        mock_gbl.return_value = []
-        self.client.GetBuildList = mock_gbl
-        with self.assertRaises(ValueError) as cm:
-            result = self.client.GetLatestBuildId(
-                100621237,
-                "git_oc-treble-dev",
-                "aosp_arm64_ab-userdebug",
-                method='POST')
-        self.assertIn("No builds found for", str(cm.exception))
-
-    @mock.patch('build_provider_pab.BuildProviderPAB._credentials')
-    @mock.patch('build_provider_pab.BuildProviderPAB.GetBuildList')
-    def testGetLatestBuildIdAllBad(self, mock_gbl, mock_creds):
-        self.client._xsrf = 'disable'
-        mock_gbl.return_value = [{'7': 0}, {'7': 0}]
-        self.client.GetBuildList = mock_gbl
-        with self.assertRaises(ValueError) as cm:
-            result = self.client.GetLatestBuildId(
-                100621237,
-                "git_oc-treble-dev",
-                "aosp_arm64_ab-userdebug",
-                method='POST')
-        self.assertEqual(
-            "No complete builds found: 2 failed or incomplete builds found",
-            str(cm.exception))
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/build/build_provider_test.py b/harnesses/host_controller/build/build_provider_test.py
deleted file mode 100644
index 71b96d1..0000000
--- a/harnesses/host_controller/build/build_provider_test.py
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import shutil
-import tempfile
-import unittest
-import zipfile
-
-from host_controller import common
-from host_controller.build import build_provider
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-
-class BuildProviderTest(unittest.TestCase):
-    """Tests for build_provider.
-
-    Attributes:
-        _build_provider: The BuildProvider object under test.
-        _temp_dir: The path to the temporary directory for test files.
-    """
-
-    def setUp(self):
-        """Creates temporary directory."""
-        self._build_provider = build_provider.BuildProvider()
-        self._temp_dir = tempfile.mkdtemp()
-
-    def tearDown(self):
-        """Deletes temporary directory."""
-        shutil.rmtree(self._temp_dir)
-
-    def _CreateFile(self, name):
-        """Creates an empty file as test data.
-
-        Args:
-            name: string, the name of the file.
-
-        Returns:
-            string, the path to the file.
-        """
-        path = os.path.join(self._temp_dir, name)
-        with open(path, "w"):
-            pass
-        return path
-
-    def _CreateZip(self, name, *paths):
-        """Creates a zip file containing empty files.
-
-        Args:
-            name: string, the name of the zip file.
-            *paths: strings, the file paths to create in the zip file.
-
-        Returns:
-            string, the path to the zip file.
-        """
-        empty_path = self._CreateFile("empty")
-        zip_path = os.path.join(self._temp_dir, name)
-        with zipfile.ZipFile(zip_path, "w") as zip_file:
-            for path in paths:
-                zip_file.write(empty_path, path)
-        return zip_path
-
-    def _CreateVtsPackage(self):
-        """Creates an android-vts.zip containing vts-tradefed.
-
-        Returns:
-            string, the path to the zip file.
-        """
-        return self._CreateZip(
-            "android-vts.zip",
-            os.path.join("android-vts", "tools", "vts-tradefed"))
-
-    def _CreateDeviceImageZip(self):
-        """Creates a zip containing common device images.
-
-        Returns:
-            string, the path to the zip file.
-        """
-        return self._CreateZip(
-            "img.zip", "system.img", "vendor.img", "boot.img")
-
-    def _CreateProdConfig(self):
-        """Creates a zip containing config files.
-
-        Returns:
-            string, the path to the zip file.
-        """
-        return self._CreateZip(
-            "vti-global-config-prod.zip", os.path.join("test", "prod.config"))
-
-    def testSetTestSuitePackage(self):
-        """Tests setting a VTS package."""
-        vts_path = self._CreateVtsPackage()
-        self._build_provider.SetTestSuitePackage("vts", vts_path)
-
-        self.assertTrue(
-            os.path.exists(self._build_provider.GetTestSuitePackage("vts")))
-
-    def testSetDeviceImageZip(self):
-        """Tests setting a device image zip."""
-        img_path = self._CreateDeviceImageZip()
-        self._build_provider.SetDeviceImageZip(img_path)
-
-        self.assertEqual(
-            img_path,
-            self._build_provider.GetDeviceImage(common.FULL_ZIPFILE))
-
-    def testSetConfigPackage(self):
-        """Tests setting a config package."""
-        config_path = self._CreateProdConfig()
-        self._build_provider.SetConfigPackage("prod", config_path)
-
-        self.assertTrue(
-            os.path.exists(self._build_provider.GetConfigPackage("prod")))
-
-    def testSetFetchedDirectory(self):
-        """Tests setting all files in a directory."""
-        self._CreateVtsPackage()
-        self._CreateProdConfig()
-        img_zip = self._CreateDeviceImageZip()
-        img_file = self._CreateFile("userdata.img")
-        txt_file = self._CreateFile("additional.txt")
-        self._build_provider.SetFetchedDirectory(self._temp_dir)
-
-        self.assertDictContainsSubset(
-            {common.FULL_ZIPFILE: img_zip, "userdata.img": img_file},
-            self._build_provider.GetDeviceImage())
-        self.assertTrue(
-            os.path.exists(self._build_provider.GetTestSuitePackage("vts")))
-        self.assertTrue(
-            os.path.exists(self._build_provider.GetConfigPackage("prod")))
-        self.assertDictContainsSubset(
-            {"additional.txt": txt_file},
-            self._build_provider.GetAdditionalFile())
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/campaigns/__init__.py b/harnesses/host_controller/campaigns/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/campaigns/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/campaigns/campaign_common.py b/harnesses/host_controller/campaigns/campaign_common.py
deleted file mode 100644
index 82bb726..0000000
--- a/harnesses/host_controller/campaigns/campaign_common.py
+++ /dev/null
@@ -1,755 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller import common
-from vti.test_serving.proto import TestScheduleConfigMessage_pb2 as pb
-
-# The list of the kwargs key. can retrieve informations on the leased job.
-_JOB_ATTR_LIST = [
-    "build_id",
-    "test_name",
-    "shards",
-    "serial",
-    "build_target",
-    "manifest_branch",
-    "gsi_branch",
-    "gsi_build_target",
-    "test_branch",
-    "test_build_target",
-]
-
-
-def HasAttr(attr, **kwargs):
-    """Returns True if 'attr' is in 'kwargs' as an arg."""
-    return True if attr in kwargs and kwargs[attr] else False
-
-
-def GetVersion(branch):
-    """Returns the API level (integer) for the given branch."""
-    branch = str(branch.lower())
-    if branch.startswith("git_"):
-        branch = branch[4:]
-    if branch.startswith("aosp-"):
-        branch = branch[5:]
-
-    if "-treble-" in branch:
-        branch = branch.replace("-treble-", "-")
-
-    if branch.endswith("-dev"):
-        branch = branch[:-4]
-    elif branch.endswith("-release"):
-        branch = branch[:-8]
-
-    if (branch.startswith("o") and branch.endswith(
-        ("mr1", "m2", "m3", "m4", "m5", "m6"))):
-        return 8.1
-    elif branch.startswith("o"):
-        return 8.0
-    elif branch.startswith("p"):
-        return 9.0
-    elif branch.startswith("gs://"):
-        if "v8.0" in branch:
-            return 8.0
-        elif "v8.1" in branch:
-            return 8.1
-        elif "v9.0" in branch:
-            return 9.0
-    return 9.0
-
-
-def EmitFetchCommands(**kwargs):
-    """Returns a list of common fetch commands.
-
-    This uses a given device branch information and automatically
-    selects a GSI branch and a test branch.
-
-    Args:
-        kwargs: keyword argument, contains data about the leased job.
-    Returns:
-        list of command string.
-        bool, True if GSI image is fetched. False otherwise
-    """
-    result = []
-    if isinstance(kwargs["build_target"], list):
-        build_target = kwargs["build_target"][0]
-    else:
-        build_target = kwargs["build_target"]
-    shards = int(kwargs["shards"])
-    suite_name, _ = kwargs["test_name"].split("/")
-    serials = kwargs["serial"]
-
-    if HasAttr("pab_account_id", **kwargs):
-        pab_account_id = kwargs["pab_account_id"]
-    else:
-        pab_account_id = common._DEFAULT_ACCOUNT_ID_INTERNAL
-
-    manifest_branch = kwargs["manifest_branch"]
-    build_id = kwargs["build_id"]
-    build_storage_type = pb.BUILD_STORAGE_TYPE_PAB
-    if HasAttr("build_storage_type", **kwargs):
-        build_storage_type = int(kwargs["build_storage_type"])
-
-    if build_storage_type == pb.BUILD_STORAGE_TYPE_PAB:
-        result.append(
-            "fetch --type=pab --branch=%s --target=%s --artifact_name=%s-img-%s.zip "
-            "--build_id=%s --account_id=%s" %
-            (manifest_branch, build_target, build_target.split("-")[0],
-             build_id if build_id != "latest" else "{build_id}", build_id,
-             pab_account_id))
-        if HasAttr("require_signed_device_build", **kwargs):
-            result[-1] += " --fetch_signed_build=True"
-        if common.UNIVERSAL9810 in build_target:
-            result[-1] += " --full_device_images=True"
-
-        if HasAttr("has_bootloader_img", **kwargs):
-            result.append("fetch --type=pab --branch=%s --target=%s "
-                          "--artifact_name=bootloader.img --build_id=%s "
-                          "--account_id=%s" % (manifest_branch, build_target,
-                                               build_id, pab_account_id))
-
-        if HasAttr("has_radio_img", **kwargs):
-            result.append("fetch --type=pab --branch=%s --target=%s "
-                          "--artifact_name=radio.img --build_id=%s "
-                          "--account_id=%s" % (manifest_branch, build_target,
-                                               build_id, pab_account_id))
-
-    elif build_storage_type == pb.BUILD_STORAGE_TYPE_GCS:
-        result.append("fetch --type=gcs --path=%s" % (manifest_branch))
-        if common.UNIVERSAL9810 in build_target:
-            result[-1] += " --full_device_images=True"
-    else:
-        logging.error("unknown build storage type is given: %d",
-                      build_storage_type)
-        return None
-
-    if HasAttr("gsi_branch", **kwargs):
-        gsi = True
-    else:
-        gsi = False
-
-    if HasAttr("gsi_vendor_version", **kwargs):
-        gsi_vendor_version = kwargs["gsi_vendor_version"]
-    else:
-        gsi_vendor_version = None
-
-    if gsi:
-        if common.SDM845 in build_target:
-            if shards > 1:
-                sub_commands = []
-                if shards <= len(serials):
-                    for shard_index in range(shards):
-                        sub_commands.append(
-                            GenerateSdm845SetupCommands(serials[shard_index]))
-                result.append(sub_commands)
-            else:
-                result.extend(GenerateSdm845SetupCommands(serials[0]))
-
-        if HasAttr("gsi_build_id", **kwargs):
-            gsi_build_id = kwargs["gsi_build_id"]
-        else:
-            gsi_build_id = "latest"
-        gsi_storage_type = pb.BUILD_STORAGE_TYPE_PAB
-        if HasAttr("gsi_storage_type", **kwargs):
-            gsi_storage_type = int(kwargs["gsi_storage_type"])
-
-        if gsi_storage_type == pb.BUILD_STORAGE_TYPE_PAB:
-            result.append(
-                "fetch --type=pab --branch=%s --target=%s --gsi=True "
-                "--artifact_name=%s-img-{build_id}.zip --build_id=%s" %
-                (kwargs["gsi_branch"], kwargs["gsi_build_target"],
-                 kwargs["gsi_build_target"].split("-")[0], gsi_build_id))
-        elif gsi_storage_type == pb.BUILD_STORAGE_TYPE_GCS:
-            result.append("fetch --type=gcs --path=%s/%s-img-%s.zip "
-                          "--gsi=True" %
-                          (kwargs["gsi_branch"],
-                           kwargs["gsi_build_target"].split("-")[0],
-                           gsi_build_id))
-        else:
-            logging.error("unknown gsi storage type is given: %d",
-                          gsi_storage_type)
-            return None
-
-        if HasAttr("gsi_pab_account_id", **kwargs):
-            result[-1] += " --account_id=%s" % kwargs["gsi_pab_account_id"]
-
-    if HasAttr("test_build_id", **kwargs):
-        test_build_id = kwargs["test_build_id"]
-    else:
-        test_build_id = "latest"
-    test_storage_type = pb.BUILD_STORAGE_TYPE_PAB
-    if HasAttr("test_storage_type", **kwargs):
-        test_storage_type = int(kwargs["test_storage_type"])
-
-    if test_storage_type == pb.BUILD_STORAGE_TYPE_PAB:
-        result.append("fetch --type=pab --branch=%s --target=%s "
-                      "--artifact_name=android-%s.zip --build_id=%s" %
-                      (kwargs["test_branch"], kwargs["test_build_target"],
-                       suite_name, test_build_id))
-    elif test_storage_type == pb.BUILD_STORAGE_TYPE_GCS:
-        result.append("fetch --type=gcs --path=%s/%s.zip --set_suite_as=%s" %
-                      (kwargs["test_branch"], kwargs["test_build_target"],
-                       suite_name))
-    else:
-        logging.error("unknown test storage type is given: %d",
-                      test_storage_type)
-        return None
-
-    if HasAttr("test_pab_account_id", **kwargs):
-        result[-1] += " --account_id=%s" % kwargs["test_pab_account_id"]
-
-    result.append("info")
-    if gsi:
-        gsispl_command = "gsispl --version_from_path=boot.img"
-        if gsi_vendor_version:
-            gsispl_command += " --vendor_version=%s" % gsi_vendor_version
-        result.append(gsispl_command)
-        result.append("info")
-
-    return result, gsi
-
-
-def EmitFlashCommands(gsi, **kwargs):
-    """Returns a list of common flash commands.
-
-    This uses a given device branch information and automatically
-    selects a GSI branch and a test branch.
-
-    Args:
-        gsi: bool, whether to flash GSI over vendor images or not.
-        kwargs: keyword argument, contains data about the leased job.
-    Returns:
-        list of command string.
-    """
-    result = []
-
-    if isinstance(kwargs["build_target"], list):
-        build_target = kwargs["build_target"][0]
-    else:
-        build_target = kwargs["build_target"]
-    shards = int(kwargs["shards"])
-    serials = kwargs["serial"]
-    if gsi:
-        system_version = GetVersion(kwargs["gsi_branch"])
-    else:
-        system_version = GetVersion(kwargs["manifest_branch"])
-
-    repack_command = "repack"
-    if HasAttr("image_package_repo_base", **kwargs):
-        repack_command += " --dest=%s" % kwargs["image_package_repo_base"]
-    if common.SDM845 in build_target and gsi:
-        repack_command += (" --additional_files")
-        for lib_file in common.SDM845_LIB_LIST:
-            repack_command += (" {tmp_dir}/%s/%s" % (serials[0], lib_file))
-    # TODO: verify this before re-enabling.
-    # result.append(repack_command)
-
-    if shards > 1:
-        sub_commands = []
-
-        if shards <= len(serials):
-            for shard_index in range(shards):
-                new_cmd_list = []
-                if (common.K39TV1_BSP in build_target
-                        or common.K39TV1_BSP_1G in build_target):
-                    new_cmd_list.extend(
-                        GenerateMt6739GsiFlashingCommands(
-                            serials[shard_index], gsi))
-                elif common.SDM845 in build_target and gsi:
-                    new_cmd_list.extend(
-                        GenerateSdm845GsiFlashingCommands(
-                            serials[shard_index]))
-                elif common.UNIVERSAL9810 in build_target:
-                    new_cmd_list.extend(
-                        GenerateUniversal9810GsiFlashingCommands(
-                            serials[shard_index], gsi))
-                else:
-                    new_cmd_list.append(
-                        "flash --current --serial %s --skip-vbmeta=True " %
-                        serials[shard_index])
-                new_cmd_list.append("adb -s %s root" % serials[shard_index])
-                if common.SDM845 not in build_target:  # b/78487061
-                    new_cmd_list.append(
-                        "dut --operation=wifi_on --serial=%s --ap=%s" %
-                        (serials[shard_index], common._DEFAULT_WIFI_AP))
-                    new_cmd_list.append(
-                        "dut --operation=volume_mute --serial=%s --version=%s"
-                        % (serials[shard_index], system_version))
-                sub_commands.append(new_cmd_list)
-        result.append(sub_commands)
-    else:
-        if (common.K39TV1_BSP in build_target
-                or common.K39TV1_BSP_1G in build_target):
-            result.extend(GenerateMt6739GsiFlashingCommands(serials[0], gsi))
-        elif common.SDM845 in build_target and gsi:
-            result.extend(GenerateSdm845GsiFlashingCommands(serials[0]))
-        elif common.UNIVERSAL9810 in build_target:
-            result.extend(
-                GenerateUniversal9810GsiFlashingCommands(serials[0], gsi))
-        else:
-            result.append(
-                "flash --current --serial %s --skip-vbmeta=True" % serials[0])
-        if common.SDM845 not in build_target:  # b/78487061
-            result.append("dut --operation=wifi_on --serial=%s --ap=%s" %
-                          (serials[0], common._DEFAULT_WIFI_AP))
-            result.append(
-                "dut --operation=volume_mute --serial=%s --version=%s" %
-                (serials[0], system_version))
-        if serials:
-            serial_arg_list = []
-            for serial in serials:
-                result.append("adb -s %s root" % serial)
-                serial_arg_list.append("--serial %s" % serial)
-
-    return result
-
-
-def EmitCommonConsoleCommands(**kwargs):
-    """Runs a common VTS-on-GSI or CTS-on-GSI test.
-
-    This uses a given device branch information and automatically
-    selects a GSI branch and a test branch.
-    """
-    result = []
-
-    if not set(_JOB_ATTR_LIST).issubset(kwargs):
-        missing_keys = [key for key in _JOB_ATTR_LIST if key not in kwargs]
-        logging.error("Leased job missing attribute(s): {}".format(
-            ", ".join(missing_keys)))
-        return None
-
-    if isinstance(kwargs["build_target"], list):
-        build_target = kwargs["build_target"][0]
-    else:
-        build_target = kwargs["build_target"]
-    shards = int(kwargs["shards"])
-    suite_name, plan_name = kwargs["test_name"].split("/")
-    serials = kwargs["serial"]
-
-    result.append("device --set_serial=%s --from_job_pool --interval=%s" %
-                  (",".join(serials), common.DEFAULT_DEVICE_TIMEOUT_SECS))
-    fetch_commands_result, gsi = EmitFetchCommands(**kwargs)
-    result.extend(fetch_commands_result)
-    flash_commands_result = EmitFlashCommands(gsi, **kwargs)
-    result.extend(flash_commands_result)
-
-    param = ""
-    if HasAttr("param", **kwargs):
-        param = " ".join(kwargs["param"])
-
-    test_branch = kwargs["test_branch"]
-    if (GetVersion(test_branch) >= 9.0 and
-        (suite_name in ["cts", "gts", "sts"] or plan_name.startswith("cts"))):
-        shard_option = "--shard-count"
-    else:
-        shard_option = "--shards"
-
-    if shards > 1:
-        test_command = "test --suite %s --keep-result -- %s %s %d %s" % (
-            suite_name, plan_name, shard_option, shards, param)
-        if shards <= len(serials):
-            for shard_index in range(shards):
-                test_command += " --serial %s" % serials[shard_index]
-        result.append(test_command)
-    else:
-        if serials:
-            serial_arg_list = []
-            for serial in serials:
-                serial_arg_list.append("--serial %s" % serial)
-            result.append("test --suite %s --keep-result -- %s %s %s" %
-                          (suite_name, plan_name, " ".join(serial_arg_list),
-                           param))
-        else:
-            result.append("test --suite %s --keep-result -- %s %s" %
-                          (suite_name, plan_name, param))
-
-    if "retry_count" in kwargs:
-        retry_count = int(kwargs["retry_count"])
-        result.append(
-            GenerateRetryCommand(build_target, test_branch, suite_name,
-                                 plan_name, serials, retry_count))
-
-    if HasAttr("test_build_id", **kwargs):
-        test_build_id = kwargs["test_build_id"]
-    else:
-        test_build_id = "latest"
-    test_storage_type = pb.BUILD_STORAGE_TYPE_PAB
-    if HasAttr("test_storage_type", **kwargs):
-        test_storage_type = int(kwargs["test_storage_type"])
-
-    if HasAttr("report_bucket", **kwargs):
-        report_buckets = kwargs["report_bucket"]
-    else:
-        report_buckets = ["gs://vts-report"]
-
-    upload_dests = []
-    upload_commands = []
-    for report_bucket in report_buckets:
-        if test_storage_type == pb.BUILD_STORAGE_TYPE_PAB:
-            upload_dest = ("%s/{suite_plan}/%s/{branch}/{target}/"
-                           "%s_{build_id}_{timestamp}/" %
-                           (report_bucket, plan_name, build_target))
-        elif test_storage_type == pb.BUILD_STORAGE_TYPE_GCS:
-            upload_dest = ("%s/{suite_plan}/%s/%s/%s/%s_%s_{timestamp}/" %
-                           (report_bucket, plan_name,
-                            kwargs["test_branch"].replace("gs://", "gs_")
-                            if kwargs["test_branch"].startswith("gs://") else
-                            kwargs["test_branch"], kwargs["test_build_target"],
-                            build_target, test_build_id))
-        upload_dests.append(upload_dest)
-        upload_commands.append(
-            "upload --src={result_full} --dest=%s "
-            "--report_path=%s/suite_result/{timestamp_year}/{timestamp_month}/"
-            "{timestamp_day}" % (upload_dest, report_bucket))
-
-    if HasAttr("report_persistent_url", **kwargs):
-        for upload_dest in kwargs["report_persistent_url"]:
-            upload_dests.append(upload_dest)
-            upload_commands.append("upload --src={result_full} --dest=%s "
-                                   "--clear_dest" % upload_dest)
-
-    result.extend(upload_commands)
-
-    if HasAttr("report_reference_url", **kwargs):
-        ref_urls = kwargs["report_reference_url"]
-    else:
-        ref_urls = []
-
-    extra_rows = " ".join("logs," + x for x in upload_dests)
-    if HasAttr("report_spreadsheet_id", **kwargs):
-        for index, sheet_id in enumerate(kwargs["report_spreadsheet_id"]):
-            sheet_command = ("sheet --src {result_zip} --dest %s "
-                             "--extra_rows %s" % (sheet_id, extra_rows))
-            if plan_name == "cts-on-gsi":
-                sheet_command += " --primary_abi_only"
-            if index < len(ref_urls):
-                sheet_command += " --ref " + ref_urls[index]
-            sheet_command += " --client_secrets DATA/vtslab-gcs.json"
-            result.append(sheet_command)
-
-    result.append("device --update=stop")
-
-    return result
-
-
-def GenerateRetryCommand(build_target,
-                         test_branch,
-                         suite_name,
-                         plan_name,
-                         serials,
-                         retry_count=None):
-    """Returns a retry command.
-
-    Args:
-        build_target: string, build target of the device images
-        test_branch: string, branch name from which the test suite is fetched
-        suite_name: string, the name of the test suite
-        plan_name: string, the name of the test plan that needs to be run
-        serials: list of strings, serial numbers of the DUTs
-        retry_count: int,
-
-    Returns:
-        a string, retry command of the console.
-    """
-    if GetVersion(test_branch) >= 9.0:
-        retry_option = ""
-        shard_option = "--shard-count"
-        if suite_name in ["cts", "gts", "sts"]:
-            retry_option = "--retry_plan=retry"
-        elif plan_name.startswith("cts"):
-            retry_option = "--retry_plan=%s-retry" % plan_name
-        else:
-            shard_option = "--shards"
-    else:
-        shard_option = "--shards"
-        retry_option = ""
-
-    if retry_count is None:
-        retry_count = common.DEFAULT_RETRY_COUNT
-    retry_command = ("retry --suite %s --count %d %s" %
-                     (suite_name, retry_count, retry_option))
-    if serials:
-        if len(serials) > 1:
-            retry_command += " %s %d" % (shard_option, len(serials))
-            for shard_index in range(len(serials)):
-                retry_command += " --serial %s" % serials[shard_index]
-        else:
-            retry_command += " --serial %s" % serials[0]
-    if suite_name in ["cts", "gts", "sts"] or plan_name.startswith("cts"):
-        if common.SDM845 in build_target:
-            # TODO(vtslab-dev): remove after b/77664643 is resolved
-            pass
-        else:
-            retry_command += " --cleanup_devices=True"
-
-    return retry_command
-
-
-def GenerateSdm845SetupCommands(serial):
-    """Returns a sequence of console commands to setup a device.
-
-    Args:
-        serial: string, the target device serial number.
-
-    Returns:
-        a list of strings, each string is a console command.
-    """
-    result = []
-
-    result.append(
-        "fastboot -s %s flash bootloader {device-image[bootloader.img]}" %
-        serial)
-    result.append("fastboot -s %s -- reboot bootloader" % serial)
-    result.append(
-        "fastboot -s %s flash radio {device-image[radio.img]}" % serial)
-    result.append("fastboot -s %s -- reboot bootloader" % serial)
-    result.append(
-        "fastboot -s %s flash boot {device-image[full-zipfile-dir]}/boot.img" %
-        serial)
-    result.append(
-        "fastboot -s %s flash dtbo {device-image[full-zipfile-dir]}/dtbo.img" %
-        serial)
-    result.append(
-        "fastboot --timeout=900 -s %s flash system {device-image[full-zipfile-dir]}/system.img"
-        % serial)
-    result.append(
-        "fastboot -s %s flash userdata {device-image[full-zipfile-dir]}/userdata.img"
-        % serial)
-    result.append(
-        "fastboot -s %s flash vbmeta {device-image[full-zipfile-dir]}/vbmeta.img"
-        " -- --disable-verity" % serial)
-    result.append(
-        "fastboot -s %s flash vendor {device-image[full-zipfile-dir]}/vendor.img"
-        % serial)
-    result.append("fastboot -s %s reboot" % serial)
-    result.append("sleep 90")  # wait for boot_complete (success)
-    result.append("adb -s %s root" % serial)
-    # TODO: to make sure {tmp_dir} is unique per session and
-    #       is cleaned up at exit.
-    result.append("shell -- mkdir -p {tmp_dir}/%s" % serial)
-    result.extend([
-        "adb -s %s pull /system/lib64/%s {tmp_dir}/%s" % (serial, lib_file,
-                                                          serial)
-        for lib_file in common.SDM845_LIB_LIST
-    ])
-
-    # TODO: remove this paragraph after b/74552817 is fixed.
-    result.append(
-        "fetch --type=gcs --path=gs://vts-release/v9.0/sdm845/vbmeta.img "
-        "--artifact_name=vbmeta.img")
-    result.append("adb -s %s reboot bootloader" % serial)
-    result.append("fastboot -s %s flash vbmeta {device-image[vbmeta.img]}"
-                  " -- --disable-verity" % serial)
-
-    return result
-
-
-def GenerateSdm845GsiFlashingCommands(serial, repacked_imageset=False):
-    """Returns a sequence of console commands to flash GSI to a device.
-
-    Args:
-        serial: string, the target device serial number.
-        repacked_imageset: bool, True if this function is called directly from
-                           the console, adjusts the resulting commands for
-                           atomic flashing process.
-
-    Returns:
-        a list of strings, each string is a console command.
-    """
-    result = []
-
-    if repacked_imageset:
-        result.append(
-            "fastboot -s %s flash bootloader {device-image[bootloader.img]}" %
-            serial)
-        result.append("fastboot -s %s -- reboot bootloader" % serial)
-        result.append(
-            "fastboot -s %s flash radio {device-image[radio.img]}" % serial)
-        result.append("fastboot -s %s -- reboot bootloader" % serial)
-        result.append(
-            "fastboot -s %s flash boot {device-image[boot.img]}" % serial)
-        result.append(
-            "fastboot -s %s flash dtbo {device-image[dtbo.img]}" % serial)
-        result.append(
-            "fastboot -s %s flash userdata {device-image[userdata.img]}" %
-            serial)
-        result.append(
-            "fastboot -s %s flash vbmeta {device-image[vbmeta.img]} -- --disable-verity"
-            % serial)
-        result.append(
-            "fastboot -s %s flash vendor {device-image[vendor.img]}" % serial)
-
-    result.append(
-        "fastboot --timeout=900 -s %s flash system {device-image[system.img]}"
-        % serial)
-    # removed -w from below command
-    result.append("fastboot -s %s -- reboot" % serial)
-    result.append("sleep 90")  # wait until adb shell (not boot complete)
-    result.append("adb -s %s root" % serial)
-    result.append("adb -s %s remount" % serial)
-    result.append("adb -s %s shell setenforce 0" % serial)
-    result.append("adb -s %s shell mkdir /bt_firmware" % serial)
-    result.append("adb -s %s shell chown system:system /bt_firmware" % serial)
-    result.append("adb -s %s shell chmod 650 /bt_firmware" % serial)
-    result.append("adb -s %s shell setenforce 1" % serial)
-    if repacked_imageset:
-        result.extend([
-            "adb -s %s push {tools[%s/%s]} /system/lib64" %
-            (serial, common._ADDITIONAL_FILES_DIR, lib_file)
-            for lib_file in common.SDM845_LIB_LIST
-        ])
-    else:
-        result.extend([
-            "adb -s %s push {tmp_dir}/%s/%s /system/lib64" % (serial, serial,
-                                                              lib_file)
-            for lib_file in common.SDM845_LIB_LIST
-        ])
-        result.extend(
-            [("adb -s %s push ../testcases/DATA/xml/media_profiles_vendor.xml "
-              "/vendor/etc/media_profiles_vendor.xml") % serial])
-
-    result.append("shell -- rm {tmp_dir}/%s -rf" % serial)
-    result.append("adb -s %s reboot bootloader" % serial)
-    result.append("sleep 5")
-    # TODO(vtslab-dev): remove after b/112171990 is resolved
-    result.append("fastboot -s %s erase userdata" % serial)
-    # removed -w from below command
-    result.append("fastboot -s %s  -- reboot" % serial)
-    if not repacked_imageset:
-        result.append("sleep 300")  # wait for boot_complete (success)
-
-    return result
-
-
-def GenerateMt6739GsiFlashingCommands(serial,
-                                      gsi=False,
-                                      repacked_imageset=False):
-    """Returns a sequence of console commands to flash device imgs and GSI.
-
-    Args:
-        serial: string, the target device serial number.
-        gsi: bool, whether to flash GSI over vendor images or not.
-        repacked_imageset: bool, True if this func is called directly from
-                           the console, adjusts the resulting commands for
-                           atomic flashing process.
-
-    Returns:
-        a list of strings, each string is a console command.
-    """
-    flash_img_cmd = ("fastboot -s %s flash %s "
-                     "{device-image[full-zipfile-dir]}/%s")
-    flash_gsi_cmd = ("fastboot --timeout=900 -s %s flash system "
-                     "{device-image[system.img]}")
-    result = [
-        flash_img_cmd % (serial, partition, image)
-        for partition, image in (
-            ("preloader", "preloader_SBOOT_DIS.img"),
-            ("loader_ext1", "loader_ext.img"),
-            ("loader_ext2", "loader_ext.img"),
-            ("tee1", "tee.img"),
-            ("tee2", "tee.img"),
-            ("lk", "lk.img"),
-            ("lk2", "lk.img"),
-        )
-    ]
-    result.append("fastboot -s %s -- reboot bootloader" % serial)
-    # gpt is the partition table and must be flashed first.
-    # The bootloader reloads partition table automatically after flashing gpt.
-    result += [
-        flash_img_cmd % (serial, partition, image)
-        for partition, image in (
-            ("gpt", "PGPT"),
-            ("md1img", "md1img.img"),
-            ("md1dsp", "md1dsp.img"),
-            ("recovery", "recovery.img"),
-            ("spmfw", "spmfw.img"),
-            ("mcupmfw", "mcupmfw.img"),
-            ("boot", "boot.img"),
-            ("dtbo", "dtbo.img"),
-            ("vendor", "vendor.img"),
-            ("cache", "cache.img"),
-            ("userdata", "userdata.img"),
-        )
-    ]
-
-    if gsi:
-        result.append(flash_gsi_cmd % serial)
-        result.append("fastboot -s %s -- -w" % serial)
-    else:
-        flash_img_cmd += " --timeout=900"
-        result.append(flash_img_cmd % (serial, "system", "system.img"))
-
-    result.append("fastboot -s %s reboot" % serial)
-    if not repacked_imageset:
-        result.append("sleep 300")  # wait for boot_complete (success)
-
-    return result
-
-
-def GenerateUniversal9810GsiFlashingCommands(serial,
-                                             gsi=False,
-                                             repacked_imageset=False):
-    """Returns a sequence of console commands to flash device imgs and GSI.
-
-    Args:
-        serial: string, the target device serial number.
-        gsi: bool, whether to flash GSI over vendor images or not.
-        repacked_imageset: bool, True if this func is called directly from
-                           the console, adjusts the resulting commands for
-                           atomic flashing process.
-
-    Returns:
-        a list of strings, each string is a console command.
-    """
-    result = [
-        ("fastboot -s %s flash el3_mon "
-         "{device-image[full-zipfile-dir]}/el3_mon.img" % serial),
-        ("fastboot -s %s flash epbl "
-         "{device-image[full-zipfile-dir]}/epbl.img" % serial),
-        ("fastboot -s %s flash bootloader "
-         "{device-image[full-zipfile-dir]}/u-boot.img" % serial),
-        ("fastboot -s %s flash dtb "
-         "{device-image[full-zipfile-dir]}/dtb.img" % serial),
-        ("fastboot -s %s flash dtbo "
-         "{device-image[full-zipfile-dir]}/dtbo.img" % serial),
-        ("fastboot -s %s flash kernel "
-         "{device-image[full-zipfile-dir]}/kernel.img" % serial),
-        ("fastboot -s %s flash ramdisk "
-         "{device-image[full-zipfile-dir]}/ramdisk.img" % serial),
-        ("fastboot -s %s flash vendor "
-         "{device-image[full-zipfile-dir]}/vendor.img -- -S 300M" % serial),
-    ]
-    if gsi:
-        result.append(("fastboot --timeout=900 -s %s flash system "
-                       "{device-image[system.img]} -- -S 512M" % serial))
-    else:
-        result.append((
-            "fastboot --timeout=900 -s %s flash system "
-            "{device-image[full-zipfile-dir]}/system.img -- -S 512M" % serial))
-    result.append("fastboot -s %s reboot -- -w" % serial)
-    if not repacked_imageset:
-        result.append("sleep 300")  # wait for boot_complete (success)
-
-    return result
-
-
-FLASH_COMMAND_EMITTER = {
-    common.K39TV1_BSP: GenerateMt6739GsiFlashingCommands,
-    common.K39TV1_BSP_1G: GenerateMt6739GsiFlashingCommands,
-    common.SDM845: GenerateSdm845GsiFlashingCommands,
-    common.UNIVERSAL9810: GenerateUniversal9810GsiFlashingCommands,
-}
diff --git a/harnesses/host_controller/campaigns/campaign_test.py b/harnesses/host_controller/campaigns/campaign_test.py
deleted file mode 100644
index ddb0c54..0000000
--- a/harnesses/host_controller/campaigns/campaign_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import unittest
-
-from host_controller.campaigns import cts
-from host_controller.campaigns import gts
-from host_controller.campaigns import sts
-from host_controller.campaigns import vts
-
-from host_controller.campaigns.testdata import default_testcase
-
-
-class CampaignTest(unittest.TestCase):
-    """Unit tests for the campaign generators."""
-
-    def setUp(self):
-        self.maxDiff = None
-
-    def testVtsBaseline(self):
-        """Tests the default device's vts scenario."""
-        test_name = "vts/vts"
-        results = vts.EmitConsoleCommands(
-            **default_testcase.GenerateInputData(test_name))
-        self.assertEqual(
-            default_testcase.GenerateOutputData(test_name), results)
-
-    def testCtsOnGsiBaseline(self):
-        """Tests the default device's vts scenario."""
-        test_name = "vts/cts-on-gsi"
-        results = vts.EmitConsoleCommands(
-            **default_testcase.GenerateInputData(test_name))
-        self.assertEqual(
-            default_testcase.GenerateOutputData(test_name), results)
-
-    def testCtsBaseline(self):
-        """Tests the default device's vts scenario."""
-        test_name = "cts/cts"
-        results = cts.EmitConsoleCommands(
-            **default_testcase.GenerateInputData(test_name))
-        self.assertEqual(
-            default_testcase.GenerateOutputData(test_name), results)
-
-    def testGtsBaseline(self):
-        """Tests the default device's vts scenario."""
-        test_name = "gts/gts"
-        results = gts.EmitConsoleCommands(
-            **default_testcase.GenerateInputData(test_name))
-        self.assertEqual(
-            default_testcase.GenerateOutputData(test_name), results)
-
-    def testStsBaseline(self):
-        """Tests the default device's vts scenario."""
-        test_name = "sts/sts"
-        results = sts.EmitConsoleCommands(
-            **default_testcase.GenerateInputData(test_name))
-        self.assertEqual(
-            default_testcase.GenerateOutputData(test_name), results)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/harnesses/host_controller/campaigns/cts.py b/harnesses/host_controller/campaigns/cts.py
deleted file mode 100644
index 28aa22d..0000000
--- a/harnesses/host_controller/campaigns/cts.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from host_controller.campaigns import campaign_common
-
-
-def EmitConsoleCommands(**kwargs):
-    """Runs a common CTS test.
-
-    This uses a given device branch information and automatically
-    selects a GSI branch and a test branch.
-    """
-    return campaign_common.EmitCommonConsoleCommands(**kwargs)
diff --git a/harnesses/host_controller/campaigns/gts.py b/harnesses/host_controller/campaigns/gts.py
deleted file mode 100644
index fec0eba..0000000
--- a/harnesses/host_controller/campaigns/gts.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from host_controller.campaigns import campaign_common
-
-
-def EmitConsoleCommands(**kwargs):
-  """Runs a common GTS test.
-
-  This uses a given device branch information and automatically
-  selects a GSI branch and a test branch.
-  """
-  return campaign_common.EmitCommonConsoleCommands(**kwargs)
diff --git a/harnesses/host_controller/campaigns/sts.py b/harnesses/host_controller/campaigns/sts.py
deleted file mode 100644
index 4850368..0000000
--- a/harnesses/host_controller/campaigns/sts.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from host_controller.campaigns import campaign_common
-
-
-def EmitConsoleCommands(**kwargs):
-  """Runs a common STS test.
-
-  This uses a given device branch information and automatically
-  selects a GSI branch and a test branch.
-  """
-  return campaign_common.EmitCommonConsoleCommands(**kwargs)
diff --git a/harnesses/host_controller/campaigns/testdata/__init__.py b/harnesses/host_controller/campaigns/testdata/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/campaigns/testdata/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/campaigns/testdata/default_testcase.py b/harnesses/host_controller/campaigns/testdata/default_testcase.py
deleted file mode 100644
index 9aeb91e..0000000
--- a/harnesses/host_controller/campaigns/testdata/default_testcase.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import copy
-
-# Based on JobModel defined in
-# test/vti/test_serving/gae/webapp/src/proto/model.py
-input_data = {
-    "test_type": 1,
-    "hostname": "my_hostname",
-    "priority": "low",
-    "test_name": "vts/vts",
-    "require_signed_device_build": True,
-    "has_bootloader_img": True,
-    "has_radio_img": True,
-    "device": "my_device",
-    "serial": ["my_serial1", "my_serial2", "my_serial3"],
-
-    # device image information
-    "build_storage_type": 1,
-    "manifest_branch": "my_branch",
-    "build_target": "my_build_target",
-    "build_id": "my_build_id",
-    "pab_account_id": "my_pab_account_id",
-    "shards": 3,
-    "param": "",
-    "status": 1,
-    "period": 24 * 60,  # 1 day
-
-    # GSI information
-    "gsi_storage_type": 1,
-    "gsi_branch": "my_gsi_branch",
-    "gsi_build_target": "my_gsi_build_target",
-    "gsi_build_id": "my_gsi_build_id",
-    "gsi_pab_account_id": "my_gsi_pab_account_id",
-    # gsi_vendor_version: "8.1.0"
-
-    # test suite information
-    "test_storage_type": 1,
-    "test_branch": "my_test_branch",
-    "test_build_target": "my_test_build_target",
-    "test_build_id": "my_test_build_id",
-    "test_pab_account_id": "my_test_pab_account_id",
-
-    #timestamp = ndb.DateTimeProperty(auto_now=False)
-    #heartbeat_stamp = ndb.DateTimeProperty(auto_now=False)
-    "retry_count": 3,
-    "infra_log_url": "infra_log_url",
-
-    #parent_schedule = ndb.KeyProperty(kind="ScheduleModel")
-    "image_package_repo_base": "image_package_repo_base",
-    "report_bucket": ["report_bucket"],
-    "report_spreadsheet_id": ["report_spreadsheet_id"],
-}
-
-expected_output = [
-    'device --set_serial=my_serial1,my_serial2,my_serial3 --from_job_pool --interval=300',
-    'fetch --type=pab --branch=my_branch --target=my_build_target --artifact_name=my_build_target-img-my_build_id.zip --build_id=my_build_id --account_id=my_pab_account_id --fetch_signed_build=True',
-    'fetch --type=pab --branch=my_branch --target=my_build_target --artifact_name=bootloader.img --build_id=my_build_id --account_id=my_pab_account_id',
-    'fetch --type=pab --branch=my_branch --target=my_build_target --artifact_name=radio.img --build_id=my_build_id --account_id=my_pab_account_id',
-    'fetch --type=pab --branch=my_gsi_branch --target=my_gsi_build_target --gsi=True --artifact_name=my_gsi_build_target-img-{build_id}.zip --build_id=my_gsi_build_id --account_id=my_gsi_pab_account_id',
-    'fetch --type=pab --branch=my_test_branch --target=my_test_build_target --artifact_name=android-{{test_suite}}.zip --build_id=my_test_build_id --account_id=my_test_pab_account_id',
-    'info', 'gsispl --version_from_path=boot.img', 'info',
-    [[
-        'flash --current --serial my_serial1 --skip-vbmeta=True ',
-        'adb -s my_serial1 root',
-        'dut --operation=wifi_on --serial=my_serial1 --ap=GoogleGuest',
-        'dut --operation=volume_mute --serial=my_serial1 --version=9.0'
-    ], [
-        'flash --current --serial my_serial2 --skip-vbmeta=True ',
-        'adb -s my_serial2 root',
-        'dut --operation=wifi_on --serial=my_serial2 --ap=GoogleGuest',
-        'dut --operation=volume_mute --serial=my_serial2 --version=9.0'
-    ], [
-        'flash --current --serial my_serial3 --skip-vbmeta=True ',
-        'adb -s my_serial3 root',
-        'dut --operation=wifi_on --serial=my_serial3 --ap=GoogleGuest',
-        'dut --operation=volume_mute --serial=my_serial3 --version=9.0'
-    ]],
-    'test --suite {{test_suite}} --keep-result -- {{test_plan}} --shards 3  --serial my_serial1 --serial my_serial2 --serial my_serial3',
-    'retry --suite {{test_suite}} --count 3 {{retry_plan}} --shards 3 --serial my_serial1 --serial my_serial2 --serial my_serial3{{cleanup_device}}',
-    'upload --src={result_full} --dest=report_bucket/{suite_plan}/{{test_plan}}/{branch}/{target}/my_build_target_{build_id}_{timestamp}/ --report_path=report_bucket/suite_result/{timestamp_year}/{timestamp_month}/{timestamp_day}',
-    'sheet --src {result_zip} --dest report_spreadsheet_id --extra_rows logs,report_bucket/{suite_plan}/{{test_plan}}/{branch}/{target}/my_build_target_{build_id}_{timestamp}/ --primary_abi_only --client_secrets DATA/vtslab-gcs.json',
-    'device --update=stop',
-]
-
-
-def GenerateInputData(test_name):
-    """Returns an input data dict for a given `test_name`."""
-    new_data = copy.copy(input_data)
-    new_data["test_name"] = test_name
-    return new_data
-
-
-def GenerateOutputData(test_name):
-    """Returns an output data list for a given `test_name`."""
-    test_suite, test_plan = test_name.split("/")
-
-    def ReplaceChars(line):
-        line = line.replace('{{test_suite}}', test_suite)
-        line = line.replace('{{test_plan}}', test_plan)
-        if test_plan != "cts-on-gsi":
-            line = line.replace(' --primary_abi_only', '')
-        if (test_suite == "cts" or test_suite == "gts" or test_suite == "sts"
-                or test_plan.startswith("cts-")):
-            line = line.replace('--shards', "--shard-count")
-            if test_suite == "vts":
-                line = line.replace('{{retry_plan}}',
-                                    '--retry_plan=%s-retry' % test_plan)
-            else:
-                line = line.replace('{{retry_plan}}', '--retry_plan=retry')
-            line = line.replace('{{cleanup_device}}',
-                                ' --cleanup_devices=True')
-        else:
-            line = line.replace('{{retry_plan}}', '')
-            line = line.replace('{{cleanup_device}}', '')
-        return line
-
-    def RecursivelyApply(input_list, func):
-        for number, item in enumerate(input_list):
-            if type(item) is list:
-                input_list[number] = RecursivelyApply(input_list[number], func)
-            elif type(item) is str:
-                input_list[number] = func(item)
-            else:
-                return None
-        return input_list
-
-    return RecursivelyApply(copy.copy(expected_output), ReplaceChars)
diff --git a/harnesses/host_controller/campaigns/vts.py b/harnesses/host_controller/campaigns/vts.py
deleted file mode 100644
index 0287455..0000000
--- a/harnesses/host_controller/campaigns/vts.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from host_controller.campaigns import campaign_common
-
-
-def EmitConsoleCommands(**kwargs):
-    """Runs a common VTS-on-GSI or CTS-on-GSI test.
-
-    This uses a given device branch information and automatically
-    selects a GSI branch and a test branch.
-    """
-    return campaign_common.EmitCommonConsoleCommands(**kwargs)
diff --git a/harnesses/host_controller/command_processor/__init__.py b/harnesses/host_controller/command_processor/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/command_processor/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/command_processor/base_command_processor.py b/harnesses/host_controller/command_processor/base_command_processor.py
deleted file mode 100644
index fa53f74..0000000
--- a/harnesses/host_controller/command_processor/base_command_processor.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import argparse
-import logging
-import re
-
-from host_controller import console_argument_parser
-
-# tmp_dir variable name.
-TMP_DIR_VAR ="{tmp_dir}"
-
-
-class BaseCommandProcessor(object):
-    '''Base class for command processors.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        arg_buffer: dict, stores last parsed argument, value pairs.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    '''
-
-    command = 'base'
-    command_detail = 'Command processor template'
-
-    def _SetUp(self, console):
-        '''Internal SetUp function that will call subclass' Setup function.
-
-        Args:
-            console: Console object.
-        '''
-        self.console = console
-        self.arg_buffer = {}
-        self.arg_parser = console_argument_parser.ConsoleArgumentParser(
-            self.command, self.command_detail)
-        self.SetUp()
-
-    def SetUp(self):
-        '''SetUp method for subclass to override.'''
-        pass
-
-    def _Run(self, arg_line):
-        '''Internal function that will call subclass' Run function.
-
-        Args:
-            arg_line: string, line of command arguments
-        '''
-        ret = self.Run(arg_line)
-        args = self.arg_parser.ParseLine(arg_line)
-        for arg_tuple in args._get_kwargs():
-            key = arg_tuple[0]
-            value = arg_tuple[1]
-            self.arg_buffer[key] = value
-
-        if ret is not None:
-            if ret == True:  # exit command executed.
-                return True
-            elif ret == False:
-                return False
-            else:
-                logging.warning("{} coommand returned {}".format(
-                    self.command, ret))
-
-    def Run(self, arg_line):
-        '''Run method to perform action when invoked from console.
-
-        Args:
-            arg_line: string, line of command
-        '''
-        pass
-
-    def _Help(self):
-        '''Internal function that will call subclass' Help function.'''
-        self.Help()
-
-    def Help(self):
-        '''Help method to print help informations.'''
-        if hasattr(self, 'arg_parser') and hasattr(self.console, '_out_file'):
-            self.arg_parser.print_help(self.console._out_file)
-
-    def _TearDown(self):
-        '''Internal function that will call subclass' TearDown function.'''
-        self.TearDown()
-
-    def TearDown(self):
-        '''TearDown tasks to be called when console is shutting down.'''
-        pass
-
-    def ReplaceVars(self, message_list):
-        """Replaces vars in a 'messsag_list' to their values."""
-        new_message_list = []
-        for message in message_list:
-            new_message = message
-
-            vars = re.findall(r"{device-image\[[^]]+\]}", message)
-            if vars:
-                for var in vars:
-                    var_name = var[len("{device-image")+1:-2]
-                    if var_name and var_name in self.console.device_image_info:
-                        new_message = new_message.replace(
-                                var, self.console.device_image_info[var_name])
-                    else:
-                        new_message = new_message.replace(var, "{undefined}")
-
-            vars = re.findall(r"{tools\[[^]]+\]}", message)
-            if vars:
-                for var in vars:
-                    var_name = var[len("{tools")+1:-2]
-                    if var_name and var_name in self.console.tools_info:
-                        new_message = new_message.replace(
-                            var, self.console.tools_info[var_name])
-                    else:
-                        new_message = new_message.replace(var, "{undefined}")
-
-            if TMP_DIR_VAR in new_message:
-                new_message = new_message.replace(
-                    TMP_DIR_VAR, self.console.tmpdir_default)
-
-            new_message_list.append(new_message)
-        return new_message_list
diff --git a/harnesses/host_controller/command_processor/command_acloud.py b/harnesses/host_controller/command_processor/command_acloud.py
deleted file mode 100644
index 42b377f..0000000
--- a/harnesses/host_controller/command_processor/command_acloud.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller.acloud import acloud_client
-from host_controller.command_processor import base_command_processor
-
-
-class CommandAcloud(base_command_processor.BaseCommandProcessor):
-    '''Command processor for acloud command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    '''
-
-    command = 'acloud'
-    command_detail = 'Create acloud instances.'
-
-    def Run(self, arg_line):
-        '''Creates an acloud instance and connects to it via adb.
-
-        Args:
-            arg_line: string, line of command arguments
-        '''
-        args = self.arg_parser.ParseLine(arg_line)
-
-        if args.provider == "ab":
-            if args.build_id.lower() == "latest":
-                build_id = self.console._build_provider["ab"].GetLatestBuildId(
-                    args.branch,
-                    args.target)
-        else:
-            # TODO(yuexima): support more provider types.
-            logging.error("Provider %s not supported yet." % args.provider)
-            return
-
-        ac = acloud_client.ACloudClient()
-        ac.PrepareConfig(args.config_path)
-        ac.CreateInstance(args.build_id)
-        ac.ConnectInstanceToAdb(ah.GetInstanceIP())
-
-    def SetUp(self):
-        """Initializes the parser for acloud command."""
-        self.arg_parser.add_argument(
-            "--build_id",
-            help="Build ID to use.")
-        self.arg_parser.add_argument(
-            "--provider",
-            default="ab",
-            choices=("local_fs", "gcs", "pab", "ab"),
-            help="Build provider type")
-        self.arg_parser.add_argument(
-            "--branch",  # not required for local_fs
-            help="Branch to grab the artifact from.")
-        self.arg_parser.add_argument(
-            "--target",  # not required for local_fs
-            help="Target product to grab the artifact from.")
-        self.arg_parser.add_argument(
-            "--config_path",
-            required=True,
-            help="Acloud config path.")
diff --git a/harnesses/host_controller/command_processor/command_adb.py b/harnesses/host_controller/command_processor/command_adb.py
deleted file mode 100644
index 1738820..0000000
--- a/harnesses/host_controller/command_processor/command_adb.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.usb import usb_utils
-
-from vts.utils.python.common import cmd_utils
-
-
-class CommandAdb(base_command_processor.BaseCommandProcessor):
-    """Command processor for adb command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "adb"
-    command_detail = "Runs an ADB command."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for device command."""
-        self.arg_parser.add_argument(
-            "--serial",
-            "-s",
-            default=None,
-            help="The target device serial to run the command.")
-        self.arg_parser.add_argument(
-            "--timeout",
-            type=float,
-            default=common.DEFAULT_DEVICE_TIMEOUT_SECS,
-            help="The maximum timeout value of this command in seconds. "
-            "Set to 0 to disable the timeout functionality.")
-        self.arg_parser.add_argument(
-            "command",
-            metavar="COMMAND",
-            nargs="+",
-            help="The command to be executed. If the command contains "
-            "arguments starting with \"-\", place the command at end of line "
-            "after \"--\".")
-
-    # @Override
-    def Run(self, arg_line):
-        """Runs an adb command."""
-        args = self.arg_parser.ParseLine(arg_line)
-        cmd_list = ["adb"]
-        if args.serial:
-            if "," in args.serial:
-                logging.error("Only one serial can be specified")
-                return False
-            cmd_list.append("-s %s" % args.serial)
-        cmd_list.extend(self.ReplaceVars(args.command))
-        if args.timeout == 0:
-            stdout, stderr, retcode = cmd_utils.ExecuteOneShellCommand(
-                " ".join(cmd_list))
-        else:
-            stdout, stderr, retcode = cmd_utils.ExecuteOneShellCommand(
-                " ".join(cmd_list), args.timeout,
-                usb_utils.ResetUsbDeviceOfSerial_Callback, args.serial)
-        if stdout:
-            logging.info(stdout)
-        if stderr:
-            logging.error(stderr)
-            if self.console.job_pool and args.serial:
-                self.console.device_status[
-                    args.serial] = common._DEVICE_STATUS_DICT["error"]
-        if retcode != 0:
-            return False
diff --git a/harnesses/host_controller/command_processor/command_build.py b/harnesses/host_controller/command_processor/command_build.py
deleted file mode 100644
index b1479d8..0000000
--- a/harnesses/host_controller/command_processor/command_build.py
+++ /dev/null
@@ -1,249 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import httplib2
-import logging
-import socket
-import threading
-import time
-
-from googleapiclient import errors
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.console_argument_parser import ConsoleArgumentError
-from host_controller.tradefed import remote_operation
-
-
-class CommandBuild(base_command_processor.BaseCommandProcessor):
-    """Command processor for build command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        build_thread: dict containing threading.Thread instances(s) that
-                      update build info regularly.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "build"
-    command_detail = "Specifies branches and targets to monitor."
-
-    def UpdateBuild(self, account_id, branch, targets, artifact_type, method,
-                    userinfo_file, noauth_local_webserver, verify_signed):
-        """Updates the build state.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-            artifact_type: string, artifact type (`device`, 'gsi' or `test').
-            method: string,  method for getting build information.
-            userinfo_file: string, the path of a file containing email and
-                           password (if method == POST).
-            noauth_local_webserver: boolean, True to not use a local websever.
-            verify_signed: A Boolean indicating whether to verify signed build.
-        """
-        builds = []
-
-        self.console._build_provider["pab"].Authenticate(
-            userinfo_file=userinfo_file,
-            noauth_local_webserver=noauth_local_webserver)
-        for target in targets.split(","):
-            try:
-                listed_builds = self.console._build_provider["pab"].GetBuildList(
-                    account_id=account_id,
-                    branch=branch,
-                    target=target,
-                    page_token="",
-                    max_results=100,
-                    method=method,
-                    verify_signed=verify_signed)
-            except ValueError as e:
-                logging.exception(e)
-                continue
-
-            for listed_build in listed_builds:
-                if method == "GET":
-                    if "successful" in listed_build:
-                        if listed_build["successful"]:
-                            build = {}
-                            build["manifest_branch"] = branch
-                            build["build_id"] = listed_build["build_id"]
-                            if "-" in target:
-                                build["build_target"], build[
-                                    "build_type"] = target.split("-")
-                            else:
-                                build["build_target"] = target
-                                build["build_type"] = ""
-                            build["artifact_type"] = artifact_type
-                            build["artifacts"] = []
-                            if "signed" in listed_build:
-                                build["signed"] = listed_build["signed"]
-                            else:
-                                build["signed"] = False
-                            builds.append(build)
-                    else:
-                        logging.error("Error: listed_build %s", listed_build)
-                else:  # POST
-                    build = {}
-                    build["manifest_branch"] = branch
-                    build["build_id"] = listed_build[u"1"]
-                    if "-" in target:
-                        (build["build_target"],
-                         build["build_type"]) = target.split("-")
-                    else:
-                        build["build_target"] = target
-                        build["build_type"] = ""
-                    build["artifact_type"] = artifact_type
-                    build["artifacts"] = []
-                    build["signed"] = False
-                    builds.append(build)
-        self.console._vti_endpoint_client.UploadBuildInfo(builds)
-
-    def UpdateBuildLoop(self, account_id, branch, target, artifact_type,
-                        method, userinfo_file, noauth_local_webserver,
-                        update_interval, verify_signed):
-        """Regularly updates the build information.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-            artifact_type: string, artifcat type (`device`, 'gsi' or `test).
-            method: string,  method for getting build information.
-            userinfo_file: string, the path of a file containing email and
-                           password (if method == POST).
-            noauth_local_webserver: boolean, True to not use a local websever.
-            update_interval: int, number of seconds before repeating
-        """
-        thread = threading.currentThread()
-        while getattr(thread, 'keep_running', True):
-            try:
-                self.UpdateBuild(account_id, branch, target, artifact_type,
-                                 method, userinfo_file, noauth_local_webserver,
-                                 verify_signed)
-            except (socket.error, remote_operation.RemoteOperationException,
-                    httplib2.HttpLib2Error, errors.HttpError) as e:
-                logging.exception(e)
-            time.sleep(update_interval)
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for build command."""
-        self.build_thread = {}
-        self.arg_parser.add_argument(
-            "--update",
-            choices=("single", "start", "stop", "list"),
-            default="start",
-            help="Update build info")
-        self.arg_parser.add_argument(
-            "--id",
-            default=None,
-            help="session ID only required for 'stop' update command")
-        self.arg_parser.add_argument(
-            "--interval",
-            type=int,
-            default=30,
-            help="Interval (seconds) to repeat build update.")
-        self.arg_parser.add_argument(
-            "--artifact-type",
-            choices=("device", "gsi", "test"),
-            default="device",
-            help="The type of an artifact to update")
-        self.arg_parser.add_argument(
-            "--branch",
-            required=True,
-            help="Branch to grab the artifact from.")
-        self.arg_parser.add_argument(
-            "--target",
-            required=True,
-            help="a comma-separate list of build target product(s).")
-        self.arg_parser.add_argument(
-            "--account_id",
-            default=common._DEFAULT_ACCOUNT_ID,
-            help="Partner Android Build account_id to use.")
-        self.arg_parser.add_argument(
-            "--method",
-            default="GET",
-            choices=("GET", "POST"),
-            help="Method for getting build information")
-        self.arg_parser.add_argument(
-            "--userinfo-file",
-            help=
-            "Location of file containing email and password, if using POST.")
-        self.arg_parser.add_argument(
-            "--noauth_local_webserver",
-            default=False,
-            type=bool,
-            help="True to not use a local webserver for authentication.")
-        self.arg_parser.add_argument(
-            "--verify-signed-build",
-            default=False,
-            type=bool,
-            help="True to verify whether the build is signed.")
-    # @Override
-    def Run(self, arg_line):
-        """Updates build info."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.update == "single":
-            self.UpdateBuild(args.account_id, args.branch, args.target,
-                             args.artifact_type, args.method,
-                             args.userinfo_file, args.noauth_local_webserver,
-                             args.verify_signed_build)
-        elif args.update == "list":
-            logging.info("Running build update sessions:")
-            for id in self.build_thread:
-                logging.info("  ID %d", id)
-        elif args.update == "start":
-            if args.interval <= 0:
-                raise ConsoleArgumentError("update interval must be positive")
-            # do not allow user to create new
-            # thread if one is currently running
-            if args.id is None:
-                if not self.build_thread:
-                    args.id = 1
-                else:
-                    args.id = max(self.build_thread) + 1
-            else:
-                args.id = int(args.id)
-            if args.id in self.build_thread and not hasattr(
-                    self.build_thread[args.id], 'keep_running'):
-                logging.warning(
-                    'build update (session ID: %s) already running. '
-                    'run build --update stop first.', args.id)
-                return
-            self.build_thread[args.id] = threading.Thread(
-                target=self.UpdateBuildLoop,
-                args=(
-                    args.account_id,
-                    args.branch,
-                    args.target,
-                    args.artifact_type,
-                    args.method,
-                    args.userinfo_file,
-                    args.noauth_local_webserver,
-                    args.interval,
-                    args.verify_signed_build,
-                ))
-            self.build_thread[args.id].daemon = True
-            self.build_thread[args.id].start()
-        elif args.update == "stop":
-            if args.id is None:
-                logging.error("--id must be set for stop")
-            else:
-                self.build_thread[int(args.id)].keep_running = False
diff --git a/harnesses/host_controller/command_processor/command_config.py b/harnesses/host_controller/command_processor/command_config.py
deleted file mode 100644
index a8b1a24..0000000
--- a/harnesses/host_controller/command_processor/command_config.py
+++ /dev/null
@@ -1,440 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import httplib2
-import itertools
-import logging
-import os
-import socket
-import threading
-import time
-
-from googleapiclient import errors
-from google.protobuf import text_format
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.console_argument_parser import ConsoleArgumentError
-from host_controller.tradefed import remote_operation
-
-from vti.test_serving.proto import TestLabConfigMessage_pb2 as LabCfgMsg
-from vti.test_serving.proto import TestScheduleConfigMessage_pb2 as SchedCfgMsg
-
-
-class CommandConfig(base_command_processor.BaseCommandProcessor):
-    """Command processor for config command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-        schedule_thread: dict containing threading.Thread instances(s) that
-                         update schedule info regularly.
-    """
-
-    command = "config"
-    command_detail = "Specifies a global config type to monitor."
-
-    def UpdateConfig(self, account_id, branch, targets, config_type, method,
-                     update_build, clear_schedule, clear_labinfo):
-        """Updates the global configuration data.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-            config_type: string, config type (`prod` or `test').
-            method: string, HTTP method for fetching.
-            update_build: boolean, indicating whether to upload build info.
-            clear_schedule: bool, True to clear all schedule data exist on the
-                            scheduler
-            clear_labinfo: bool, True to clear all lab data exist on the
-                           scheduler
-        """
-        for target in targets.split(","):
-            fetch_path = self.FetchConfig(
-                account_id=account_id,
-                branch=branch,
-                target=target,
-                config_type=config_type,
-                method=method)
-            if fetch_path:
-                self.UploadConfig(
-                    path=fetch_path,
-                    update_build=update_build,
-                    clear_schedule=clear_schedule,
-                    clear_labinfo=clear_labinfo)
-
-    def FetchConfig(self, account_id, branch, target, config_type, method):
-        """Fetches config files from the PAB build provider.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            target: string, build target.
-            config_type: string, config type (`prod` or `test').
-            method: string, HTTP method for fetching.
-
-        Returns:
-            string, a path to the temp directory where config files are stored.
-        """
-        path = ""
-        self.console._build_provider["pab"].Authenticate()
-        try:
-            listed_builds = self.console._build_provider["pab"].GetBuildList(
-                account_id=account_id,
-                branch=branch,
-                target=target,
-                page_token="",
-                max_results=1,
-                method="GET")
-        except ValueError as e:
-            logging.exception(e)
-            return path
-
-        if listed_builds and len(listed_builds) > 0:
-            listed_build = listed_builds[0]
-            if listed_build["successful"]:
-                device_images, test_suites, artifacts, configs = (
-                    self.console._build_provider["pab"].GetArtifact(
-                        account_id=account_id,
-                        branch=branch,
-                        target=target,
-                        artifact_name=(
-                            "vti-global-config-%s.zip" % config_type),
-                        build_id=listed_build["build_id"],
-                        method=method))
-                path = os.path.dirname(configs[config_type])
-
-        return path
-
-    def UploadConfig(self, path, update_build, clear_schedule, clear_labinfo):
-        """Uploads configs to VTI server.
-
-        Args:
-            path: string, a path where config files are stored.
-            update_build: boolean, indicating whether to upload build info.
-            clear_schedule: bool, True to clear all schedule data exist on the
-                            scheduler
-            clear_labinfo: bool, True to clear all lab data exist on the
-                           scheduler
-        """
-        schedules_pbs = []
-        lab_pbs = []
-        for root, dirs, files in os.walk(path):
-            for config_file in files:
-                full_path = os.path.join(root, config_file)
-                try:
-                    if config_file.endswith(".schedule_config"):
-                        with open(full_path, "r") as fd:
-                            context = fd.read()
-                            sched_cfg_msg = SchedCfgMsg.ScheduleConfigMessage()
-                            text_format.Merge(context, sched_cfg_msg)
-                            schedules_pbs.append(sched_cfg_msg)
-                            logging.info(sched_cfg_msg.manifest_branch)
-                    elif config_file.endswith(".lab_config"):
-                        with open(full_path, "r") as fd:
-                            context = fd.read()
-                            lab_cfg_msg = LabCfgMsg.LabConfigMessage()
-                            text_format.Merge(context, lab_cfg_msg)
-                            lab_pbs.append(lab_cfg_msg)
-                except text_format.ParseError as e:
-                    logging.error("ERROR: Config parsing error %s", e)
-        if update_build:
-            commands = self.GetBuildCommands(schedules_pbs)
-            if commands:
-                for command in commands:
-                    ret = self.console.onecmd(command)
-                    if ret == False:
-                        break
-        self.console._vti_endpoint_client.UploadScheduleInfo(
-            schedules_pbs, clear_schedule)
-        self.console._vti_endpoint_client.UploadLabInfo(lab_pbs, clear_labinfo)
-
-    def UpdateConfigLoop(self, account_id, branch, target, config_type, method,
-                         update_build, update_interval, clear_schedule,
-                         clear_labinfo):
-        """Regularly updates the global configuration.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-            config_type: string, config type (`prod` or `test').
-            method: string, HTTP method for fetching.
-            update_build: boolean, indicating whether to upload build info.
-            update_interval: int, number of seconds before repeating
-            clear_schedule: bool, True to clear all schedule data exist on the
-                            scheduler
-            clear_labinfo: bool, True to clear all lab data exist on the
-                           scheduler
-        """
-        thread = threading.currentThread()
-        while getattr(thread, 'keep_running', True):
-            try:
-                self.UpdateConfig(account_id, branch, target, config_type,
-                                  method, update_build, clear_schedule,
-                                  clear_labinfo)
-            except (socket.error, remote_operation.RemoteOperationException,
-                    httplib2.HttpLib2Error, errors.HttpError) as e:
-                logging.exception(e)
-            time.sleep(update_interval)
-
-    def GetBuildCommands(self, schedule_pbs):
-        """Generates a list of build commands with given schedules.
-
-        Args:
-            schedule_pbs: a list of TestScheduleConfig protobuf messages.
-
-        Returns:
-            a list of build command strings
-        """
-        attrs = {}
-        attrs["device"] = [
-            "build_storage_type", "manifest_branch", "pab_account_id",
-            "require_signed_device_build", "name"
-        ]
-        attrs["gsi"] = [
-            "gsi_storage_type", "gsi_branch", "gsi_pab_account_id",
-            "gsi_build_target"
-        ]
-        attrs["test"] = [
-            "test_storage_type", "test_branch", "test_pab_account_id",
-            "test_build_target"
-        ]
-
-        class BuildInfo(object):
-            """A build information class."""
-
-            def __init__(self, _build_type):
-                if _build_type in attrs:
-                    for attribute in attrs[_build_type]:
-                        setattr(self, attribute, "")
-
-            def __eq__(self, compare):
-                return self.__dict__ == compare.__dict__
-
-        build_commands = []
-        if not schedule_pbs:
-            return build_commands
-
-        # parses the given protobuf and stores as BuildInfo object.
-        builds = {"device": [], "gsi": [], "test": []}
-        for pb in schedule_pbs:
-            for build_target in pb.build_target:
-                build_type = "device"
-                device = BuildInfo(build_type)
-                for attr in attrs[build_type]:
-                    if hasattr(pb, attr):
-                        setattr(device, attr, getattr(pb, attr, None))
-                    elif hasattr(build_target, attr):
-                        setattr(device, attr, getattr(build_target, attr,
-                                                      None))
-                if not [x for x in builds[build_type] if x == device]:
-                    builds[build_type].append(device)
-                for test_schedule in build_target.test_schedule:
-                    build_type = "gsi"
-                    gsi = BuildInfo(build_type)
-                    for attr in attrs[build_type]:
-                        if hasattr(test_schedule, attr):
-                            setattr(gsi, attr,
-                                    getattr(test_schedule, attr, None))
-                    if not [x for x in builds[build_type] if x == gsi]:
-                        builds[build_type].append(gsi)
-
-                    build_type = "test"
-                    test = BuildInfo(build_type)
-                    for attr in attrs[build_type]:
-                        if hasattr(test_schedule, attr):
-                            setattr(test, attr,
-                                    getattr(test_schedule, attr, None))
-                    if not [x for x in builds[build_type] if x == test]:
-                        builds[build_type].append(test)
-
-        # groups by artifact, branch, and account id, and builds a command.
-        for artifact in attrs:
-            load_attrs = attrs[artifact]
-            if artifact == "device":
-                storage_type_text = "build_storage_type"
-            else:
-                storage_type_text = "" + artifact + "_storage_type"
-            pab_builds = [
-                x for x in builds[artifact]
-                if getattr(x, storage_type_text) ==
-                SchedCfgMsg.BUILD_STORAGE_TYPE_PAB
-            ]
-            pab_builds.sort(key=lambda x: tuple([getattr(x, attribute)
-                                                 for attribute in load_attrs]))
-            groups = [list(g) for k, g in itertools.groupby(
-                pab_builds, lambda x: tuple([getattr(x, attribute)
-                                             for attribute
-                                             in load_attrs[1:-1]]))]
-            for group in groups:
-                command = ("build --artifact-type={} --method=GET "
-                           "--noauth_local_webserver=True --update=single".
-                           format(artifact))
-                if artifact == "device":
-                    if group[0].manifest_branch:
-                        command += " --branch={}".format(
-                            group[0].manifest_branch)
-                    else:
-                        logging.debug(
-                            "Device manifest branch is a mandatory field.")
-                        continue
-                    if group[0].pab_account_id:
-                        command += " --account_id={}".format(
-                            group[0].pab_account_id)
-                    if group[0].require_signed_device_build:
-                        command += " --verify-signed-build=True"
-                    targets = ",".join([x.name for x in group if x.name])
-                    if targets:
-                        command += " --target={}".format(targets)
-                        build_commands.append(command)
-                else:
-                    if getattr(group[0], "" + artifact + "_branch"):
-                        command += " --branch={}".format(
-                            getattr(group[0], "" + artifact + "_branch"))
-                    else:
-                        logging.debug(
-                            "{} branch is a mandatory field.".format(artifact))
-                        continue
-                    if getattr(group[0], "" + artifact + "_pab_account_id"):
-                        command += " --account_id={}".format(
-                            getattr(group[0],
-                                    "" + artifact + "_pab_account_id"))
-                    targets = ",".join([
-                        getattr(x, "" + artifact + "_build_target")
-                        for x in group
-                        if getattr(x, "" + artifact + "_build_target")
-                    ])
-                    if targets:
-                        command += " --target={}".format(targets)
-                        build_commands.append(command)
-
-        return build_commands
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for config command."""
-        self.schedule_thread = {}
-        self.arg_parser.add_argument(
-            "--update",
-            choices=("single", "start", "stop", "list"),
-            default="start",
-            help="Update build info")
-        self.arg_parser.add_argument(
-            "--id",
-            default=None,
-            help="session ID only required for 'stop' update command")
-        self.arg_parser.add_argument(
-            "--interval",
-            type=int,
-            default=60,
-            help="Interval (seconds) to repeat build update.")
-        self.arg_parser.add_argument(
-            "--config-type",
-            choices=("prod", "test"),
-            default="prod",
-            help="Whether it's for prod")
-        self.arg_parser.add_argument(
-            "--branch",
-            required=True,
-            help="Branch to grab the artifact from.")
-        self.arg_parser.add_argument(
-            "--target",
-            required=True,
-            help="a comma-separate list of build target product(s).")
-        self.arg_parser.add_argument(
-            "--account_id",
-            default=common._DEFAULT_ACCOUNT_ID,
-            help="Partner Android Build account_id to use.")
-        self.arg_parser.add_argument(
-            '--method',
-            default='GET',
-            choices=('GET', 'POST'),
-            help='Method for fetching')
-        self.arg_parser.add_argument(
-            '--update_build',
-            dest='update_build',
-            action='store_true',
-            help='A boolean value indicating whether to upload build info.')
-        self.arg_parser.add_argument(
-            "--clear_schedule",
-            default=False,
-            help="True to clear all schedule data on the scheduler cloud")
-        self.arg_parser.add_argument(
-            "--clear_labinfo",
-            default=False,
-            help="True to clear all lab info data on the scheduler cloud")
-
-    # @Override
-    def Run(self, arg_line):
-        """Updates global config."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.update == "single":
-            self.UpdateConfig(args.account_id, args.branch, args.target,
-                              args.config_type, args.method, args.update_build,
-                              args.clear_schedule, args.clear_labinfo)
-        elif args.update == "list":
-            logging.info("Running config update sessions:")
-            for id in self.schedule_thread:
-                logging.info("  ID %d", id)
-        elif args.update == "start":
-            if args.interval <= 0:
-                raise ConsoleArgumentError("update interval must be positive")
-            # do not allow user to create new
-            # thread if one is currently running
-            if args.id is None:
-                if not self.schedule_thread:
-                    args.id = 1
-                else:
-                    args.id = max(self.schedule_thread) + 1
-            else:
-                args.id = int(args.id)
-            if args.id in self.schedule_thread and not hasattr(
-                    self.schedule_thread[args.id], 'keep_running'):
-                logging.warning('config update already running. '
-                                'run config --update=stop --id=%s first.',
-                                args.id)
-                return
-            self.schedule_thread[args.id] = threading.Thread(
-                target=self.UpdateConfigLoop,
-                args=(
-                    args.account_id,
-                    args.branch,
-                    args.target,
-                    args.config_type,
-                    args.method,
-                    args.update_build,
-                    args.interval,
-                    args.clear_schedule,
-                    args.clear_labinfo,
-                ))
-            self.schedule_thread[args.id].daemon = True
-            self.schedule_thread[args.id].start()
-        elif args.update == "stop":
-            if args.id is None:
-                logging.error("--id must be set for stop")
-            else:
-                self.schedule_thread[int(args.id)].keep_running = False
-
-    def Help(self):
-        base_command_processor.BaseCommandProcessor.Help(self)
-        logging.info("Sample: config --branch=<branch name> "
-                     "--target=<build target> "
-                     "--account_id=<account id> --config-type=[prod|test] "
-                     "--update=single")
diff --git a/harnesses/host_controller/command_processor/command_config_local.py b/harnesses/host_controller/command_processor/command_config_local.py
deleted file mode 100644
index 6c6e5e0..0000000
--- a/harnesses/host_controller/command_processor/command_config_local.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import httplib2
-import logging
-import socket
-import threading
-import time
-
-from googleapiclient import errors
-
-from host_controller.command_processor import base_command_processor
-from host_controller.command_processor import command_config
-from host_controller.console_argument_parser import ConsoleArgumentError
-from host_controller.tradefed import remote_operation
-
-
-class CommandConfigLocal(command_config.CommandConfig):
-    """Command processor for config-local command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-        schedule_thread: dict containing threading.Thread instances(s) that
-                         update schedule info regularly.
-    """
-
-    command = "config_local"
-    command_detail = "Uploads configs from local path."
-
-    # @Override
-    def UpdateConfig(self, path, update_build, clear_schedule, clear_labinfo):
-        """Updates the global configuration data.
-
-        Args:
-            path: string, a path where config files are stored.
-            update_build: boolean, indicating whether to upload build info.
-        """
-        if path:
-            self.UploadConfig(
-                path=path,
-                update_build=update_build,
-                clear_schedule=clear_schedule,
-                clear_labinfo=clear_labinfo)
-
-    # @Override
-    def UpdateConfigLoop(self, path, update_build, update_interval,
-                         clear_schedule, clear_labinfo):
-        """Regularly updates the global configuration.
-
-        Args:
-            path: string, a path where config files are stored.
-            update_build: boolean, indicating whether to upload build info.
-            update_interval: int, number of seconds before repeating
-        """
-        thread = threading.currentThread()
-        while getattr(thread, 'keep_running', True):
-            try:
-                self.UpdateConfig(path, update_build, clear_schedule,
-                                  clear_labinfo)
-            except (socket.error, remote_operation.RemoteOperationException,
-                    httplib2.HttpLib2Error, errors.HttpError) as e:
-                logging.exception(e)
-            time.sleep(update_interval)
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for config command."""
-        self.schedule_thread = {}
-        self.arg_parser.add_argument(
-            "--update",
-            choices=("single", "start", "stop", "list"),
-            default="single",
-            help="Update build info")
-        self.arg_parser.add_argument(
-            "--id",
-            default=None,
-            help="session ID only required for 'stop' update command")
-        self.arg_parser.add_argument(
-            "--interval",
-            type=int,
-            default=60,
-            help="Interval (seconds) to repeat build update.")
-        self.arg_parser.add_argument(
-            "--path",
-            required=True,
-            help="A path where config files are stored.")
-        self.arg_parser.add_argument(
-            '--update_build',
-            dest='update_build',
-            action='store_true',
-            help='A boolean value indicating whether to upload build info.')
-        self.arg_parser.add_argument(
-            "--clear_schedule",
-            default=False,
-            help="True to clear all schedule data on the scheduler cloud")
-        self.arg_parser.add_argument(
-            "--clear_labinfo",
-            default=False,
-            help="True to clear all lab info data on the scheduler cloud")
-
-    # @Override
-    def Run(self, arg_line):
-        """Updates global config."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.update == "single":
-            self.UpdateConfig(args.path, args.update_build,
-                              args.clear_schedule, args.clear_labinfo)
-        elif args.update == "list":
-            logging.info("Running config update sessions:")
-            for id in self.schedule_thread:
-                logging.info("  ID %d", id)
-        elif args.update == "start":
-            if args.interval <= 0:
-                raise ConsoleArgumentError("update interval must be positive")
-            # do not allow user to create new
-            # thread if one is currently running
-            if args.id is None:
-                if not self.schedule_thread:
-                    args.id = 1
-                else:
-                    args.id = max(self.schedule_thread) + 1
-            else:
-                args.id = int(args.id)
-            if args.id in self.schedule_thread and not hasattr(
-                    self.schedule_thread[args.id], 'keep_running'):
-                logging.warning(
-                    'config update already running. '
-                    'run config-local --update=stop --id=%s first.', args.id)
-                return
-            self.schedule_thread[args.id] = threading.Thread(
-                target=self.UpdateConfigLoop,
-                args=(
-                    args.path,
-                    args.update_build,
-                    args.interval,
-                    args.clear_schedule,
-                    args.clear_labinfo,
-                ))
-            self.schedule_thread[args.id].daemon = True
-            self.schedule_thread[args.id].start()
-        elif args.update == "stop":
-            if args.id is None:
-                logging.error("--id must be set for stop")
-            else:
-                self.schedule_thread[int(args.id)].keep_running = False
-
-    def Help(self):
-        base_command_processor.BaseCommandProcessor.Help(self)
-        logging.info("Sample: config-local --path=/usr/local/home/config/prod "
-                     "--update=single --update_build")
diff --git a/harnesses/host_controller/command_processor/command_copy.py b/harnesses/host_controller/command_processor/command_copy.py
deleted file mode 100644
index 880e55e..0000000
--- a/harnesses/host_controller/command_processor/command_copy.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-import shutil
-
-from host_controller.command_processor import base_command_processor
-
-
-class CommandCopy(base_command_processor.BaseCommandProcessor):
-    """Command processor for copy command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "copy"
-    command_detail = "Copy a file."
-
-    # @Override
-    def Run(self, arg_line):
-        """Copy a file from source to destination path."""
-        src, dst = arg_line.split()
-        if dst == "{vts_tf_home}":
-            dst = os.path.dirname(self.console.test_suite_info["vts"])
-        elif "{" in dst:
-            logging.error("unknown dst %s", dst)
-            return
-        shutil.copy(src, dst)
\ No newline at end of file
diff --git a/harnesses/host_controller/command_processor/command_device.py b/harnesses/host_controller/command_processor/command_device.py
deleted file mode 100644
index 32d51dd..0000000
--- a/harnesses/host_controller/command_processor/command_device.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import httplib2
-import logging
-import socket
-import threading
-import time
-
-from googleapiclient import errors
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.console_argument_parser import ConsoleArgumentError
-from host_controller.tradefed import remote_operation
-from host_controller.utils.usb import usb_utils
-
-from vts.utils.python.common import cmd_utils
-
-
-class CommandDevice(base_command_processor.BaseCommandProcessor):
-    """Command processor for Device command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-        update_thread: threading.Thread that updates device state regularly.
-    """
-
-    command = "device"
-    command_detail = "Selects device(s) under test."
-
-    def UpdateDevice(self,
-                     server_type,
-                     host,
-                     lease,
-                     suppress_lock_warning=True,
-                     from_job_pool=False):
-        """Updates the device state of all devices on a given host.
-
-        Args:
-            server_type: string, the type of a test secheduling server.
-            host: HostController object
-            lease: boolean, True to lease and execute jobs.
-            suppress_lock_warning: bool, True to suppress the warning msg from
-                                   file_lock.
-            from_job_pool: bool, True if the 'device' command is executed from
-                           one of the job pool processes. Checks only
-                           the availability of the devices when set.
-        """
-        if server_type == "vti":
-            devices = []
-
-            if from_job_pool:
-                devices_dict = {}
-                for serial in self.console.GetSerials():
-                    device = {}
-                    device["serial"] = serial
-                    device["status"] = common._DEVICE_STATUS_DICT[
-                        "no-response"]
-                    device["product"] = "error"
-                    devices_dict[serial] = device
-
-            stdout, stderr, returncode = cmd_utils.ExecuteOneShellCommand(
-                "adb devices")
-            lines_adb = stdout.split("\n")
-            stdout, stderr, returncode = cmd_utils.ExecuteOneShellCommand(
-                "fastboot devices")
-            lines_fastboot = stdout.split("\n")
-
-            for line in lines_adb:
-                if (len(line.strip()) and not (line.startswith("* ")
-                                               or line.startswith("List "))):
-                    device = {}
-                    device["serial"] = line.split()[0]
-                    serial = device["serial"]
-
-                    if from_job_pool:
-                        if (serial in devices_dict
-                                and line.split()[1] == "device"):
-                            devices_dict[serial][
-                                "status"] = common._DEVICE_STATUS_DICT[
-                                    "online"]
-                            product = (self.console._vti_endpoint_client.
-                                       GetJobDeviceProductName())
-                            if product:
-                                devices_dict[serial]["product"] = product
-                        continue
-
-                    if self.console.file_lock.LockDevice(
-                            serial, suppress_lock_warning) == False:
-                        self.console.device_status[
-                            serial] = common._DEVICE_STATUS_DICT["use"]
-                        if not suppress_lock_warning:
-                            logging.info("Device %s already locked." % serial)
-                        continue
-
-                    stdout, _, retcode = cmd_utils.ExecuteOneShellCommand(
-                        "adb -s %s reboot bootloader" % device["serial"],
-                        common.DEFAULT_DEVICE_TIMEOUT_SECS,
-                        usb_utils.ResetUsbDeviceOfSerial_Callback,
-                        device["serial"])
-                    if retcode == 0:
-                        lines_fastboot.append(line)
-
-                    self.console.file_lock.UnlockDevice(serial)
-
-            for line in lines_fastboot:
-                if len(line.strip()):
-                    device = {}
-                    device["serial"] = line.split()[0]
-                    serial = device["serial"]
-
-                    if from_job_pool:
-                        if serial in devices_dict:
-                            devices_dict[serial][
-                                "status"] = common._DEVICE_STATUS_DICT[
-                                    "fastboot"]
-                            product = (self.console._vti_endpoint_client.
-                                       GetJobDeviceProductName())
-                            if product:
-                                devices_dict[serial]["product"] = product
-                        continue
-
-                    if self.console.file_lock.LockDevice(
-                            serial, suppress_lock_warning) == False:
-                        self.console.device_status[
-                            serial] = common._DEVICE_STATUS_DICT["use"]
-                        if not suppress_lock_warning:
-                            logging.info("Device %s already locked." % serial)
-                        continue
-
-                    _, stderr, retcode = cmd_utils.ExecuteOneShellCommand(
-                        "fastboot -s %s getvar product" % device["serial"],
-                        common.DEFAULT_DEVICE_TIMEOUT_SECS,
-                        usb_utils.ResetUsbDeviceOfSerial_Callback,
-                        device["serial"])
-                    if retcode == 0:
-                        res = stderr.splitlines()[0].rstrip()
-                        if ":" in res:
-                            device["product"] = res.split(":")[1].strip()
-                        elif "waiting for %s" % serial in res:
-                            res = stderr.splitlines()[1].rstrip()
-                            device["product"] = res.split(":")[1].strip()
-                        else:
-                            device["product"] = "error"
-                        self.console.device_status[
-                            serial] = common._DEVICE_STATUS_DICT["fastboot"]
-                    else:
-                        device["product"] = "error"
-                        self.console.device_status[
-                            serial] = common._DEVICE_STATUS_DICT["no-response"]
-
-                    device["status"] = self.console.device_status[serial]
-                    devices.append(device)
-
-                    self.console.file_lock.UnlockDevice(serial)
-
-            if from_job_pool:
-                devices = devices_dict.values()
-                if devices:
-                    self.console._vti_endpoint_client.UploadDeviceInfo(
-                        host.hostname, devices)
-                return
-
-            self.console._vti_endpoint_client.UploadDeviceInfo(
-                host.hostname, devices)
-
-            if lease:
-                self.console._job_in_queue.put("lease")
-
-            if self.console.vtslab_version:
-                self.console._vti_endpoint_client.UploadHostVersion(
-                    host.hostname, self.console.vtslab_version)
-        elif server_type == "tfc":
-            devices = host.ListDevices()
-            for device in devices:
-                device.Extend(['sim_state', 'sim_operator', 'mac_address'])
-            snapshots = self.console._tfc_client.CreateDeviceSnapshot(
-                host._cluster_ids[0], host.hostname, devices)
-            self.console._tfc_client.SubmitHostEvents([snapshots])
-        else:
-            logging.error("Error: unknown server_type %s for UpdateDevice",
-                          server_type)
-
-    def UpdateDeviceRepeat(self,
-                           server_type,
-                           host,
-                           lease,
-                           update_interval,
-                           suppress_lock_warning=True,
-                           from_job_pool=False):
-        """Regularly updates the device state of devices on a given host.
-
-        Args:
-            server_type: string, the type of a test secheduling server.
-            host: HostController object
-            lease: boolean, True to lease and execute jobs.
-            update_interval: int, number of seconds before repeating
-            suppress_lock_warning: bool, True to suppress the warning msg from
-                                   file_lock.
-            from_job_pool: bool, True if the 'device' command is executed form
-                           one of the job pool processes.
-        """
-        thread = threading.currentThread()
-        while getattr(thread, 'keep_running', True):
-            try:
-                self.UpdateDevice(server_type, host, lease,
-                                  suppress_lock_warning, from_job_pool)
-            except (socket.error, remote_operation.RemoteOperationException,
-                    httplib2.HttpLib2Error, errors.HttpError) as e:
-                logging.exception(e)
-            time.sleep(update_interval)
-
-    def RunUSBResetTimer(self, serial, interval):
-        """Sets up a timer to run the target function after 'interval' secs.
-
-        Args:
-            serial: string, serial number of the device whose USB device file
-                    will reset when the timeout happens.
-            interval: int, sets up the timer for the target function to be
-                      executed after 'interval' seconds, if not canceled.
-
-        Returns:
-            threading.Timer, set to reset USB port corresponding the device
-            with the given serial number.
-        """
-        usb_reset_timer = threading.Timer(interval, self.USBResetCallback,
-                                          (serial, ))
-        usb_reset_timer.daemon = True
-        usb_reset_timer.start()
-
-        return usb_reset_timer
-
-    def USBResetCallback(self, serial):
-        """Resets USB device file corresponding to the given device serial.
-
-        Args:
-            serial: string, serial number of the device whose USB device file
-                    will reset.
-        """
-        device_file_path = usb_utils.GetDevicesUSBFilePath()
-        if serial in device_file_path:
-            logging.error(
-                "Device %s not responding. Resetting device file %s.", serial,
-                device_file_path[serial])
-            usb_utils.ResetDeviceUsb(device_file_path[serial])
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for device command."""
-        self.update_thread = None
-        self.arg_parser.add_argument(
-            "--set_serial",
-            default="",
-            help="Serial number for device. Can be a comma-separated list.")
-        self.arg_parser.add_argument(
-            "--update",
-            choices=("single", "start", "stop"),
-            default="start",
-            help="Update device info on cloud scheduler")
-        self.arg_parser.add_argument(
-            "--interval",
-            type=int,
-            default=30,
-            help="Interval (seconds) to repeat device update.")
-        self.arg_parser.add_argument(
-            "--host", type=int, help="The index of the host.")
-        self.arg_parser.add_argument(
-            "--server_type",
-            choices=("vti", "tfc"),
-            default="vti",
-            help="The type of a cloud-based test scheduler server.")
-        self.arg_parser.add_argument(
-            "--lease",
-            default=False,
-            type=bool,
-            help="Whether to lease jobs and execute them.")
-        self.arg_parser.add_argument(
-            "--suppress_lock_warning",
-            default=True,
-            help="Whether to suppress device lock warning messages.")
-        self.arg_parser.add_argument(
-            "--from_job_pool",
-            action="store_true",
-            help="Whether the command is executed from the job pool. "
-            "Check only the availability of the devices when set.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Sets device info such as serial number."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.set_serial:
-            self.console.SetSerials(args.set_serial.split(","))
-            logging.info("serials: %s", self.console._serials)
-        if args.update:
-            if args.host is None:
-                if len(self.console._hosts) > 1:
-                    raise ConsoleArgumentError("More than one host.")
-                args.host = 0
-            host = self.console._hosts[args.host]
-
-            if args.suppress_lock_warning:
-                if (type(args.suppress_lock_warning) != str
-                        or args.suppress_lock_warning.lower() == "true"):
-                    suppress_lock_warning = True
-                else:
-                    suppress_lock_warning = False
-
-            if args.update == "single":
-                self.UpdateDevice(args.server_type, host, args.lease,
-                                  suppress_lock_warning, args.from_job_pool)
-            elif args.update == "start":
-                if args.interval <= 0:
-                    raise ConsoleArgumentError(
-                        "update interval must be positive")
-                # do not allow user to create new
-                # thread if one is currently running
-                if self.update_thread is not None and not hasattr(
-                        self.update_thread, 'keep_running'):
-                    logging.warning('device update already running. '
-                                    'run device --update stop first.')
-                    return
-                self.update_thread = threading.Thread(
-                    target=self.UpdateDeviceRepeat,
-                    args=(
-                        args.server_type,
-                        host,
-                        args.lease,
-                        args.interval,
-                        suppress_lock_warning,
-                        args.from_job_pool,
-                    ))
-                self.update_thread.daemon = True
-                self.update_thread.start()
-            elif args.update == "stop":
-                self.update_thread.keep_running = False
-                if self.console.GetSerials():
-                    self.console.ResetSerials()
diff --git a/harnesses/host_controller/command_processor/command_device_test.py b/harnesses/host_controller/command_processor/command_device_test.py
deleted file mode 100644
index f951c56..0000000
--- a/harnesses/host_controller/command_processor/command_device_test.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import re
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import common
-from host_controller.command_processor import command_device
-
-
-def cmd_util_side_effect(value, timeout=0, callback_on_timeout=None, *args):
-    ret = ("", "", 0)
-    if value == "adb devices":
-        ret = ("List of devices attached\ndevice1\tdevice\ndevice2\tdevice",
-               "", 0)
-    elif value == "fastboot devices":
-        ret = ("device3\tfastboot\n", "", 0)
-    elif re.match("fastboot -s .* getvar product", value):
-        ret = ("", "product: somefish", 0)
-    return ret
-
-
-class CommandDeviceTest(unittest.TestCase):
-    """Tests for device command processor"""
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_device.cmd_utils")
-    def testUpdateDevice(self, mock_cmd_utils, mock_console):
-        command = command_device.CommandDevice()
-        command._SetUp(mock_console)
-        mock_host = mock.Mock()
-        mock_host.hostname = "vtslab-001"
-        mock_cmd_utils.ExecuteOneShellCommand.side_effect = cmd_util_side_effect
-        command.UpdateDevice("vti", mock_host, False)
-        mock_console._vti_endpoint_client.UploadDeviceInfo.assert_called_with(
-            "vtslab-001", [{
-                "status": mock.ANY,
-                "serial": "device3",
-                "product": "somefish"
-            }, {
-                "status": mock.ANY,
-                "serial": "device1",
-                "product": "somefish"
-            }, {
-                "status": mock.ANY,
-                "serial": "device2",
-                "product": "somefish"
-            }])
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_device.cmd_utils")
-    def testUpdateDeviceLeaseJob(self, mock_cmd_utils, mock_console):
-        command = command_device.CommandDevice()
-        command._SetUp(mock_console)
-        mock_host = mock.Mock()
-        mock_host.hostname = "vtslab-001"
-        mock_cmd_utils.ExecuteOneShellCommand.side_effect = cmd_util_side_effect
-        command.UpdateDevice("vti", mock_host, True)
-        mock_console._job_in_queue.put.assert_called_with("lease")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_device.cmd_utils")
-    def testUpdateDeviceFromJobPool(self, mock_cmd_utils, mock_console):
-        mock_console.GetSerials.return_value = ["device1", "device4"]
-        command = command_device.CommandDevice()
-        command._SetUp(mock_console)
-        mock_host = mock.Mock()
-        mock_host.hostname = "vtslab-001"
-        mock_cmd_utils.ExecuteOneShellCommand.side_effect = cmd_util_side_effect
-        command.UpdateDevice("vti", mock_host, False, from_job_pool=True)
-        mock_console._vti_endpoint_client.UploadDeviceInfo.assert_called_with(
-            "vtslab-001",
-            [{
-                'status': common._DEVICE_STATUS_DICT["no-response"],
-                'serial': 'device4',
-                'product': 'error'
-            }, {
-                'status': common._DEVICE_STATUS_DICT["online"],
-                'serial': 'device1',
-                'product': mock.ANY
-            }])
-
-    @mock.patch("host_controller.console.Console")
-    def testCommandDeviceUpdateSingle(self, mock_console):
-        command = command_device.CommandDevice()
-        command.UpdateDevice = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run("--update=single")
-        self.assertIsNone(ret)
-        command.UpdateDevice.assert_called_with("vti", mock.ANY, False, True,
-                                                False)
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_device.threading")
-    def testCommandDeviceUpdateSetSerial(self, mock_threading, mock_console):
-        mock_thread = mock.Mock()
-        mock_threading.Thread.return_value = mock_thread
-        command = command_device.CommandDevice()
-        command.UpdateDevice = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run("--set_serial=device1,device2,device3")
-        self.assertIsNone(ret)
-        mock_console.SetSerials.assert_called_with(
-            ["device1", "device2", "device3"])
-        mock_threading.Thread.assert_called_with(
-            args=("vti", mock.ANY, False, 30, True, False),
-            target=command.UpdateDeviceRepeat)
-        mock_thread.start.assert_called_with()
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_device.threading")
-    def testCommandDeviceUpdateStop(self, mock_threading, mock_console):
-        mock_thread = mock.Mock()
-        mock_threading.Thread.return_value = mock_thread
-        command = command_device.CommandDevice()
-        command.UpdateDevice = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run("")
-        self.assertIsNone(ret)
-        mock_threading.Thread.assert_called_with(
-            args=("vti", mock.ANY, False, 30, True, False),
-            target=command.UpdateDeviceRepeat)
-        mock_thread.start.assert_called_with()
-        ret = command._Run("--update=stop")
-        self.assertIsNone(ret)
-        self.assertFalse(mock_thread.keep_running)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/command_processor/command_dut.py b/harnesses/host_controller/command_processor/command_dut.py
deleted file mode 100644
index a722b41..0000000
--- a/harnesses/host_controller/command_processor/command_dut.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-
-from vts.utils.python.common import cmd_utils
-from vts.utils.python.controllers import adb
-from vts.utils.python.controllers import android_device
-
-# Default index of setStreamVolume() from IAudioService.aidl (1 based)
-SETSTREAMVOLUME_INDEX_DEFAULT = 3
-
-# Indices of each stream type (can be checked with "adb shell dumpsys audio" on the command line)
-STREAM_TYPE_CALL = 0
-STREAM_TYPE_RINGTONE = 2
-STREAM_TYPE_MEDIA = 3
-STREAM_TYPE_ALARM = 4
-
-STREAM_TYPE_LIST = [
-    STREAM_TYPE_CALL,
-    STREAM_TYPE_RINGTONE,
-    STREAM_TYPE_MEDIA,
-    STREAM_TYPE_ALARM,
-]
-
-
-class CommandDUT(base_command_processor.BaseCommandProcessor):
-    """Command processor for DUT command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "dut"
-    command_detail = "Performs certain operations on DUT (Device Under Test)."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for dut command."""
-        self.arg_parser.add_argument(
-            "--operation",
-            choices=("wifi_on", "wifi_off", 'volume_mute', 'volume_max'),
-            default="",
-            required=True,
-            help="Operation to perform.")
-        self.arg_parser.add_argument(
-            "--serial", default="", required=True, help="The device serial.")
-        self.arg_parser.add_argument(
-            "--ap",
-            default="",  # Required only for wifi_on
-            help="Access point (AP) name for 'wifi_on' operation.")
-        self.arg_parser.add_argument(
-            "--volume_levels",
-            type=int,
-            default=30,  # Required only for volume_mute and volume_max
-            help="The number of volume control levels.")
-        self.arg_parser.add_argument(
-            "--version",
-            type=float,
-            default=8.0,
-            help="System version information of the device on which "
-            "the test will run.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Performs the requested operation on the selected DUT."""
-        args = self.arg_parser.ParseLine(arg_line)
-        device = android_device.AndroidDevice(
-            args.serial, device_callback_port=-1)
-        boot_complete = device.waitForBootCompletion()
-        if not boot_complete:
-            logging.error("Device %s failed to bootup.", args.serial)
-            self.console.device_status[
-                args.serial] = common._DEVICE_STATUS_DICT["error"]
-            self.console.vti_endpoint_client.SetJobStatusFromLeasedTo(
-                "bootup-err")
-            return False
-
-        adb_proxy = adb.AdbProxy(serial=args.serial)
-        adb_proxy.root()
-        try:
-            if args.operation == "wifi_on":
-                adb_proxy.shell("svc wifi enable")
-                if args.ap:
-                    adb_proxy.install(
-                        "../testcases/DATA/app/WifiUtil/WifiUtil.apk")
-                    adb_proxy.shell(
-                        "am instrument -e method \"connectToNetwork\" "
-                        "-e ssid %s "
-                        "-w com.android.tradefed.utils.wifi/.WifiUtil" %
-                        args.ap)
-            elif args.operation == "wifi_off":
-                adb_proxy.shell("svc wifi disable")
-            elif args.operation == "volume_mute":
-                for _ in range(args.volume_levels):
-                    adb_proxy.shell("input keyevent 25")
-                self.SetOtherVolumes(adb_proxy, 0, args.version)
-            elif args.operation == "volume_max":
-                for _ in range(args.volume_levels):
-                    adb_proxy.shell("input keyevent 24")
-                self.SetOtherVolumes(adb_proxy, args.volume_levels,
-                                     args.version)
-        except adb.AdbError as e:
-            logging.exception(e)
-            return False
-
-    def SetOtherVolumes(self, adb_proxy, volume_level, version=None):
-        """Sets device's call/media/alarm volumes a certain level.
-
-        Args:
-            adb_proxy: AdbProxy, used for interacting with the device via adb.
-            volume_level: int, volume level value.
-            version: float, Android system version value. The index of
-                     setStreamVolume() depends on the Android version.
-        """
-        setStreamVolume_index = SETSTREAMVOLUME_INDEX_DEFAULT
-        if version and version >= 9.0:
-            setStreamVolume_index = 7
-        for stream_type in STREAM_TYPE_LIST:
-            adb_volume_command = "service call audio %s i32 %s i32 %s i32 1" % (
-                setStreamVolume_index, stream_type, volume_level)
-            adb_proxy.shell(adb_volume_command)
diff --git a/harnesses/host_controller/command_processor/command_dut_test.py b/harnesses/host_controller/command_processor/command_dut_test.py
deleted file mode 100644
index fff5c4d..0000000
--- a/harnesses/host_controller/command_processor/command_dut_test.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import common
-from host_controller.command_processor import command_dut
-
-
-class CommandDUTTest(unittest.TestCase):
-    """Tests for DUT command processor"""
-
-    def setUp(self):
-        """Creates CommandSheet."""
-        self._command = command_dut.CommandDUT()
-        mock_console = mock.Mock()
-        mock_console.device_status = {}
-        self._command._SetUp(mock_console)
-
-    def testSetOtherVolumesWithoutVersionInfo(self):
-        mock_adb_proxy = mock.Mock()
-        self._command.SetOtherVolumes(mock_adb_proxy, 5)
-        self.assertEqual(mock_adb_proxy.shell.mock_calls, [
-            mock.call("service call audio 3 i32 0 i32 5 i32 1"),
-            mock.call("service call audio 3 i32 2 i32 5 i32 1"),
-            mock.call("service call audio 3 i32 3 i32 5 i32 1"),
-            mock.call("service call audio 3 i32 4 i32 5 i32 1"),
-        ])
-
-    def testSetOtherVolumesWithVersionInfo(self):
-        mock_adb_proxy = mock.Mock()
-        self._command.SetOtherVolumes(mock_adb_proxy, 0, 8.1)
-        self.assertEqual(mock_adb_proxy.shell.mock_calls, [
-            mock.call("service call audio 3 i32 0 i32 0 i32 1"),
-            mock.call("service call audio 3 i32 2 i32 0 i32 1"),
-            mock.call("service call audio 3 i32 3 i32 0 i32 1"),
-            mock.call("service call audio 3 i32 4 i32 0 i32 1"),
-        ])
-        mock_adb_proxy.shell.mock_calls = []
-        self._command.SetOtherVolumes(mock_adb_proxy, 10, 9.0)
-        self.assertEqual(mock_adb_proxy.shell.mock_calls, [
-            mock.call("service call audio 7 i32 0 i32 10 i32 1"),
-            mock.call("service call audio 7 i32 2 i32 10 i32 1"),
-            mock.call("service call audio 7 i32 3 i32 10 i32 1"),
-            mock.call("service call audio 7 i32 4 i32 10 i32 1"),
-        ])
-
-    @mock.patch("host_controller.command_processor.command_dut.android_device")
-    @mock.patch("host_controller.command_processor.command_dut.logging")
-    def testCommandDUTBootupFail(self, mock_logging, mock_android_device):
-        mock_device = mock.Mock()
-        mock_device.waitForBootCompletion.return_value = False
-        mock_android_device.AndroidDevice.return_value = mock_device
-        ret = self._command._Run("--serial device1 --operation wifi_on")
-        self.assertFalse(ret)
-        mock_logging.error.assert_called_with("Device %s failed to bootup.",
-                                              "device1")
-
-    @mock.patch("host_controller.command_processor.command_dut.android_device")
-    @mock.patch("host_controller.command_processor.command_dut.adb")
-    def testCommandDUTWifiOnWithoutAP(self, mock_adb, mock_android_device):
-        mock_adb_proxy = mock.Mock()
-        mock_adb.AdbProxy.return_value = mock_adb_proxy
-        mock_device = mock.Mock()
-        mock_device.waitForBootCompletion.return_value = True
-        mock_android_device.AndroidDevice.return_value = mock_device
-        ret = self._command._Run("--serial device1 --operation wifi_on")
-        self.assertIsNone(ret)
-        mock_adb_proxy.root.assert_called_once()
-        mock_adb_proxy.shell.assert_called_with("svc wifi enable")
-        mock_adb_proxy.install.assert_not_called()
-
-    @mock.patch("host_controller.command_processor.command_dut.android_device")
-    @mock.patch("host_controller.command_processor.command_dut.adb")
-    def testCommandDUTWifiOn(self, mock_adb, mock_android_device):
-        mock_adb_proxy = mock.Mock()
-        mock_adb.AdbProxy.return_value = mock_adb_proxy
-        mock_device = mock.Mock()
-        mock_device.waitForBootCompletion.return_value = True
-        mock_android_device.AndroidDevice.return_value = mock_device
-        ret = self._command._Run("--serial device1 --operation wifi_on --ap %s"
-                                 % common._DEFAULT_WIFI_AP)
-        self.assertIsNone(ret)
-        mock_adb_proxy.root.assert_called_once()
-        mock_adb_proxy.shell.assert_any_call("svc wifi enable")
-        mock_adb_proxy.install.assert_called_with(
-            "../testcases/DATA/app/WifiUtil/WifiUtil.apk")
-        mock_adb_proxy.shell.assert_called_with(
-            "am instrument -e method \"connectToNetwork\" -e ssid GoogleGuest "
-            "-w com.android.tradefed.utils.wifi/.WifiUtil")
-
-    @mock.patch("host_controller.command_processor.command_dut.android_device")
-    @mock.patch("host_controller.command_processor.command_dut.adb")
-    def testCommandDUTWifiOff(self, mock_adb, mock_android_device):
-        mock_adb_proxy = mock.Mock()
-        mock_adb.AdbProxy.return_value = mock_adb_proxy
-        mock_device = mock.Mock()
-        mock_device.waitForBootCompletion.return_value = True
-        mock_android_device.AndroidDevice.return_value = mock_device
-        ret = self._command._Run("--serial device1 --operation wifi_off")
-        self.assertIsNone(ret)
-        mock_adb_proxy.root.assert_called_once()
-        mock_adb_proxy.shell.assert_any_call("svc wifi disable")
-
-    @mock.patch("host_controller.command_processor.command_dut.android_device")
-    @mock.patch("host_controller.command_processor.command_dut.adb")
-    def testCommandDUTVolumeMute(self, mock_adb, mock_android_device):
-        self._command.SetOtherVolumes = mock.Mock()
-        mock_adb_proxy = mock.Mock()
-        mock_adb.AdbProxy.return_value = mock_adb_proxy
-        mock_device = mock.Mock()
-        mock_device.waitForBootCompletion.return_value = True
-        mock_android_device.AndroidDevice.return_value = mock_device
-        ret = self._command._Run("--serial device1 --operation volume_mute")
-        self.assertIsNone(ret)
-        mock_adb_proxy.root.assert_called_once()
-        self.assertEqual(mock_adb_proxy.shell.mock_calls,
-                         [mock.call("input keyevent 25")] * 30)
-        self._command.SetOtherVolumes.assert_called_with(mock.ANY, 0, 8.0)
-
-    @mock.patch("host_controller.command_processor.command_dut.android_device")
-    @mock.patch("host_controller.command_processor.command_dut.adb")
-    def testCommandDUTVolumeMax(self, mock_adb, mock_android_device):
-        self._command.SetOtherVolumes = mock.Mock()
-        mock_adb_proxy = mock.Mock()
-        mock_adb.AdbProxy.return_value = mock_adb_proxy
-        mock_device = mock.Mock()
-        mock_device.waitForBootCompletion.return_value = True
-        mock_android_device.AndroidDevice.return_value = mock_device
-        ret = self._command._Run(
-            "--serial device1 --operation volume_max --version 9.0")
-        self.assertIsNone(ret)
-        mock_adb_proxy.root.assert_called_once()
-        self.assertEqual(mock_adb_proxy.shell.mock_calls,
-                         [mock.call("input keyevent 24")] * 30)
-        self._command.SetOtherVolumes.assert_called_with(mock.ANY, 30, 9.0)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/command_processor/command_exit.py b/harnesses/host_controller/command_processor/command_exit.py
deleted file mode 100644
index 638e6ad..0000000
--- a/harnesses/host_controller/command_processor/command_exit.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller.command_processor import base_command_processor
-
-
-class CommandExit(base_command_processor.BaseCommandProcessor):
-    """Command processor for exit command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "exit"
-    command_detail = ""
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for request command."""
-        self.arg_parser.add_argument(
-            "--wait_for_jobs",
-            default=True,
-            help="True to wait for the running jobs to complete before exiting."
-        )
-
-    # @Override
-    def Run(self, arg_line):
-        """Terminates the console.
-
-        Returns:
-            True, which stops the cmdloop.
-        """
-        args = self.arg_parser.ParseLine(arg_line)
-
-        self.console.onecmd("device --update stop")
-
-        if args.wait_for_jobs:
-            if (type(args.wait_for_jobs) != str or
-                args.wait_for_jobs.lower() == "true"):
-                logging.info("waiting for running jobs to complete...")
-                self.console.WaitForJobsToExit()
-
-        self.console.StopJobThreadAndProcessPool()
-        self.console.__exit__()
-        return True
diff --git a/harnesses/host_controller/command_processor/command_fastboot.py b/harnesses/host_controller/command_processor/command_fastboot.py
deleted file mode 100644
index 459a079..0000000
--- a/harnesses/host_controller/command_processor/command_fastboot.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.ipc import file_lock_semaphore
-from host_controller.utils.usb import usb_utils
-
-from vts.utils.python.common import cmd_utils
-
-
-class CommandFastboot(base_command_processor.BaseCommandProcessor):
-    """Command processor for fastboot command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "fastboot"
-    command_detail = "Runs a fastboot command."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for device command."""
-        self.sem_fastboot = file_lock_semaphore.FileLockSemaphore("fastboot")
-        self.arg_parser.add_argument(
-            "--serial",
-            "-s",
-            required=True,
-            default=None,
-            help="The target device serial to run the command.")
-        self.arg_parser.add_argument(
-            "--retry",
-            type=int,
-            default=2,
-            help="The number of times to retry if a command fails.")
-        self.arg_parser.add_argument(
-            "--timeout",
-            type=float,
-            default=common.DEFAULT_DEVICE_TIMEOUT_SECS,
-            help="The maximum timeout value of this command in seconds. "
-            "Set to 0 to disable the timeout functionality.")
-        self.arg_parser.add_argument(
-            "command",
-            metavar="COMMAND",
-            nargs="+",
-            help="The command to be executed. If the command contains "
-            "arguments starting with \"-\", place the command at end of line "
-            "after \"--\".")
-
-    # @Override
-    def Run(self, arg_line):
-        """Runs a fastboot command."""
-        args = self.arg_parser.ParseLine(arg_line)
-        cmd_list = ["fastboot"]
-        if args.serial:
-            if "," in args.serial:
-                logging.error("Only one serial can be specified")
-                return False
-            cmd_list.append("-s %s" % args.serial)
-        cmd_list.extend(self.ReplaceVars(args.command))
-        cmd = " ".join(cmd_list)
-        for _ in range(args.retry + 1):
-            self.sem_fastboot.Acquire()
-            if args.timeout == 0:
-                stdout, stderr, retcode = cmd_utils.ExecuteOneShellCommand(cmd)
-            else:
-                stdout, stderr, retcode = cmd_utils.ExecuteOneShellCommand(
-                    cmd, args.timeout,
-                    usb_utils.ResetUsbDeviceOfSerial_Callback, args.serial)
-            self.sem_fastboot.Release()
-            if stdout:
-                logging.info(stdout)
-            if stderr:
-                logging.error(stderr)
-            if retcode == 0:
-                return
-            logging.warn("Retrying... (%s)", cmd)
-
-        if self.console.job_pool and args.serial:
-            self.console.device_status[
-                args.serial] = common._DEVICE_STATUS_DICT["error"]
-        return False
diff --git a/harnesses/host_controller/command_processor/command_fetch.py b/harnesses/host_controller/command_processor/command_fetch.py
deleted file mode 100644
index f43731d..0000000
--- a/harnesses/host_controller/command_processor/command_fetch.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-
-
-class CommandFetch(base_command_processor.BaseCommandProcessor):
-    """Command processor for fetch command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "fetch"
-    command_detail = "Fetch a build artifact."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for fetch command."""
-        self.arg_parser.add_argument(
-            '--type',
-            default='pab',
-            choices=('local_fs', 'gcs', 'pab', 'ab'),
-            help='Build provider type')
-        self.arg_parser.add_argument(
-            '--method',
-            default='GET',
-            choices=('GET', 'POST'),
-            help='Method for fetching')
-        self.arg_parser.add_argument(
-            "--path",  # required for local_fs
-            help="The path of a local directory which keeps the artifacts.")
-        self.arg_parser.add_argument(
-            "--branch",  # required for pab
-            help="Branch to grab the artifact from.")
-        self.arg_parser.add_argument(
-            "--target",  # required for pab
-            help="Target product to grab the artifact from.")
-        # TODO(lejonathan): find a way to not specify this?
-        self.arg_parser.add_argument(
-            "--account_id",
-            default=common._DEFAULT_ACCOUNT_ID,
-            help="Partner Android Build account_id to use.")
-        self.arg_parser.add_argument(
-            '--build_id',
-            default='latest',
-            help='Build ID to use default latest.')
-        self.arg_parser.add_argument(
-            "--artifact_name",  # required for pab
-            help=
-            "Name of the artifact to be fetched. {id} replaced with build id.")
-        self.arg_parser.add_argument(
-            "--userinfo-file",
-            help=
-            "Location of file containing email and password, if using POST.")
-        self.arg_parser.add_argument(
-            "--noauth_local_webserver",
-            default=False,
-            type=bool,
-            help="True to not use a local webserver for authentication.")
-        self.arg_parser.add_argument(
-            "--fetch_signed_build",
-            default=False,
-            type=bool,
-            help="True to fetch only signed build images.")
-        self.arg_parser.add_argument(
-            "--full_device_images",
-            default=False,
-            type=bool,
-            help="True to skip checking whether the fetched artifacts are "
-            "fully packaged device images.")
-        self.arg_parser.add_argument(
-            "--gsi",
-            default=False,
-            type=bool,
-            help="True if a target is GSI. Only system.img and "
-            "vbmeta.img are taken.")
-        self.arg_parser.add_argument(
-            "--set_suite_as",
-            default="",
-            choices=("", "vts", "cts", "gts", "sts"),
-            help="To specify the type of a test suite that is being fetched."
-            "Used when the artifact's file name does not follow the "
-            "standard naming convention.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Makes the host download a build artifact from PAB."""
-        args = self.arg_parser.ParseLine(arg_line)
-
-        if args.type not in self.console._build_provider:
-            logging.error("ERROR: uninitialized fetch type %s", args.type)
-            return False
-
-        provider = self.console._build_provider[args.type]
-        if args.type == "pab":
-            # do we want this somewhere else? No harm in doing multiple times
-            provider.Authenticate(args.userinfo_file,
-                                  args.noauth_local_webserver)
-            if not args.fetch_signed_build:
-                (device_images, test_suites, fetch_environment,
-                 _) = provider.GetArtifact(
-                     account_id=args.account_id,
-                     branch=args.branch,
-                     target=args.target,
-                     artifact_name=args.artifact_name,
-                     build_id=args.build_id,
-                     method=args.method,
-                     full_device_images=args.full_device_images)
-                self.console.fetch_info["fetch_signed_build"] = False
-            else:
-                (device_images, test_suites, fetch_environment,
-                 _) = provider.GetSignedBuildArtifact(
-                     account_id=args.account_id,
-                     branch=args.branch,
-                     target=args.target,
-                     artifact_name=args.artifact_name,
-                     build_id=args.build_id,
-                     method=args.method,
-                     full_device_images=args.full_device_images)
-                self.console.fetch_info["fetch_signed_build"] = True
-
-            self.console.fetch_info["build_id"] = fetch_environment["build_id"]
-        elif args.type == "local_fs":
-            device_images, test_suites = provider.Fetch(
-                args.path, args.full_device_images)
-            self.console.fetch_info["build_id"] = None
-        elif args.type == "gcs":
-            device_images, test_suites, tools = provider.Fetch(
-                args.path, args.full_device_images, args.set_suite_as)
-            self.console.fetch_info["build_id"] = None
-        elif args.type == "ab":
-            device_images, test_suites, fetch_environment = provider.Fetch(
-                branch=args.branch,
-                target=args.target,
-                artifact_name=args.artifact_name,
-                build_id=args.build_id,
-                full_device_images=args.full_device_images)
-            self.console.fetch_info["build_id"] = fetch_environment["build_id"]
-        else:
-            logging.error("ERROR: unknown fetch type %s", args.type)
-            return False
-
-        if args.gsi:
-            filtered_images = {}
-            image_names = device_images.keys()
-            for image_name in image_names:
-                if image_name.endswith(".img") and image_name not in [
-                        "system.img", "vbmeta.img"
-                ]:
-                    provider.RemoveDeviceImage(image_name)
-                    continue
-                filtered_images[image_name] = device_images[image_name]
-            device_images = filtered_images
-
-        if args.type == "gcs":
-            gcs_path, filename = os.path.split(args.path)
-            self.console.fetch_info["branch"] = gcs_path
-            self.console.fetch_info["target"] = filename
-            self.console.fetch_info["build_id"] = "latest"
-            self.console.fetch_info["account_id"] = ""
-        else:
-            self.console.fetch_info["branch"] = args.branch
-            self.console.fetch_info["target"] = args.target
-            self.console.fetch_info["account_id"] = args.account_id
-
-        self.console.UpdateFetchInfo(provider.GetFetchedArtifactType())
-
-        self.console.device_image_info.update(device_images)
-        self.console.test_suite_info.update(test_suites)
-        self.console.tools_info.update(provider.GetAdditionalFile())
-
-        if self.console.device_image_info:
-            logging.info("device images:\n%s", "\n".join(
-                image + ": " + path
-                for image, path in self.console.device_image_info.iteritems()))
-        if self.console.test_suite_info:
-            logging.info("test suites:\n%s", "\n".join(
-                suite + ": " + path
-                for suite, path in self.console.test_suite_info.iteritems()))
-        if self.console.tools_info:
-            logging.info("additional files:\n%s", "\n".join(
-                rel_path + ": " + full_path for rel_path, full_path in
-                self.console.tools_info.iteritems()))
diff --git a/harnesses/host_controller/command_processor/command_flash.py b/harnesses/host_controller/command_processor/command_flash.py
deleted file mode 100644
index b8a2d7e..0000000
--- a/harnesses/host_controller/command_processor/command_flash.py
+++ /dev/null
@@ -1,210 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import importlib
-import os
-import stat
-
-from host_controller import common
-from host_controller.build import build_flasher
-from host_controller.command_processor import base_command_processor
-
-
-class CommandFlash(base_command_processor.BaseCommandProcessor):
-    """Command processor for flash command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "flash"
-    command_detail = "Flash images to a device."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for flash command."""
-        self.arg_parser.add_argument(
-            "--image",
-            help=("The file name of an image to flash."
-                  " Used to flash a single image."))
-        self.arg_parser.add_argument(
-            "--current",
-            metavar="PARTITION_IMAGE",
-            nargs="*",
-            type=lambda x: x.split("="),
-            help="The partitions and images to be flashed. The format is "
-            "<partition>=<image>. If PARTITION_IMAGE list is empty, "
-            "currently fetched " + ", ".join(common._DEFAULT_FLASH_IMAGES) +
-            " will be flashed.")
-        self.arg_parser.add_argument(
-            "--serial", default="", help="Serial number for device.")
-        self.arg_parser.add_argument(
-            "--build_dir",
-            help="Directory containing build images to be flashed.")
-        self.arg_parser.add_argument(
-            "--gsi", help="Path to generic system image")
-        self.arg_parser.add_argument("--vbmeta", help="Path to vbmeta image")
-        self.arg_parser.add_argument(
-            "--flasher_type",
-            default="fastboot",
-            help="Flasher type. Valid arguments are \"fastboot\", \"custom\", "
-            "and full module name followed by class name. The class must "
-            "inherit build_flasher.BuildFlasher, and implement "
-            "__init__(serial, flasher_path) and "
-            "Flash(device_images, additional_files, *flasher_args).")
-        self.arg_parser.add_argument(
-            "--flasher_path", default=None, help="Path to a flasher binary")
-        self.arg_parser.add_argument(
-            "flasher_args",
-            metavar="ARGUMENTS",
-            nargs="*",
-            help="The arguments passed to the flasher binary. If any argument "
-            "starts with \"-\", place all of them after \"--\" at end of "
-            "line.")
-        self.arg_parser.add_argument(
-            "--reboot_mode",
-            default="bootloader",
-            choices=("bootloader", "download"),
-            help="Reboot device to bootloader/download mode")
-        self.arg_parser.add_argument(
-            "--repackage",
-            default="tar.md5",
-            choices=("tar.md5"),
-            help="Repackage artifacts into given format before flashing.")
-        self.arg_parser.add_argument(
-            "--wait-for-boot",
-            default="true",
-            help="false to not wait for device booting.")
-        self.arg_parser.add_argument(
-            "--reboot", default="false", help="true to reboot the device(s).")
-        self.arg_parser.add_argument(
-            "--skip-vbmeta",
-            default=False,
-            type=bool,
-            help="true to skip flashing vbmeta.img if the device does not have "
-            "the vbmeta slot .")
-
-    # @Override
-    def Run(self, arg_line):
-        """Flash GSI or build images to a device connected with ADB."""
-        args = self.arg_parser.ParseLine(arg_line)
-
-        # path
-        if (self.console.tools_info is not None
-                and args.flasher_path in self.console.tools_info):
-            flasher_path = self.console.tools_info[args.flasher_path]
-        elif args.flasher_path:
-            flasher_path = args.flasher_path
-        else:
-            flasher_path = ""
-        if os.path.exists(flasher_path):
-            flasher_mode = os.stat(flasher_path).st_mode
-            os.chmod(flasher_path,
-                     flasher_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
-
-        # serial numbers
-        if args.serial:
-            flasher_serials = [args.serial]
-        elif self.console._serials:
-            flasher_serials = self.console._serials
-        else:
-            flasher_serials = [""]
-
-        # images
-        if args.image:
-            partition_image = {}
-            partition_image[args.image] = self.console.device_image_info[
-                args.image]
-        else:
-            if args.current:
-                partition_image = dict((partition,
-                                        self.console.device_image_info[image])
-                                       for partition, image in args.current)
-            else:
-                partition_image = dict(
-                    (image.rsplit(".img", 1)[0],
-                     self.console.device_image_info[image])
-                    for image in common._DEFAULT_FLASH_IMAGES
-                    if image in self.console.device_image_info)
-
-        # type
-        if args.flasher_type in ("fastboot", "custom"):
-            flasher_class = build_flasher.BuildFlasher
-        else:
-            class_path = args.flasher_type.rsplit(".", 1)
-            flasher_module = importlib.import_module(class_path[0])
-            flasher_class = getattr(flasher_module, class_path[1])
-            if not issubclass(flasher_class, build_flasher.BuildFlasher):
-                raise TypeError(
-                    "%s is not a subclass of BuildFlasher." % class_path[1])
-
-        flashers = [flasher_class(s, flasher_path) for s in flasher_serials]
-
-        # Can be parallelized as long as that's proven reliable.
-        for flasher in flashers:
-            ret_flash = True
-            if args.flasher_type == "fastboot":
-                if args.image is not None:
-                    ret_flash = flasher.FlashImage(partition_image, True
-                                                   if args.reboot == "true"
-                                                   else False)
-                elif args.current is not None:
-                    ret_flash = flasher.Flash(partition_image,
-                                              args.skip_vbmeta)
-                else:
-                    if args.gsi is None and args.build_dir is None:
-                        self.arg_parser.error("Nothing requested: "
-                                              "specify --gsi or --build_dir")
-                        return False
-                    if args.build_dir is not None:
-                        ret_flash = flasher.Flashall(args.build_dir)
-                    if args.gsi is not None:
-                        ret_flash = flasher.FlashGSI(
-                            args.gsi,
-                            args.vbmeta,
-                            skip_vbmeta=args.skip_vbmeta)
-            elif args.flasher_type == "custom":
-                if flasher_path is not None:
-                    if args.repackage is not None:
-                        flasher.RepackageArtifacts(
-                            self.console.device_image_info, args.repackage)
-                    ret_flash = flasher.FlashUsingCustomBinary(
-                        self.console.device_image_info, args.reboot_mode,
-                        args.flasher_args, 300)
-                else:
-                    self.arg_parser.error(
-                        "Please specify the path to custom flash tool.")
-                    return False
-            else:
-                ret_flash = flasher.Flash(partition_image,
-                                          self.console.tools_info,
-                                          *args.flasher_args)
-            if ret_flash == False:
-                return False
-
-        if args.wait_for_boot == "true":
-            for flasher in flashers:
-                ret_wait = flasher.WaitForDevice()
-                if ret_wait == False:
-                    self.console.device_status[
-                        flasher.device.serial] = common._DEVICE_STATUS_DICT[
-                            "error"]
-                    self.console.vti_endpoint_client.SetJobStatusFromLeasedTo(
-                        "bootup-err")
-                    return False
diff --git a/harnesses/host_controller/command_processor/command_gsispl.py b/harnesses/host_controller/command_processor/command_gsispl.py
deleted file mode 100644
index 9ebcd68..0000000
--- a/harnesses/host_controller/command_processor/command_gsispl.py
+++ /dev/null
@@ -1,153 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import datetime
-import logging
-import os
-import shutil
-import tempfile
-import zipfile
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.gsi import img_utils
-
-from vts.utils.python.common import cmd_utils
-
-
-class CommandGsispl(base_command_processor.BaseCommandProcessor):
-    """Command processor for gsispl command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "gsispl"
-    command_detail = "Changes security patch level on a selected GSI file."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for device command."""
-        self.arg_parser.add_argument(
-            "--gsi",
-            help="Path to GSI image to change security patch level. "
-            "If path is not given, the most recently fetched system.img "
-            "kept in device_image_info dictionary is used and then "
-            "device_image_info will be updated with the new GSI file.")
-        self.arg_parser.add_argument(
-            "--version", help="New version ID. It should be YYYY-mm-dd format")
-        self.arg_parser.add_argument(
-            "--version_from_path",
-            help="Path to vendor provided image file to retrieve SPL version. "
-            "If just a file name is given, the most recently fetched .img "
-            "file will be used.")
-        self.arg_parser.add_argument(
-            "--vendor_version",
-            help="The version of vendor.img that will be used (e.g., 8.1.0).")
-
-    # @Override
-    def Run(self, arg_line):
-        """Changes security patch level on a selected GSI file."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.gsi:
-            if os.path.isfile(args.gsi):
-                gsi_path = args.gsi
-            else:
-                logging.error("Cannot find system image in given path")
-                return
-        elif "system.img" in self.console.device_image_info:
-            gsi_path = self.console.device_image_info["system.img"]
-        else:
-            logging.error("Cannot find system image.")
-            return False
-
-        if args.version:
-            try:
-                version_date = datetime.datetime.strptime(
-                    args.version, "%Y-%m-%d")
-                version = "{:04d}-{:02d}-{:02d}".format(
-                    version_date.year, version_date.month, version_date.day)
-            except ValueError as e:
-                logging.error("version ID should be YYYY-mm-dd format.")
-                return
-        elif args.version_from_path:
-            dest_path = None
-            if os.path.isabs(args.version_from_path) and os.path.exists(
-                    args.version_from_path):
-                img_path = args.version_from_path
-            elif args.version_from_path in self.console.device_image_info:
-                img_path = self.console.device_image_info[
-                    args.version_from_path]
-            elif (args.version_from_path == "boot.img"
-                  and "full-zipfile" in self.console.device_image_info):
-                tempdir_base = os.path.join(os.getcwd(), "tmp")
-                if not os.path.exists(tempdir_base):
-                    os.mkdir(tempdir_base)
-                dest_path = tempfile.mkdtemp(dir=tempdir_base)
-
-                with zipfile.ZipFile(
-                        self.console.device_image_info["full-zipfile"],
-                        'r') as zip_ref:
-                    zip_ref.extractall(dest_path)
-                    img_path = os.path.join(dest_path, "boot.img")
-                    if not os.path.exists(img_path):
-                        logging.error("No %s file in device img .zip.",
-                                      args.version_from_path)
-                        shutil.rmtree(dest_path)
-                        return
-            else:
-                logging.error("Cannot find %s file.", args.version_from_path)
-                return False
-
-            version_dict = img_utils.GetSPLVersionFromBootImg(img_path)
-            if dest_path:
-                shutil.rmtree(dest_path)
-            if "year" in version_dict and "month" in version_dict:
-                version = "{:04d}-{:02d}-{:02d}".format(
-                    version_dict["year"], version_dict["month"],
-                    common._SPL_DEFAULT_DAY)
-            else:
-                logging.error("Failed to fetch SPL version from %s file.",
-                              img_path)
-                return False
-        else:
-            logging.error("version ID or path of .img file must be given.")
-            return False
-
-        output_path = os.path.join(
-            os.path.dirname(os.path.abspath(gsi_path)),
-            "system-{}.img".format(version))
-        command = "{} {} {} {}".format(
-            os.path.join(os.getcwd(), "..", "bin",
-                         "change_security_patch_ver.sh"), gsi_path,
-            output_path, version)
-        if args.vendor_version:
-            command = command + " -v " + args.vendor_version
-        if self.console.password.value:
-            command = "echo {} | sudo -S {}".format(
-                self.console.password.value, command)
-        stdout, stderr, err_code = cmd_utils.ExecuteOneShellCommand(command)
-        if err_code is 0:
-            if not args.gsi:
-                logging.info(
-                    "system.img path is updated to : {}".format(output_path))
-                self.console.device_image_info["system.img"] = output_path
-        else:
-            logging.error("gsispl error: {} {}".format(stdout, stderr))
-            return False
diff --git a/harnesses/host_controller/command_processor/command_info.py b/harnesses/host_controller/command_processor/command_info.py
deleted file mode 100644
index 715f913..0000000
--- a/harnesses/host_controller/command_processor/command_info.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller.command_processor import base_command_processor
-
-
-class CommandInfo(base_command_processor.BaseCommandProcessor):
-    '''Command processor for info command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    '''
-
-    command = 'info'
-    command_detail = 'Show status.'
-
-    def Run(self, arg_line):
-        '''Shows the console's session status information.
-
-        Args:
-            arg_line: string, line of command arguments
-        '''
-        logging.info('device image: %s', self.console.device_image_info)
-        logging.info('test suite: %s', self.console.test_suite_info)
-        logging.info('test result: %s', self.console.test_results)
-        logging.info('fetch info: %s', self.console.fetch_info)
-        logging.info('detailed fetch info: %s', self.console.detailed_fetch_info)
diff --git a/harnesses/host_controller/command_processor/command_lease.py b/harnesses/host_controller/command_processor/command_lease.py
deleted file mode 100644
index cc21306..0000000
--- a/harnesses/host_controller/command_processor/command_lease.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from host_controller.command_processor import base_command_processor
-from host_controller.console_argument_parser import ConsoleArgumentError
-
-
-class CommandLease(base_command_processor.BaseCommandProcessor):
-    """Command processor for lease command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "lease"
-    command_detail = "Make a host lease command tasks from TFC."
-
-    def _PrintTasks(self, tasks):
-        """Shows a list of command tasks.
-
-        Args:
-            devices: A list of DeviceInfo objects.
-        """
-        attr_names = ("request_id", "command_id", "task_id", "device_serials",
-                      "command_line")
-        self.console._PrintObjects(tasks, attr_names)
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for lease command."""
-        self.arg_parser.add_argument(
-            "--host", type=int, help="The index of the host.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Makes a host lease command tasks from TFC."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.host is None:
-            if len(self.console._hosts) > 1:
-                raise ConsoleArgumentError("More than one hosts.")
-            args.host = 0
-        tasks = self.console._hosts[args.host].LeaseCommandTasks()
-        self._PrintTasks(tasks)
\ No newline at end of file
diff --git a/harnesses/host_controller/command_processor/command_list.py b/harnesses/host_controller/command_processor/command_list.py
deleted file mode 100644
index e196a1a..0000000
--- a/harnesses/host_controller/command_processor/command_list.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller.command_processor import base_command_processor
-
-
-class CommandList(base_command_processor.BaseCommandProcessor):
-    """Command processor for list command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "list"
-    command_detail = "Show information about the hosts."
-
-    def _PrintHosts(self, hosts):
-        """Shows a list of host controllers.
-
-        Args:
-            hosts: A list of HostController objects.
-        """
-        self.console._Print("index  name")
-        for ind, host in enumerate(hosts):
-            self.console._Print("[%3d]  %s" % (ind, host.hostname))
-
-    def _PrintDevices(self, devices):
-        """Shows a list of devices.
-
-        Args:
-            devices: A list of DeviceInfo objects.
-        """
-        attr_names = ("device_serial", "state", "run_target", "build_id",
-                      "sdk_version", "stub")
-        self.console._PrintObjects(devices, attr_names)
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for list command."""
-        self.arg_parser.add_argument(
-            "--host", type=int, help="The index of the host.")
-        self.arg_parser.add_argument(
-            "type",
-            choices=("hosts", "devices"),
-            help="The type of the shown objects.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Shows information about the hosts."""
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.host is None:
-            hosts = enumerate(self.console._hosts)
-        else:
-            hosts = [(args.host, self.console._hosts[args.host])]
-        if args.type == "hosts":
-            self._PrintHosts(self.console._hosts)
-        elif args.type == "devices":
-            for ind, host in hosts:
-                devices = host.ListDevices()
-                self.console._Print("[%3d]  %s" % (ind, host.hostname))
-                self._PrintDevices(devices)
-
-    def Help(self):
-        base_command_processor.BaseCommandProcessor.Help(self)
-        logging.info("Sample: build --target=aosp_sailfish-userdebug "
-                     "--branch=<branch name> --artifact-type=device")
diff --git a/harnesses/host_controller/command_processor/command_password.py b/harnesses/host_controller/command_processor/command_password.py
deleted file mode 100644
index c767f22..0000000
--- a/harnesses/host_controller/command_processor/command_password.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import getpass
-import logging
-
-from host_controller.command_processor import base_command_processor
-
-
-class CommandPassword(base_command_processor.BaseCommandProcessor):
-    """Command processor for password command.
-
-    Attributes:
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "password"
-    command_detail = "Sets password."
-
-    # @Override
-    def Run(self, arg_line):
-        """Gets a new password."""
-        new_password = getpass.getpass()
-        if new_password:
-            self.console.password.value = new_password
-            logging.info("new password set.")
-        else:
-            logging.warn("password is not updated.")
-
-    def Help(self):
-        base_command_processor.BaseCommandProcessor.Help(self)
diff --git a/harnesses/host_controller/command_processor/command_release.py b/harnesses/host_controller/command_processor/command_release.py
deleted file mode 100644
index 71eccbf..0000000
--- a/harnesses/host_controller/command_processor/command_release.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import datetime
-import logging
-import stat
-import threading
-import zipfile
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-
-_REPACKAGE_ADDITIONAL_FILE_LIST = [
-    "android-vtslab/testcases/DATA/app/WifiUtil/WifiUtil.apk",
-    "android-vtslab/testcases/DATA/vtslab-gcs.json",
-    "android-vtslab/testcases/DATA/xml/media_profiles_vendor.xml",
-    "android-vtslab/testcases/host_controller/build/client_secrets.json",
-    "android-vtslab/testcases/host_controller/build/credentials",
-]
-
-_REPACKAGE_ADDITIONAL_BIN_LIST = [
-    "android-vtslab/bin/adb",
-]
-
-# Path to the version.txt file in the fetched vtslab package zip.
-_VERSION_INFO_FILE_PATH = "android-vtslab/testcases/version.txt"
-
-# List of strings for supported ak versions.
-AK_VERSIONS = ["8.0.0", "8.0.1", "8.1.0", "9", "O", "OMR1", "P", "Q"]
-
-for version in AK_VERSIONS:
-    file_path = "android-vtslab/testcases/DATA/ak/.%s.ak" % version
-    _REPACKAGE_ADDITIONAL_FILE_LIST.append(file_path)
-    file_path += ".pub"
-    _REPACKAGE_ADDITIONAL_FILE_LIST.append(file_path)
-
-
-class CommandRelease(base_command_processor.BaseCommandProcessor):
-    """Command processor for update command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-        _timers: dict, instances of scheduled threading.Timer.
-                 Uses timestamp("%H:%M") string as a key.
-        _vtslab_package_version: string, version information of the fetched
-                                 vtslab package.
-                                 (<git commit timestamp>:<git commit hash value>)
-    """
-
-    command = "release"
-    command_detail = "Release HC. Used for fetching HC package from PAB and uploading to GCS."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for update command."""
-        self._timers = {}
-        self._vtslab_package_version = ""
-        self.arg_parser.add_argument(
-            "--schedule-for",
-            default="17:00",
-            help="Schedule to update HC package at the given time every day. "
-            "Example: --schedule-for=%%H:%%M")
-        self.arg_parser.add_argument(
-            "--account_id",
-            default=common._DEFAULT_ACCOUNT_ID,
-            help="Partner Android Build account_id to use.")
-        self.arg_parser.add_argument(
-            "--branch", help="Branch to grab the artifact from.")
-        self.arg_parser.add_argument(
-            "--target",
-            help="a comma-separate list of build target product(s).")
-        self.arg_parser.add_argument(
-            "--dest",
-            help="Google Cloud Storage URL to which the file is uploaded.")
-        self.arg_parser.add_argument(
-            "--cancel", help="Cancel all scheduled release if given.")
-        self.arg_parser.add_argument(
-            "--print-all", help="Print all scheduled timers.")
-        self.arg_parser.add_argument(
-            "--additional_files_bucket",
-            default="gs://vtslab-release",
-            help="GCS bucket URL from where to fetch the additional files "
-            "required for HC to run properly.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Schedule a host_constroller package release at a certain time."""
-        args = self.arg_parser.ParseLine(arg_line)
-
-        if args.print_all:
-            logging.info(self._timers)
-            return
-
-        if not args.cancel:
-            if args.schedule_for == "now":
-                self.ReleaseCallback(args.schedule_for, args.account_id,
-                                     args.branch, args.target, args.dest,
-                                     args.additional_files_bucket)
-                return
-
-            elif len(args.schedule_for.split(":")) != 2:
-                logging.error("The format of --schedule-for flag is %H:%M")
-                return False
-
-            if (int(args.schedule_for.split(":")[0]) not in range(24)
-                    or int(args.schedule_for.split(":")[-1]) not in range(60)):
-                logging.error("The value of --schedule-for flag must be in "
-                              "\"00:00\"..\"23:59\" inclusive")
-                return False
-
-            if not args.schedule_for in self._timers:
-                delta_time = datetime.datetime.now().replace(
-                    hour=int(args.schedule_for.split(":")[0]),
-                    minute=int(args.schedule_for.split(":")[-1]),
-                    second=0,
-                    microsecond=0) - datetime.datetime.now()
-
-                if delta_time <= datetime.timedelta(0):
-                    delta_time += datetime.timedelta(days=1)
-
-                self._timers[args.schedule_for] = threading.Timer(
-                    delta_time.total_seconds(), self.ReleaseCallback,
-                    (args.schedule_for, args.account_id, args.branch,
-                     args.target, args.dest, args.additional_files_bucket))
-                self._timers[args.schedule_for].daemon = True
-                self._timers[args.schedule_for].start()
-                logging.info("Release job scheduled for {}".format(
-                    datetime.datetime.now() + delta_time))
-        else:
-            self.CancelAllEvents()
-
-    def FetchVtslab(self, account_id, branch, target, bucket):
-        """Fetchs android-vtslab.zip and return the fetched file path.
-
-        Args:
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-            bucket: string, GCS bucket URL from where to fetch the additional
-                    files.
-
-        Returns:
-            path to the fetched android-vtslab.zip file. None if the fetching
-            has failed.
-        """
-        self.console.build_provider["pab"].Authenticate()
-        fetched_path = self.console.build_provider[
-            "pab"].FetchLatestBuiltHCPackage(account_id, branch, target)
-
-        with zipfile.ZipFile(fetched_path, mode="a") as vtslab_package:
-            if _VERSION_INFO_FILE_PATH in vtslab_package.namelist():
-                self._vtslab_package_version = vtslab_package.open(
-                    _VERSION_INFO_FILE_PATH).readline().strip()
-            else:
-                self._vtslab_package_version = ""
-
-            for path in _REPACKAGE_ADDITIONAL_FILE_LIST:
-                additional_file = os.path.join(bucket, path)
-                self.console.build_provider["gcs"].Fetch(additional_file)
-                try:
-                    logging.info("Adding file %s into %s" %
-                                 (os.path.basename(path),
-                                  os.path.basename(fetched_path)))
-                    additional_file_path = self.console.build_provider[
-                        "gcs"].GetAdditionalFile(os.path.basename(path))
-                    vtslab_package.write(additional_file_path, path)
-                except KeyError as e:
-                    logging.exception(e)
-
-            for bin in _REPACKAGE_ADDITIONAL_BIN_LIST:
-                additional_bin = os.path.join(bucket, bin)
-                self.console.build_provider["gcs"].Fetch(additional_bin)
-                try:
-                    logging.info("Adding executable %s into %s" %
-                                 (os.path.basename(bin),
-                                  os.path.basename(fetched_path)))
-                    additional_bin_path = self.console.build_provider[
-                        "gcs"].GetAdditionalFile(os.path.basename(bin))
-                    bin_mode = os.stat(additional_bin_path).st_mode
-                    os.chmod(
-                        additional_bin_path,
-                        bin_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
-                    vtslab_package.write(additional_bin_path, bin)
-                except KeyError as e:
-                    logging.exception(e)
-
-        return fetched_path
-
-    def UploadVtslab(self, package_file_path, dest_path):
-        """upload repackaged vtslab package to GCS.
-
-        Args:
-            package_file_path: string, path to the vtslab package file.
-            dest_path: string, URL to GCS.
-        """
-        if dest_path and dest_path.endswith("/"):
-            split_list = os.path.basename(package_file_path).split(".")
-            if self._vtslab_package_version:
-                try:
-                    timestamp, hash = self._vtslab_package_version.split(":")
-                    split_list[0] += "-%s-%s" % (timestamp, hash)
-                except ValueError as e:
-                    logging.exception(e)
-                    split_list[0] += "-{timestamp_date}"
-            else:
-                split_list[0] += "-{timestamp_date}"
-            dest_path += ".".join(split_list)
-
-        upload_command = "upload --src %s --dest %s" % (package_file_path,
-                                                        dest_path)
-        self.console.onecmd(upload_command)
-
-    def ReleaseCallback(self, schedule_for, account_id, branch, target, dest,
-                        bucket):
-        """Target function for the scheduled Timer.
-
-        Args:
-            schedule_for: string, scheduled time for this Timer.
-                          Format: "%H:%M" (from "00:00" to  "23:59" inclusive)
-            account_id: string, Partner Android Build account_id to use.
-            branch: string, branch to grab the artifact from.
-            targets: string, a comma-separate list of build target product(s).
-            dest: string, URL to GCS.
-            bucket: string, GCS bucket URL from where to fetch the additional
-                    files.
-        """
-        fetched_path = self.FetchVtslab(account_id, branch, target, bucket)
-        if fetched_path:
-            self.UploadVtslab(fetched_path, dest)
-
-        if schedule_for != "now":
-            delta_time = datetime.datetime.now().replace(
-                hour=int(schedule_for.split(":")[0]),
-                minute=int(schedule_for.split(":")[-1]),
-                second=0,
-                microsecond=0) - datetime.datetime.now() + datetime.timedelta(
-                    days=1)
-            self._timers[schedule_for] = threading.Timer(
-                delta_time.total_seconds(), self.ReleaseCallback,
-                (schedule_for, account_id, branch, target, dest, bucket))
-            self._timers[schedule_for].daemon = True
-            self._timers[schedule_for].start()
-            logging.info("Release job scheduled for {}".format(
-                datetime.datetime.now() + delta_time))
-
-    def CancelAllEvents(self):
-        """Cancel all scheduled Timer."""
-        for scheduled_time in self._timers:
-            self._timers[scheduled_time].cancel()
-        self._timers = {}
diff --git a/harnesses/host_controller/command_processor/command_repack.py b/harnesses/host_controller/command_processor/command_repack.py
deleted file mode 100644
index 98a9168..0000000
--- a/harnesses/host_controller/command_processor/command_repack.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-import re
-import shutil
-import tempfile
-import zipfile
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-
-# Name of android-info.txt file which contains prerequisite data for the img.zip
-_ANDROID_INFO_TXT_FILENAME = "android-info.txt"
-
-
-class CommandRepack(base_command_processor.BaseCommandProcessor):
-    """Command processor for repack command."""
-
-    command = "repack"
-    command_detail = ("Repackage the whole device image files, including GSI "
-                      "images if exist.")
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for repack command."""
-        self.arg_parser.add_argument(
-            "--dest",
-            default="gs://vts-release/img_package",
-            help="Google Cloud Storage base URL to which the file is uploaded."
-        )
-        self.arg_parser.add_argument(
-            "--additional_files",
-            nargs="*",
-            default=[],
-            help="Additional files that need to be added to the zip file.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Runs an repack command."""
-        args = self.arg_parser.ParseLine(arg_line)
-        try:
-            device_zipfile_path = self.console.device_image_info[
-                common.FULL_ZIPFILE]
-        except KeyError as e:
-            logging.exception(e)
-            logging.error(
-                "please execute this command after fetching at least one "
-                "device img set.")
-            return False
-
-        with zipfile.ZipFile(device_zipfile_path, 'r') as zip_ref:
-            zip_ref.extract(_ANDROID_INFO_TXT_FILENAME,
-                            common.FULL_ZIPFILE_DIR)
-            self.console.tools_info[_ANDROID_INFO_TXT_FILENAME] = os.path.join(
-                common.FULL_ZIPFILE_DIR, _ANDROID_INFO_TXT_FILENAME)
-
-        tempdir_base = os.path.join(os.getcwd(), "tmp")
-        tmpdir_rezip = tempfile.mkdtemp(dir=tempdir_base)
-
-        dest_url_base, new_zipfile_name = os.path.split(
-            self.GetDestURL(args.dest))
-
-        new_zipfile_path = os.path.join(tmpdir_rezip, new_zipfile_name)
-        with zipfile.ZipFile(
-                new_zipfile_path, "w", allowZip64=True) as zip_ref:
-            for img_path in self.console.device_image_info:
-                if img_path not in (common.FULL_ZIPFILE,
-                                    common.FULL_ZIPFILE_DIR,
-                                    common.GSI_ZIPFILE,
-                                    common.GSI_ZIPFILE_DIR):
-                    logging.info("Adding %s into the zip archive.", img_path)
-                    zip_ref.write(
-                        self.console.device_image_info[img_path],
-                        img_path,
-                        compress_type=zipfile.ZIP_DEFLATED)
-            if args.additional_files:
-                additional_file_list = self.ReplaceVars(args.additional_files)
-                for file_path in additional_file_list:
-                    file_name = os.path.basename(file_path)
-                    logging.info(
-                        "Adding additional file %s into the zip archive.",
-                        file_name)
-                    zip_ref.write(
-                        file_path,
-                        os.path.join(common._ADDITIONAL_FILES_DIR, file_name),
-                        compress_type=zipfile.ZIP_DEFLATED)
-            zip_ref.write(
-                self.console.tools_info[_ANDROID_INFO_TXT_FILENAME],
-                _ANDROID_INFO_TXT_FILENAME,
-                compress_type=zipfile.ZIP_DEFLATED)
-
-        logging.info("Repackaged image set: %s", new_zipfile_path)
-        logging.info("Uploading %s to %s.", new_zipfile_name, dest_url_base)
-
-        self.console.onecmd("upload --src=%s --dest=%s/%s" %
-                            (new_zipfile_path, dest_url_base,
-                             new_zipfile_name))
-
-        shutil.rmtree(tmpdir_rezip, ignore_errors=True)
-
-    def GetDestURL(self, dest_base_url):
-        """Generates the destination URL to GCS bucket based on dest_base_url.
-
-        Args:
-            dest_base_url: string, URL to a GCS bucket.
-
-        Returns:
-            A string, device/gsi img sets branch/target info and the final
-            .zip file name appended to the dest_base_url.
-        """
-        device_branch = re.sub(
-            "git_", "", self.console.detailed_fetch_info["device"]["branch"])
-        device_target = self.console.detailed_fetch_info["device"]["target"]
-        device_build_id = self.console.detailed_fetch_info["device"][
-            "build_id"]
-        new_zipfile_name = ("%s_%s_%s.zip" % (device_branch, device_target,
-                                              device_build_id))
-        dest_url_base = os.path.join(dest_base_url, device_branch,
-                                     device_target)
-
-        if common.GSI_ZIPFILE in self.console.device_image_info:
-            gsi_branch = re.sub(
-                "git_", "", self.console.detailed_fetch_info["gsi"]["branch"])
-            gsi_target = self.console.detailed_fetch_info["gsi"]["target"]
-            gsi_build_id = self.console.detailed_fetch_info["gsi"]["build_id"]
-            new_zipfile_name = new_zipfile_name[:-4] + ("_%s_%s_%s.zip" % (
-                gsi_branch, gsi_target, gsi_build_id))
-            dest_url_base = os.path.join(dest_url_base, gsi_branch, gsi_target)
-
-        ret = os.path.join(dest_url_base, new_zipfile_name)
-        self.console.repack_dest_path = ret
-        return ret
diff --git a/harnesses/host_controller/command_processor/command_repack_test.py b/harnesses/host_controller/command_processor/command_repack_test.py
deleted file mode 100644
index 6eca960..0000000
--- a/harnesses/host_controller/command_processor/command_repack_test.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import common
-from host_controller.command_processor import command_repack
-
-_SAMPLE_COMMAND_REPACK = "repack --dest"
-
-
-class CommandRepackTest(unittest.TestCase):
-    """Tests for repack command processor"""
-
-    @mock.patch("host_controller.console.Console")
-    def testGetDestURLWithoutGSI(self, mock_console):
-        mock_console.detailed_fetch_info = {
-            "device": {
-                "branch": "git_device_branch",
-                "target": "device_userdebug",
-                "build_id": "1234567"
-            }
-        }
-        command = command_repack.CommandRepack()
-        command._SetUp(mock_console)
-        ret = command.GetDestURL("gs://bucket/base/url")
-
-        self.assertEqual(ret,
-                         "gs://bucket/base/url/device_branch/device_userdebug"
-                         "/device_branch_device_userdebug_1234567.zip")
-
-    @mock.patch("host_controller.console.Console")
-    def testGetDestURLWithGSI(self, mock_console):
-        mock_console.device_image_info = {common.GSI_ZIPFILE: ""}
-        mock_console.detailed_fetch_info = {
-            "device": {
-                "branch": "git_device_branch",
-                "target": "device-userdebug",
-                "build_id": "1234567"
-            },
-            "gsi": {
-                "branch": "git_aosp_gsi_branch",
-                "target": "gsi-userdebug",
-                "build_id": "2345678"
-            }
-        }
-
-        command = command_repack.CommandRepack()
-        command._SetUp(mock_console)
-        ret = command.GetDestURL("gs://bucket/base/url")
-
-        self.assertEqual(
-            ret, "gs://bucket/base/url/device_branch/device-userdebug/"
-            "aosp_gsi_branch/gsi-userdebug/device_branch_device-userdebug"
-            "_1234567_aosp_gsi_branch_gsi-userdebug_2345678.zip")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_repack.logging")
-    def testRepackFullDeviceImageAbsent(self, mock_logger, mock_console):
-        mock_console.device_image_info = {}
-        command = command_repack.CommandRepack()
-        command._SetUp(mock_console)
-        ret = command._Run("--dest=gs://bucket/path/")
-
-        self.assertFalse(ret)
-        mock_logger.error.assert_called_with(
-            "please execute this command after fetching at least"
-            " one device img set.")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_repack.zipfile")
-    @mock.patch("host_controller.command_processor.command_repack.os")
-    @mock.patch("host_controller.command_processor.command_repack.tempfile")
-    @mock.patch("host_controller.command_processor.command_repack.shutil")
-    def testRepackWithFullDeviceImage(self, mock_shutil, mock_tempfile,
-                                      mock_os, mock_zipfile, mock_console):
-        mock_zip_ref = mock.Mock()
-        mock_zip_ref.__enter__ = mock.Mock(return_value=mock_zip_ref)
-        mock_zip_ref.__exit__ = mock.Mock(return_value=None)
-        mock_zipfile.ZipFile.return_value = mock_zip_ref
-        mock_console.device_image_info = {
-            common.FULL_ZIPFILE: "/path/to/full-zipfile.zip",
-            "system.img": "/path/to/full-zipfile.zip.dir/system.img",
-            "odm.img": "/path/to/full-zipfile.zip.dir/odm.img"
-        }
-        mock_os.getcwd.return_value = "/abs/path/to/current/dir"
-        mock_os.path.split = os.path.split
-        command = command_repack.CommandRepack()
-        command.GetDestURL = mock.Mock(
-            return_value="gs://dest/gs/url/file.zip")
-        command._SetUp(mock_console)
-        ret = command._Run("--dest=gs://bucket/path/")
-
-        self.assertIsNone(ret)
-        mock_zip_ref.extract.assert_called_with("android-info.txt",
-                                                common.FULL_ZIPFILE_DIR)
-        mock_zip_ref.write.assert_any_call(
-            "/path/to/full-zipfile.zip.dir/system.img",
-            "system.img",
-            compress_type=mock.ANY)
-        mock_zip_ref.write.assert_any_call(
-            "/path/to/full-zipfile.zip.dir/odm.img",
-            "odm.img",
-            compress_type=mock.ANY)
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_repack.zipfile")
-    @mock.patch("host_controller.command_processor.command_repack.os")
-    @mock.patch("host_controller.command_processor.command_repack.tempfile")
-    @mock.patch("host_controller.command_processor.command_repack.shutil")
-    def testRepackWithAdditionalFiles(self, mock_shutil, mock_tempfile,
-                                      mock_os, mock_zipfile, mock_console):
-        mock_zip_ref = mock.Mock()
-        mock_zip_ref.__enter__ = mock.Mock(return_value=mock_zip_ref)
-        mock_zip_ref.__exit__ = mock.Mock(return_value=None)
-        mock_zipfile.ZipFile.return_value = mock_zip_ref
-        mock_console.device_image_info = {
-            common.FULL_ZIPFILE: "/path/to/full-zipfile.zip",
-            "system.img": "/path/to/full-zipfile.zip.dir/system.img",
-            "odm.img": "/path/to/full-zipfile.zip.dir/odm.img"
-        }
-        mock_os.getcwd.return_value = "/abs/path/to/current/dir"
-        mock_os.path.split = os.path.split
-        mock_os.path.join = os.path.join
-        mock_os.path.basename = os.path.basename
-        command = command_repack.CommandRepack()
-        command.GetDestURL = mock.Mock(
-            return_value="gs://dest/gs/url/file.zip")
-        command._SetUp(mock_console)
-        ret = command._Run(
-            "--dest=gs://bucket/path/ --additional_files /path/to/tmp/af1"
-            " /path/to/tmp/af2")
-
-        self.assertIsNone(ret)
-        mock_zip_ref.extract.assert_called_with("android-info.txt",
-                                                common.FULL_ZIPFILE_DIR)
-        mock_zip_ref.write.assert_any_call(
-            "/path/to/full-zipfile.zip.dir/system.img",
-            "system.img",
-            compress_type=mock.ANY)
-        mock_zip_ref.write.assert_any_call(
-            "/path/to/full-zipfile.zip.dir/odm.img",
-            "odm.img",
-            compress_type=mock.ANY)
-        mock_zip_ref.write.assert_any_call(
-            "/path/to/tmp/af1", "additional_file/af1", compress_type=mock.ANY)
-        mock_zip_ref.write.assert_any_call(
-            "/path/to/tmp/af2", "additional_file/af2", compress_type=mock.ANY)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/command_processor/command_reproduce.py b/harnesses/host_controller/command_processor/command_reproduce.py
deleted file mode 100644
index 7d4f68f..0000000
--- a/harnesses/host_controller/command_processor/command_reproduce.py
+++ /dev/null
@@ -1,301 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import imp  # Python v2 compatibility
-import logging
-import os
-import re
-import subprocess
-import zipfile
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.gcp import gcs_utils
-
-from vti.dashboard.proto import TestSuiteResultMessage_pb2 as SuiteResMsg
-from vti.test_serving.proto import TestScheduleConfigMessage_pb2 as SchedCfgMsg
-
-
-class CommandReproduce(base_command_processor.BaseCommandProcessor):
-    """Command processor for reproduce command.
-
-    Attributes:
-        campaign_common: campaign module. Dynamically imported since
-                         the campaign might need to be separated from the
-                         host controller itself.
-    """
-
-    command = "reproduce"
-    command_detail = ("Reproduce the test environment for a pre-run test and "
-                      "execute the tradefed command prompt of the fetched "
-                      "test suite. Setup the test env "
-                      "(fetching, flashing devices, etc) and retrieve "
-                      "formerly run test result to retry on, if the path "
-                      "to the report protobuf file is given.")
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for reproduce command."""
-        self.campaign_common = None
-        self.arg_parser.add_argument(
-            "--suite",
-            default="vts",
-            choices=("vts", "cts", "gts", "sts"),
-            help="To specify the type of a test suite to be run.")
-        self.arg_parser.add_argument(
-            "--report_path",
-            required=True,
-            help="Google Cloud Storage URL, the path of a report protobuf file."
-        )
-        self.arg_parser.add_argument(
-            "--serial",
-            default=None,
-            help="The serial numbers for flashing and testing. "
-            "Multiple serial numbers are separated by commas.")
-        self.arg_parser.add_argument(
-            "--automated_retry",
-            action="store_true",
-            help="Retries automatically until all test cases are passed "
-            "or the number or the failed test cases is the same as "
-            "the previous one.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Reproduces the test env of the pre-run test."""
-        args = self.arg_parser.ParseLine(arg_line)
-
-        if args.report_path:
-            gsutil_path = gcs_utils.GetGsutilPath()
-            if not gsutil_path:
-                logging.error(
-                    "Please check whether gsutil is installed and on your PATH"
-                )
-                return False
-
-            if (not args.report_path.startswith("gs://")
-                    or not gcs_utils.IsGcsFile(gsutil_path, args.report_path)):
-                logging.error("%s is not a valid GCS path.", args.report_path)
-                return False
-
-            dest_path = os.path.join("".join(self.ReplaceVars(["{tmp_dir}"])),
-                                     os.path.basename(args.report_path))
-            gcs_utils.Copy(gsutil_path, args.report_path, dest_path)
-            report_msg = SuiteResMsg.TestSuiteResultMessage()
-            try:
-                with open(dest_path, "r") as report_fd:
-                    report_msg.ParseFromString(report_fd.read())
-            except IOError as e:
-                logging.exception(e)
-                return False
-            serial = []
-            if args.serial:
-                serial = args.serial.split(",")
-            setup_command_list = self.GenerateSetupCommands(report_msg, serial)
-            if not setup_command_list:
-                suite_fetch_command = self.GenerateTestSuiteFetchCommand(
-                    report_msg)
-                if suite_fetch_command:
-                    setup_command_list.append(suite_fetch_command)
-            for command in setup_command_list:
-                self.console.onecmd(command)
-
-            if not self.GetResultFromGCS(gsutil_path, report_msg, args.suite):
-                return False
-        else:
-            logging.error("Path to a report protobuf file is required.")
-            return False
-
-        if args.suite not in self.console.test_suite_info:
-            logging.error("test_suite_info doesn't have '%s': %s", args.suite,
-                          self.console.test_suite_info)
-            return False
-
-        if args.automated_retry:
-            if self.campaign_common is None:
-                self.campaign_common = imp.load_source(
-                    'campaign_common',
-                    os.path.join(os.getcwd(), "host_controller", "campaigns",
-                                 "campaign_common.py"))
-            retry_command = self.campaign_common.GenerateRetryCommand(
-                report_msg.schedule_config.build_target[0].name,
-                report_msg.branch, report_msg.suite_name.lower(),
-                report_msg.suite_plan, serial)
-            self.console.onecmd(retry_command)
-        else:
-            subprocess.call(self.console.test_suite_info[args.suite])
-
-    def GenerateSetupCommands(self, report_msg, serial):
-        """Generates fetch, flash commands using fetch info from report_msg.
-
-        Args:
-            report_msg: pb2, contains fetch info of the test suite.
-            serial: list of string, serial number(s) of the device(s)
-                    to be flashed.
-
-        Returns:
-            list of string, console commands to fetch device/gsi images
-            and flash the device(s).
-        """
-        ret = []
-        schedule_config = report_msg.schedule_config
-        if not schedule_config.manifest_branch:
-            logging.error("Report contains no fetch information. "
-                          "Aborting pre-test setups on the device(s).")
-        elif not serial:
-            logging.error("Device serial number(s) not given. "
-                          "Aborting pre-test setups on the device(s).")
-        else:
-            try:
-                build_target_msg = schedule_config.build_target[0]
-                test_schedule_msg = build_target_msg.test_schedule[0]
-            except IndexError as e:
-                logging.exception(e)
-                return ret
-            kwargs = {}
-            # common fetch info
-            kwargs["shards"] = str(len(serial))
-            kwargs["test_name"] = "%s/%s" % (report_msg.suite_name.lower(),
-                                             report_msg.suite_plan)
-            kwargs["serial"] = serial
-
-            # fetch info for device images
-            kwargs["manifest_branch"] = schedule_config.manifest_branch
-            kwargs["build_target"] = build_target_msg.name
-            kwargs["build_id"] = report_msg.vendor_build_id
-            kwargs["pab_account_id"] = schedule_config.pab_account_id
-            if kwargs["manifest_branch"].startswith("gs://"):
-                kwargs[
-                    "build_storage_type"] = SchedCfgMsg.BUILD_STORAGE_TYPE_GCS
-            else:
-                kwargs[
-                    "build_storage_type"] = SchedCfgMsg.BUILD_STORAGE_TYPE_PAB
-            kwargs["require_signed_device_build"] = (
-                build_target_msg.require_signed_device_build)
-            kwargs["has_bootloader_img"] = build_target_msg.has_bootloader_img
-            kwargs["has_radio_img"] = build_target_msg.has_radio_img
-
-            # fetch info for gsi images and gsispl command
-            kwargs["gsi_branch"] = test_schedule_msg.gsi_branch
-            kwargs["gsi_build_target"] = test_schedule_msg.gsi_build_target
-            kwargs["gsi_build_id"] = report_msg.gsi_build_id
-            kwargs["gsi_pab_account_id"] = test_schedule_msg.gsi_pab_account_id
-            if kwargs["gsi_branch"].startswith("gs://"):
-                kwargs["gsi_storage_type"] = SchedCfgMsg.BUILD_STORAGE_TYPE_GCS
-            else:
-                kwargs["gsi_storage_type"] = SchedCfgMsg.BUILD_STORAGE_TYPE_PAB
-            kwargs["gsi_vendor_version"] = test_schedule_msg.gsi_vendor_version
-
-            # fetch info for test suite
-            kwargs["test_build_id"] = report_msg.build_id
-            kwargs["test_branch"] = report_msg.branch
-            kwargs["test_build_target"] = report_msg.target
-            if kwargs["test_build_target"].endswith(".zip"):
-                kwargs["test_build_target"] = kwargs["test_build_target"][:-4]
-            kwargs[
-                "test_pab_account_id"] = test_schedule_msg.test_pab_account_id
-            if kwargs["test_branch"].startswith("gs://"):
-                kwargs[
-                    "test_storage_type"] = SchedCfgMsg.BUILD_STORAGE_TYPE_GCS
-            else:
-                kwargs["gsi_storage_type"] = SchedCfgMsg.BUILD_STORAGE_TYPE_PAB
-
-            self.campaign_common = imp.load_source(
-                "campaign_common",
-                os.path.join(os.getcwd(), "host_controller", "campaigns",
-                             "campaign_common.py"))
-            fetch_commands_result, gsi = self.campaign_common.EmitFetchCommands(
-                **kwargs)
-            ret.extend(fetch_commands_result)
-            flash_commands_result = self.campaign_common.EmitFlashCommands(
-                gsi, **kwargs)
-            ret.extend(flash_commands_result)
-
-        return ret
-
-    def GenerateTestSuiteFetchCommand(self, report_msg):
-        """Generates a fetch command line using fetch info from report_msg.
-
-        Args:
-            report_msg: pb2, contains fetch info of the test suite.
-
-        Returns:
-            string, console command to fetch a test suite artifact.
-        """
-        ret = "fetch"
-
-        if report_msg.branch.startswith("gs://"):
-            ret += " --type=gcs --path=%s/%s --set_suite_as=%s" % (
-                report_msg.branch, report_msg.target,
-                report_msg.suite_name.lower())
-        else:
-            ret += (" --type=pab --branch=%s --target=%s --build_id=%s"
-                    " --artifact_name=android-%s.zip") % (
-                        report_msg.branch, report_msg.target,
-                        report_msg.build_id, report_msg.suite_name.lower())
-            try:
-                build_target_msg = report_msg.schedule_config.build_target[0]
-                test_schedule_msg = build_target_msg.test_schedule[0]
-            except IndexError as e:
-                logging.exception(e)
-                test_schedule_msg = SchedCfgMsg.TestScheduleConfigMessage()
-            if test_schedule_msg.test_pab_account_id:
-                ret += " --account_id=%s" % test_schedule_msg.test_pab_account_id
-            else:
-                ret += " --account_id=%s" % common._DEFAULT_ACCOUNT_ID_INTERNAL
-
-        return ret
-
-    def GetResultFromGCS(self, gsutil_path, report_msg, suite):
-        """Downloads results.zip from GCS and unzip it to the results directory.
-
-        Args:
-            gsutil_path: string, path to the gsutil binary.
-            report_msg: pb2, contains fetch info of the test suite.
-            suite: string, specifies the type of test suite fetched.
-
-        Returns:
-            True if successful. False otherwise
-        """
-        result_base_path = report_msg.result_path
-        try:
-            tools_path = os.path.dirname(self.console.test_suite_info[suite])
-        except KeyError as e:
-            logging.exception(e)
-            return False
-        local_results_path = os.path.join(tools_path,
-                                          common._RESULTS_BASE_PATH)
-
-        if not os.path.exists(local_results_path):
-            os.mkdir(local_results_path)
-
-        result_path_list = gcs_utils.List(gsutil_path, result_base_path)
-        result_zip_url = ""
-        for result_path in result_path_list:
-            if re.match(".*results_.*\.zip", result_path):
-                result_zip_url = result_path
-                break
-
-        if (not result_zip_url or not gcs_utils.Copy(
-                gsutil_path, result_zip_url, local_results_path)):
-            logging.error("Fail to copy from %s.", result_base_path)
-            return False
-
-        result_zip_local_path = os.path.join(local_results_path,
-                                             os.path.basename(result_zip_url))
-        with zipfile.ZipFile(result_zip_local_path, mode="r") as zip_ref:
-            zip_ref.extractall(local_results_path)
-
-        return True
diff --git a/harnesses/host_controller/command_processor/command_reproduce_test.py b/harnesses/host_controller/command_processor/command_reproduce_test.py
deleted file mode 100644
index a5ab4f6..0000000
--- a/harnesses/host_controller/command_processor/command_reproduce_test.py
+++ /dev/null
@@ -1,353 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import common
-from host_controller.command_processor import command_reproduce
-
-
-def emit_fetch_commands(**kwargs):
-    gsi = "gsi_branch" in kwargs
-    return [], gsi
-
-
-def emit_flash_commands(gsi, **kwargs):
-    return []
-
-
-class CommandReproduceTest(unittest.TestCase):
-    """Tests for reproduce command processor"""
-
-    def setUp(self):
-        mock_console = mock.Mock()
-        self._command = command_reproduce.CommandReproduce()
-        self._command._SetUp(mock_console)
-
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testGenerateSetupCommandsNoFetchInfo(self, mock_logging):
-        mock_msg = mock.Mock()
-        mock_msg.schedule_config.manifest_branch = ""
-        ret = self._command.GenerateSetupCommands(mock_msg,
-                                                  ["serial1", "serial2"])
-        self.assertEqual(ret, [])
-        mock_logging.error.assert_called_with(
-            "Report contains no fetch information. "
-            "Aborting pre-test setups on the device(s).")
-
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testGenerateSetupCommandsNoSerial(self, mock_logging):
-        mock_msg = mock.Mock()
-        mock_msg.schedule_config.manifest_branch = "some_branch"
-        ret = self._command.GenerateSetupCommands(mock_msg, [])
-        self.assertEqual(ret, [])
-        mock_logging.error.assert_called_with(
-            "Device serial number(s) not given. "
-            "Aborting pre-test setups on the device(s).")
-
-    @mock.patch("host_controller.command_processor.command_reproduce.imp")
-    def testGenerateSetupCommands(self, mock_imp):
-        mock_campiagn = mock.Mock()
-        mock_campiagn.EmitFetchCommands.side_effect = emit_fetch_commands
-        mock_campiagn.EmitFlashCommands.side_effect = emit_flash_commands
-        mock_imp.load_source.return_value = mock_campiagn
-        mock_msg = mock.Mock()
-        mock_msg.suite_name = "vts"
-        mock_msg.suite_plan = "vts"
-        mock_msg.vendor_build_id = "1234567"
-        mock_msg.gsi_build_id = "2345678"
-        mock_msg.build_id = "3456789"
-        mock_msg.branch = "git_whatever-release"
-        mock_msg.target = "test_suites_bitness"
-        mock_msg.schedule_config.manifest_branch = "git_whatever-release"
-        mock_msg.schedule_config.pab_account_id = common._DEFAULT_ACCOUNT_ID_INTERNAL
-        mock_msg.schedule_config.build_target = []
-        mock_build_target_msg = mock.Mock()
-        mock_build_target_msg.name = "somefish-userdebug"
-        mock_build_target_msg.test_schedule = []
-        mock_build_target_msg.require_signed_device_build = False
-        mock_build_target_msg.has_bootloader_img = True
-        mock_build_target_msg.has_radio_img = True
-        mock_test_schedule_msg = mock.Mock()
-        mock_test_schedule_msg.gsi_branch = "git_whatever-gsi"
-        mock_test_schedule_msg.gsi_build_target = "aosp_bitness-userdebug"
-        mock_test_schedule_msg.gsi_pab_account_id = common._DEFAULT_ACCOUNT_ID
-        mock_test_schedule_msg.test_pab_account_id = common._DEFAULT_ACCOUNT_ID
-        mock_build_target_msg.test_schedule.append(mock_test_schedule_msg)
-        mock_msg.schedule_config.build_target.append(mock_build_target_msg)
-        self._command.GenerateSetupCommands(mock_msg, ["serial1", "serial2"])
-        mock_campiagn.EmitFetchCommands.assert_called_with(
-            build_id="1234567",
-            build_storage_type=1,
-            build_target="somefish-userdebug",
-            gsi_branch="git_whatever-gsi",
-            gsi_build_id="2345678",
-            gsi_build_target="aosp_bitness-userdebug",
-            gsi_pab_account_id="543365459",
-            gsi_storage_type=1,
-            gsi_vendor_version=mock.ANY,
-            has_bootloader_img=True,
-            has_radio_img=True,
-            manifest_branch="git_whatever-release",
-            pab_account_id="541462473",
-            require_signed_device_build=False,
-            serial=["serial1", "serial2"],
-            shards="2",
-            test_branch="git_whatever-release",
-            test_build_id="3456789",
-            test_build_target="test_suites_bitness",
-            test_name="vts/vts",
-            test_pab_account_id="543365459")
-        mock_campiagn.EmitFlashCommands.assert_called_with(
-            True,
-            build_id="1234567",
-            build_storage_type=1,
-            build_target="somefish-userdebug",
-            gsi_branch="git_whatever-gsi",
-            gsi_build_id="2345678",
-            gsi_build_target="aosp_bitness-userdebug",
-            gsi_pab_account_id="543365459",
-            gsi_storage_type=1,
-            gsi_vendor_version=mock.ANY,
-            has_bootloader_img=True,
-            has_radio_img=True,
-            manifest_branch="git_whatever-release",
-            pab_account_id="541462473",
-            require_signed_device_build=False,
-            serial=["serial1", "serial2"],
-            shards="2",
-            test_branch="git_whatever-release",
-            test_build_id="3456789",
-            test_build_target="test_suites_bitness",
-            test_name="vts/vts",
-            test_pab_account_id="543365459")
-
-    def testGenerateTestSuiteFetchCommandGCS(self):
-        report_msg = mock.Mock()
-        report_msg.branch = "gs://bucket/path/to/vts/release"
-        report_msg.target = "android-vts.zip"
-        report_msg.suite_name = "VTS"
-        ret = self._command.GenerateTestSuiteFetchCommand(report_msg)
-        self.assertEqual(
-            ret, "fetch --type=gcs "
-            "--path=gs://bucket/path/to/vts/release/android-vts.zip "
-            "--set_suite_as=vts")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.SchedCfgMsg")
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testGenerateTestSuiteFetchCommandIndexError(self, mock_logging,
-                                                    mock_sched_cfg_msg):
-        report_msg = mock.Mock()
-        report_msg.branch = "git_whatever-release"
-        report_msg.target = "test_suites_bitness"
-        report_msg.build_id = "1234567"
-        report_msg.suite_name = "VTS"
-        report_msg.schedule_config.build_target = []
-        mock_test_schedule_msg = mock.Mock()
-        mock_test_schedule_msg.test_pab_account_id = "1234567898765"
-        mock_sched_cfg_msg.TestScheduleConfigMessage.return_value = (
-            mock_test_schedule_msg)
-        ret = self._command.GenerateTestSuiteFetchCommand(report_msg)
-        mock_logging.exception.assert_called()
-        self.assertEqual(ret, "fetch --type=pab --branch=git_whatever-release "
-                         "--target=test_suites_bitness --build_id=1234567 "
-                         "--artifact_name=android-vts.zip "
-                         "--account_id=1234567898765")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.SchedCfgMsg")
-    def testGenerateTestSuiteFetchCommandPAB(self, mock_sched_cfg_msg):
-        report_msg = mock.Mock()
-        report_msg.branch = "git_whatever-release"
-        report_msg.target = "test_suites_bitness"
-        report_msg.build_id = "1234567"
-        report_msg.suite_name = "VTS"
-        mock_build_target_msg = mock.Mock()
-        mock_test_schedule_msg = mock.Mock()
-        mock_test_schedule_msg.test_pab_account_id = "987654321"
-        mock_build_target_msg.test_schedule = []
-        mock_build_target_msg.test_schedule.append(mock_test_schedule_msg)
-        report_msg.schedule_config.build_target = []
-        report_msg.schedule_config.build_target.append(mock_build_target_msg)
-        mock_sched_cfg_msg.TestScheduleConfigMessage.return_value = (
-            mock_test_schedule_msg)
-
-        ret = self._command.GenerateTestSuiteFetchCommand(report_msg)
-        self.assertEqual(ret, "fetch --type=pab --branch=git_whatever-release "
-                         "--target=test_suites_bitness --build_id=1234567 "
-                         "--artifact_name=android-vts.zip "
-                         "--account_id=987654321")
-
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testGetResultFromGCSNoTestSuite(self, mock_logging):
-        report_msg = mock.Mock()
-        report_msg.result_path = "gs://bucket/path/to/log/files"
-        self._command.console.test_suite_info = {}
-        ret = self._command.GetResultFromGCS("/mock_bin/gsutil", report_msg,
-                                             "vts")
-        self.assertFalse(ret)
-        mock_logging.exception.assert_called()
-
-    @mock.patch("host_controller.command_processor.command_reproduce.os")
-    def testGetResultFromGCSMkdirResults(self, mock_os):
-        report_msg = mock.Mock()
-        report_msg.result_path = "gs://bucket/path/to/log/files"
-        self._command.console.test_suite_info = {
-            "vts": "tmp/android-vts/tools/vts-tradefed"
-        }
-        mock_os.path.exists.return_value = False
-        mock_os.path.join = os.path.join
-        mock_os.path.dirname = os.path.dirname
-        self._command.GetResultFromGCS("/mock_bin/gsutil", report_msg, "vts")
-        mock_os.mkdir.assert_called_with("tmp/android-vts/tools/../results")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_reproduce.os")
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testGetResultFromGCSNoResult(self, mock_logging, mock_os,
-                                     mock_gcs_util):
-        report_msg = mock.Mock()
-        report_msg.result_path = "gs://bucket/path/to/log/files"
-        self._command.console.test_suite_info = {
-            "vts": "tmp/android-vts/tools/vts-tradefed"
-        }
-        mock_gcs_util.List.return_value = [
-            "some_log1.zip", "some_log2.zip", "not_a_result.zip"
-        ]
-        ret = self._command.GetResultFromGCS("/mock_bin/gsutil", report_msg,
-                                             "vts")
-        self.assertFalse(ret)
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_reproduce.os")
-    @mock.patch("host_controller.command_processor.command_reproduce.zipfile")
-    def testGetResultFromGCS(self, mock_zipfile, mock_os, mock_gcs_util):
-        report_msg = mock.Mock()
-        report_msg.result_path = "gs://bucket/path/to/log/files"
-        self._command.console.test_suite_info = {
-            "vts": "tmp/android-vts/tools/vts-tradefed"
-        }
-        mock_zip_ref = mock.Mock()
-        mock_zip_ref.__enter__ = mock.Mock(return_value=mock_zip_ref)
-        mock_zip_ref.__exit__ = mock.Mock(return_value=None)
-        mock_zipfile.ZipFile.return_value = mock_zip_ref
-        mock_gcs_util.List.return_value = [
-            "some_log1.zip", "some_log2.zip", "results_some_hash.zip"
-        ]
-        mock_gcs_util.Copy.return_value = True
-        mock_os.path.join = os.path.join
-        mock_os.path.exists.return_value = False
-        mock_os.path.dirname = os.path.dirname
-        ret = self._command.GetResultFromGCS("/mock_bin/gsutil", report_msg,
-                                             "vts")
-        self.assertTrue(ret)
-        mock_zip_ref.extractall.assert_called_with(
-            "tmp/android-vts/tools/../results")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testCommandReproduceGsutilAbsent(self, mock_logging, mock_gcs_util):
-        mock_gcs_util.GetGsutilPath.return_value = ""
-        ret = self._command._Run(
-            "--report_path=gs://bucket/path/to/report/file")
-        self.assertFalse(ret)
-        mock_logging.error.assert_called_with(
-            "Please check whether gsutil is installed and on your PATH")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_reproduce.logging")
-    def testCommandReproduceInvalidURL(self, mock_logging, mock_gcs_util):
-        mock_gcs_util.GetGsutilPath.return_value = "/mock_bin/gsutil"
-        ret = self._command._Run("--report_path=/some/path/to/report/file")
-        self.assertFalse(ret)
-        mock_logging.error.assert_called_with("%s is not a valid GCS path.",
-                                              "/some/path/to/report/file")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.gcs_utils")
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.open",
-        new_callable=mock.mock_open)
-    @mock.patch("host_controller.command_processor.command_reproduce.imp")
-    def testCommandReproduceAutomatedRetry(self, mock_imp, mock_open,
-                                           mock_gcs_util):
-        mock_gcs_util.GetGsutilPath.return_value = "/mock_bin/gsutil"
-        mock_gcs_util.IsGcsFile.return_value = True
-        mock_gcs_util.Copy = mock.Mock(return_value=True)
-        command_reproduce.SuiteResMsg.ParseFromString = mock.Mock(
-            return_value={})
-        self._command.console.test_suite_info = {
-            "vts": "tmp/android-vts/tools/vts-tradefed"
-        }
-        mock_campiagn = mock.Mock()
-        mock_imp.load_source.return_value = mock_campiagn
-        self._command.ReplaceVars = mock.Mock(return_value="tmp")
-        self._command.GetResultFromGCS = mock.Mock(return_value=True)
-        self._command.GenerateSetupCommands = mock.Mock(return_value=[])
-        self._command.GenerateTestSuiteFetchCommand = mock.Mock(
-            return_value=[])
-        ret = self._command._Run("--report_path=gs://some/path/to/report/file"
-                                 " --serial=device1 --automated_retry")
-        self.assertIsNone(ret)
-        self._command.console.onecmd.assert_called_with(
-            "retry --suite vts  --serial device1")
-
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.gcs_utils")
-    @mock.patch(
-        "host_controller.command_processor.command_reproduce.open",
-        new_callable=mock.mock_open)
-    @mock.patch("host_controller.command_processor.command_reproduce.imp")
-    def testCommandReproduceAutomatedRetryShardOption(
-            self, mock_imp, mock_open, mock_gcs_util):
-        mock_gcs_util.GetGsutilPath.return_value = "/mock_bin/gsutil"
-        mock_gcs_util.IsGcsFile.return_value = True
-        mock_gcs_util.Copy = mock.Mock(return_value=True)
-        command_reproduce.SuiteResMsg.ParseFromString = mock.Mock()
-        self._command.console.test_suite_info = {
-            "vts": "tmp/android-vts/tools/vts-tradefed"
-        }
-        mock_campiagn = mock.Mock()
-        mock_campiagn.GetVersion.return_value = 8.0
-        mock_imp.load_source.return_value = mock_campiagn
-        self._command.ReplaceVars = mock.Mock(return_value="tmp")
-        self._command.GetResultFromGCS = mock.Mock(return_value=True)
-        self._command.GenerateSetupCommands = mock.Mock(return_value=[])
-        self._command.GenerateTestSuiteFetchCommand = mock.Mock(
-            return_value=[])
-        ret = self._command._Run(
-            "--suite=vts --report_path=gs://some/path/to/report/file"
-            " --serial=device1,device2 --automated_retry")
-        self.assertIsNone(ret)
-        self._command.console.onecmd.assert_called_with(
-            "retry --suite vts  --shards 2 "
-            "--serial device1 --serial device2")
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/command_processor/command_request.py b/harnesses/host_controller/command_processor/command_request.py
deleted file mode 100644
index 3851823..0000000
--- a/harnesses/host_controller/command_processor/command_request.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from host_controller.command_processor import base_command_processor
-from host_controller.tfc import request
-
-
-class CommandRequest(base_command_processor.BaseCommandProcessor):
-    """Command processor for request command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "request"
-    command_detail = "Send TFC a request to execute a command."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for request command."""
-        self.arg_parser.add_argument(
-            "--cluster",
-            required=True,
-            help="The cluster to which the request is submitted.")
-        self.arg_parser.add_argument(
-            "--run-target",
-            required=True,
-            help="The target device to run the command.")
-        self.arg_parser.add_argument(
-            "--user",
-            required=True,
-            help="The name of the user submitting the request.")
-        self.arg_parser.add_argument(
-            "command",
-            metavar="COMMAND",
-            nargs="+",
-            help='The command to be executed. If the command contains '
-            'arguments starting with "-", place the command after '
-            '"--" at end of line.')
-
-    # @Override
-    def Run(self, arg_line):
-        """Sends TFC a request to execute a command."""
-        args = self.arg_parser.ParseLine(arg_line)
-        req = request.Request(
-            cluster=args.cluster,
-            command_line=" ".join(args.command),
-            run_target=args.run_target,
-            user=args.user)
-        self.console._tfc_client.NewRequest(req)
diff --git a/harnesses/host_controller/command_processor/command_retry.py b/harnesses/host_controller/command_processor/command_retry.py
deleted file mode 100644
index 3108b4b..0000000
--- a/harnesses/host_controller/command_processor/command_retry.py
+++ /dev/null
@@ -1,301 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import itertools
-import logging
-import os
-import zipfile
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.gcp import gcs_utils
-from host_controller.utils.parser import xml_utils
-
-from vts.utils.python.common import cmd_utils
-
-# The command list for cleaning up each devices listed for the retry command.
-_DEVICE_CLEANUP_COMMAND_LIST = [
-    "adb -s {serial} reboot bootloader",
-    "fastboot -s {serial} erase metadata -- -w",
-    "fastboot -s {serial} reboot",
-    "adb -s {serial} wait-for-device",
-    "dut --operation=wifi_on --serial={serial} --ap=" +
-    common._DEFAULT_WIFI_AP,
-]
-
-
-class CommandRetry(base_command_processor.BaseCommandProcessor):
-    """Command processor for retry command."""
-
-    command = "retry"
-    command_detail = "Retry last run test plan for certain times."
-
-    def IsResultZipFile(self, zip_ref):
-        """Determines whether the given zip_ref is the right result archive.
-
-        Need to check the number of contents of the zip file since
-        the "log-result_<>.zip" file only contains "test_result.xml",
-        but cannot parsed by vts-tf properly when trying to do the retry.
-
-        Args:
-            zip_ref: ZipFile, reference to the downloaded results_<>.zip file
-
-        Returns:
-            True if the downloaded zip file is usable from vts-fs,
-            False otherwise.
-        """
-        if len(zip_ref.namelist()) > 1:
-            for name in zip_ref.namelist():
-                if common._TEST_RESULT_XML in name:
-                    return True
-        return False
-
-    def GetResultFromGCS(self, gcs_result_path, local_results_dir):
-        """Downloads a vts-tf result zip archive from GCS.
-
-        And unzip the file to "android-vts/results/" path so
-        the vts-tf will parse the result correctly.
-
-        Args:
-            gcs_result_path: string, path to GCS file.
-            local_results_dir: string, abs path to the result directory of
-                               currently running vts-tf.
-        Returns:
-            A string which is the name of unzipped result directory.
-            None if the download has failed or the downloaded zip file
-            is not a correct result archive.
-        """
-        gsutil_path = gcs_utils.GetGsutilPath()
-        if not gsutil_path:
-            logging.error("Please check gsutil is installed and on your PATH")
-            return None
-
-        if (not gcs_result_path.startswith("gs://")
-                or not gcs_utils.IsGcsFile(gsutil_path, gcs_result_path)):
-            logging.error("%s is not correct GCS url.", gcs_result_path)
-            return None
-        if not gcs_result_path.endswith(".zip"):
-            logging.error("%s is not a correct result archive file.",
-                          gcs_result_path)
-            return None
-
-        if not os.path.exists(local_results_dir):
-            os.mkdir(local_results_dir)
-        if not gcs_utils.Copy(gsutil_path, gcs_result_path, local_results_dir):
-            logging.error("Fail to copy from %s.", gcs_result_path)
-            return None
-        result_zip = os.path.join(local_results_dir,
-                                  gcs_result_path.split("/")[-1])
-        with zipfile.ZipFile(result_zip, mode="r") as zip_ref:
-            if self.IsResultZipFile(zip_ref):
-                unzipped_result_dir = zip_ref.namelist()[0].rstrip("/")
-                zip_ref.extractall(local_results_dir)
-                return unzipped_result_dir
-            else:
-                logging.error("Not a correct vts-tf result archive file.")
-                return None
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for retry command."""
-        self.arg_parser.add_argument(
-            "--suite",
-            default="vts",
-            choices=("vts", "cts", "gts", "sts"),
-            help="To specify the type of a test suite to be run.")
-        self.arg_parser.add_argument(
-            "--count",
-            type=int,
-            default=common.DEFAULT_RETRY_COUNT,
-            help="Retry count. Default retry count is %s." %
-            common.DEFAULT_RETRY_COUNT)
-        self.arg_parser.add_argument(
-            "--force-count",
-            type=int,
-            default=3,
-            help="Forced retry count. Retry certain test plan for the given "
-            "times whether all testcases has passed or not.")
-        self.arg_parser.add_argument(
-            "--result-from-gcs",
-            help="Google Cloud Storage URL from which the result is downloaded. "
-            "Will retry based on the fetched result data")
-        self.arg_parser.add_argument(
-            "--serial",
-            action="append",
-            default=[],
-            help="Serial number for device. Can pass this flag multiple times."
-        )
-        self.arg_parser.add_argument(
-            "--shards", type=int, help="Test plan's shard count.")
-        self.arg_parser.add_argument(
-            "--shard-count",
-            type=int,
-            help=
-            "Test plan's shard count. Same as the \"--shards\" flag but the "
-            "value will be passed to the tradefed with \"--shard-count\" flag."
-        )
-        self.arg_parser.add_argument(
-            "--cleanup_devices",
-            default=False,
-            type=bool,
-            help="True to erase metadata and userdata (equivalent to "
-            "factory reset) between retries.")
-        self.arg_parser.add_argument(
-            "--retry_plan", help="The name of a retry plan to use.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Retry last run plan for certain times."""
-        args = self.arg_parser.ParseLine(arg_line)
-        retry_count = args.count
-        force_retry_count = args.force_count
-
-        if args.suite not in self.console.test_suite_info:
-            logging.error("test_suite_info doesn't have '%s': %s", args.suite,
-                          self.console.test_suite_info)
-            return False
-
-        tools_path = os.path.dirname(self.console.test_suite_info[args.suite])
-        results_path = os.path.join(tools_path, common._RESULTS_BASE_PATH)
-
-        unzipped_result_dir = ""
-        unzipped_result_session_id = -1
-        if args.result_from_gcs:
-            unzipped_result_dir = self.GetResultFromGCS(
-                args.result_from_gcs, results_path)
-            if not unzipped_result_dir:
-                return False
-
-        former_results = [
-            result for result in os.listdir(results_path)
-            if os.path.isdir(os.path.join(results_path, result))
-            and not os.path.islink(os.path.join(results_path, result))
-        ]
-        former_result_count = len(former_results)
-        if former_result_count < 1:
-            logging.error(
-                "No test plan has been run yet, former results count is %d",
-                former_result_count)
-            return False
-
-        if unzipped_result_dir:
-            former_results.sort()
-            unzipped_result_session_id = former_results.index(
-                unzipped_result_dir)
-
-        for result_index in range(retry_count):
-            if unzipped_result_session_id >= 0:
-                session_id = unzipped_result_session_id
-                unzipped_result_session_id = -1
-                latest_result_xml_path = os.path.join(
-                    results_path, unzipped_result_dir, common._TEST_RESULT_XML)
-            else:
-                session_id = former_result_count - 1 + result_index
-                latest_result_xml_path = os.path.join(results_path, "latest",
-                                                      common._TEST_RESULT_XML)
-                if not os.path.exists(latest_result_xml_path):
-                    latest_result_xml_path = os.path.join(
-                        results_path, former_results[-1],
-                        common._TEST_RESULT_XML)
-
-            result_attrs = xml_utils.GetAttributes(
-                latest_result_xml_path, common._RESULT_TAG,
-                [common._SUITE_PLAN_ATTR_KEY])
-
-            summary_attrs = xml_utils.GetAttributes(
-                latest_result_xml_path, common._SUMMARY_TAG, [
-                    common._FAILED_ATTR_KEY, common._MODULES_TOTAL_ATTR_KEY,
-                    common._MODULES_DONE_ATTR_KEY
-                ])
-
-            result_fail_count = int(summary_attrs[common._FAILED_ATTR_KEY])
-            result_skip_count = int(
-                summary_attrs[common._MODULES_TOTAL_ATTR_KEY]) - int(
-                    summary_attrs[common._MODULES_DONE_ATTR_KEY])
-
-            if (result_index >= force_retry_count and result_skip_count == 0
-                    and result_fail_count == 0):
-                logging.info("All modules have run and passed. "
-                             "Skipping remaining %d retry runs.",
-                             (retry_count - result_index))
-                break
-
-            shard_flag_literal = ""
-            if args.shards:
-                shard_flag_literal = "--shards"
-                shard_num = args.shards
-            if args.shard_count:
-                shard_flag_literal = "--shard-count"
-                shard_num = args.shard_count
-
-            if args.retry_plan:
-                retry_plan = args.retry_plan
-            else:
-                retry_plan = result_attrs[common._SUITE_PLAN_ATTR_KEY]
-            if shard_flag_literal:
-                retry_test_command = (
-                    "test --suite=%s --keep-result -- %s --retry %d %s %d" %
-                    (args.suite, retry_plan, session_id, shard_flag_literal,
-                     shard_num))
-            else:
-                retry_test_command = (
-                    "test --suite=%s --keep-result -- %s --retry %d" %
-                    (args.suite, retry_plan, session_id))
-            if args.serial:
-                for serial in args.serial:
-                    retry_test_command += " --serial %s" % serial
-
-            if args.cleanup_devices:
-                for (command, serial) in itertools.product(
-                        _DEVICE_CLEANUP_COMMAND_LIST, args.serial):
-                    if not self.console.onecmd(command.format(serial=serial)):
-                        logging.error(
-                            "Factory reset failed on the devices %s. "
-                            "Skipping retry run(s)", serial)
-                        self.console.device_status[
-                            serial] = common._DEVICE_STATUS_DICT["use"]
-                        return
-
-            self.console.onecmd(retry_test_command)
-
-            for result in os.listdir(results_path):
-                new_result = os.path.join(results_path, result)
-                if (os.path.isdir(new_result)
-                        and not os.path.islink(new_result)
-                        and result not in former_results):
-                    former_results.append(result)
-                    break
-
-            summary_after_retry = xml_utils.GetAttributes(
-                os.path.join(results_path, former_results[-1],
-                             common._TEST_RESULT_XML), common._SUMMARY_TAG,
-                [
-                    common._FAILED_ATTR_KEY, common._MODULES_TOTAL_ATTR_KEY,
-                    common._MODULES_DONE_ATTR_KEY
-                ])
-            fail_count_after_retry = int(
-                summary_after_retry[common._FAILED_ATTR_KEY])
-            skip_count_after_retry = int(
-                summary_after_retry[common._MODULES_TOTAL_ATTR_KEY]) - int(
-                    summary_after_retry[common._MODULES_DONE_ATTR_KEY])
-            if (result_index >= force_retry_count
-                    and fail_count_after_retry == result_fail_count
-                    and skip_count_after_retry == result_skip_count):
-                logging.warning(
-                    "Same result as the former test run from the retry run. "
-                    "Skipping remaining %d retry runs.",
-                    (retry_count - result_index))
-                break
diff --git a/harnesses/host_controller/command_processor/command_sheet.py b/harnesses/host_controller/command_processor/command_sheet.py
deleted file mode 100644
index 090f707..0000000
--- a/harnesses/host_controller/command_processor/command_sheet.py
+++ /dev/null
@@ -1,421 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import csv
-import os
-import logging
-import re
-import shutil
-import tempfile
-import zipfile
-
-try:
-    # TODO: Remove when we stop supporting Python 2
-    import StringIO as string_io_module
-except ImportError:
-    import io as string_io_module
-
-import gspread
-
-from oauth2client.service_account import ServiceAccountCredentials
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.gcp import gcs_utils
-from host_controller.utils.parser import result_utils
-from host_controller.utils.parser import xml_utils
-
-# Attributes shown on spreadsheet
-_RESULT_ATTR_KEYS = [
-    common._SUITE_NAME_ATTR_KEY, common._SUITE_PLAN_ATTR_KEY,
-    common._SUITE_VERSION_ATTR_KEY, common._SUITE_BUILD_NUM_ATTR_KEY,
-    common._START_DISPLAY_TIME_ATTR_KEY,
-    common._END_DISPLAY_TIME_ATTR_KEY
-]
-
-_BUILD_ATTR_KEYS = [
-    common._FINGERPRINT_ATTR_KEY,
-    common._SYSTEM_FINGERPRINT_ATTR_KEY,
-    common._VENDOR_FINGERPRINT_ATTR_KEY
-]
-
-_SUMMARY_ATTR_KEYS = [
-    common._PASSED_ATTR_KEY, common._FAILED_ATTR_KEY,
-    common._MODULES_TOTAL_ATTR_KEY, common._MODULES_DONE_ATTR_KEY
-]
-
-# Texts on spreadsheet
-_TABLE_HEADER = ("BITNESS", "TEST_MODULE", "TEST_CLASS", "TEST_CASE", "RESULT")
-
-_CMP_TABLE_HEADER = _TABLE_HEADER + ("REFERENCE_RESULT",)
-
-_TOO_MANY_DATA = "too many to be displayed"
-
-
-class CommandSheet(base_command_processor.BaseCommandProcessor):
-    """Command processor for sheet command.
-
-    Attributes:
-        _SCOPE: The scope needed to access Google Sheets.
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-    _SCOPE = "https://www.googleapis.com/auth/drive"
-    command = "sheet"
-    command_detail = "Convert and upload a file to Google Sheets."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for sheet command."""
-        self.arg_parser.add_argument(
-            "--src",
-            required=True,
-            help="The local file or GCS URL to be uploaded to Google Sheets. "
-            "This command supports the results produced by TradeFed in XML "
-            "and ZIP formats. Variables enclosed in {} are replaced with the "
-            "the values stored in the console.")
-        self.arg_parser.add_argument(
-            "--dest",
-            required=True,
-            help="The ID of the spreadsheet to which the file is uploaded.")
-        self.arg_parser.add_argument(
-            "--ref",
-            default=None,
-            help="The reference file to be compared with src. If a test in "
-            "src fails, its result in ref is also written to the spreadsheet.")
-        self.arg_parser.add_argument(
-            "--extra_rows",
-            nargs="*",
-            default=[],
-            help="The extra rows written to the spreadsheet. Each argument "
-            "is a row. Cells in a row are separated by commas. Each cell can "
-            "contain variables enclosed in {}.")
-        self.arg_parser.add_argument(
-            "--max",
-            default=30000,
-            type=int,
-            help="Maximum number of results written to the spreadsheet. "
-            "If there are too many results, only failing ones are written.")
-        self.arg_parser.add_argument(
-            "--primary_abi_only",
-            action="store_true",
-            help="Whether to upload only the test results for primary ABI. If "
-            "ref is also specified, this command loads the primary ABI "
-            "results from ref and compares regardless of bitness.")
-        self.arg_parser.add_argument(
-            "--client_secrets",
-            default=None,
-            help="The path to the client secrets file in JSON format for "
-            "authentication. If this argument is not specified, this command "
-            "uses PAB client secrets.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Uploads args.src file to args.dest on Google Sheets."""
-        args = self.arg_parser.ParseLine(arg_line)
-
-        try:
-            src_path = self.console.FormatString(args.src)
-            ref_path = (None if args.ref is None else
-                        self.console.FormatString(args.ref))
-            extra_rows = []
-            for row in args.extra_rows:
-                extra_rows.append([self.console.FormatString(cell)
-                                   for cell in row.split(",")])
-        except KeyError as e:
-            logging.error(
-                "Unknown or uninitialized variable in arguments: %s", e)
-            return False
-
-        if args.client_secrets is not None:
-            credentials = ServiceAccountCredentials.from_json_keyfile_name(
-                args.client_secrets, scopes=self._SCOPE)
-        else:
-            credentials = self.console.build_provider["pab"].Authenticate(
-                scopes=self._SCOPE)
-        client = gspread.authorize(credentials)
-
-        # Load result_attrs, build_attrs, summary_attrs,
-        # src_dict, ref_dict, and exceed_max
-        temp_dir = tempfile.mkdtemp()
-        try:
-            src_path = _GetResultAsXml(src_path, os.path.join(temp_dir, "src"))
-            if not src_path:
-                return False
-
-            with open(src_path, "r") as src_file:
-                (result_attrs,
-                 build_attrs,
-                 summary_attrs) = result_utils.LoadTestSummary(src_file)
-                src_file.seek(0)
-                if args.primary_abi_only:
-                    abis = build_attrs.get(
-                        common._ABIS_ATTR_KEY, "").split(",")
-                    src_bitness = str(result_utils.GetAbiBitness(abis[0]))
-                    src_dict, exceed_max = _LoadSrcResults(src_file, args.max,
-                                                           src_bitness)
-                else:
-                    src_dict, exceed_max = _LoadSrcResults(src_file, args.max)
-
-            if ref_path:
-                ref_path = _GetResultAsXml(
-                    ref_path, os.path.join(temp_dir, "ref"))
-                if not ref_path:
-                    return False
-                with open(ref_path, "r") as ref_file:
-                    if args.primary_abi_only:
-                        ref_build_attrs = xml_utils.GetAttributes(
-                            ref_file, common._BUILD_TAG,
-                            (common._ABIS_ATTR_KEY, ))
-                        ref_file.seek(0)
-                        abis = ref_build_attrs[
-                            common._ABIS_ATTR_KEY].split(",")
-                        ref_bitness = str(result_utils.GetAbiBitness(abis[0]))
-                        ref_dict = _LoadRefResults(ref_file, src_dict,
-                                                   ref_bitness, src_bitness)
-                    else:
-                        ref_dict = _LoadRefResults(ref_file, src_dict)
-        finally:
-            shutil.rmtree(temp_dir)
-
-        # Output
-        csv_file = string_io_module.StringIO()
-        try:
-            writer = csv.writer(csv_file, lineterminator="\n")
-
-            writer.writerows(extra_rows)
-
-            for keys, attrs in (
-                    (_RESULT_ATTR_KEYS, result_attrs),
-                    (_BUILD_ATTR_KEYS, build_attrs),
-                    (_SUMMARY_ATTR_KEYS, summary_attrs)):
-                writer.writerows((k, attrs.get(k, "")) for k in keys)
-
-            src_list = sorted(src_dict.items())
-            if ref_path:
-                _WriteComparisonToCsv(src_list, ref_dict, writer)
-            else:
-                _WriteResultsToCsv(src_list, writer)
-
-            if exceed_max:
-                writer.writerow((_TOO_MANY_DATA,))
-
-            client.import_csv(args.dest, csv_file.getvalue())
-        finally:
-            csv_file.close()
-
-
-def _DownloadResultZipFromGcs(gcs_url, local_dir):
-    """Downloads a result ZIP from GCS.
-
-    If the GCS URL is a directory, this function searches the directory for the
-    file whose name matches the pattern of result ZIP.
-
-    Args:
-        gcs_url: The URL of the ZIP file or the directory.
-        local_dir: The local directory where the ZIP is downloaded.
-
-    Returns:
-        The path to the downloaded ZIP file.
-        None if fail to download.
-    """
-    gsutil_path = gcs_utils.GetGsutilPath()
-    if not gsutil_path:
-        return False
-
-    if gcs_utils.IsGcsFile(gsutil_path, gcs_url):
-        gcs_urls = [gcs_url]
-    else:
-        ls_urls = gcs_utils.List(gsutil_path, gcs_url)
-        gcs_urls = [x for x in ls_urls if
-                    re.match(".+/results_\\d*\\.zip$", x)]
-        if not gcs_urls:
-            gcs_urls = [x for x in ls_urls if
-                        re.match(".+/log-result_\\d*\\.zip$", x)]
-
-    if not gcs_urls:
-        logging.error("No results on %s", gcs_url)
-        return None
-    if len(gcs_urls) > 1:
-        logging.warning("More than one result. Select %s", gcs_urls[0])
-
-    if not os.path.exists(local_dir):
-        os.makedirs(local_dir)
-    if not gcs_utils.Copy(gsutil_path, gcs_urls[0], local_dir):
-        logging.error("Fail to copy from %s", gcs_urls[0])
-        return None
-
-    return os.path.join(local_dir, gcs_urls[0].rpartition("/")[2])
-
-
-def _GetResultAsXml(src, temp_dir):
-    """Downloads and extracts an XML result.
-
-    If src is a GCS URL, it is downloaded to temp_dir.
-    If the file is a ZIP, it is extracted to temp_dir.
-
-    Args:
-        src: The location of the file, can be a directory on GCS,
-             a ZIP file on GCS, a local ZIP file, or a local XML file.
-        temp_dir: The directory where the ZIP is downloaded and extracted.
-
-    Returns:
-        The path to the XML file.
-        None if fails to the find the XML.
-    """
-    original_src = src
-    if src.startswith("gs://"):
-        src = _DownloadResultZipFromGcs(src, os.path.join(temp_dir, "zipped"))
-        if not src:
-            return None
-
-    if zipfile.is_zipfile(src):
-        with zipfile.ZipFile(src, mode="r") as zip_file:
-            src = result_utils.ExtractResultZip(
-                zip_file, os.path.join(temp_dir, "unzipped"))
-        if not src:
-            logging.error("Cannot find XML result in %s", original_src)
-            return None
-
-    return src
-
-
-def _FilterTestResults(xml_file, max_return, filter_func):
-    """Loads test results from XML to dictionary with a filter.
-
-    Args:
-        xml_file: The input file object in XML format.
-        max_return: Maximum number of output results.
-        filter_func: A function taking the test name and result as parameters,
-                     and returning whether it should be included.
-
-    Returns:
-        A dict of {name: result} where name is a tuple of strings and result
-        is a string.
-    """
-    result_dict = dict()
-    for module, testcase, test in result_utils.IterateTestResults(xml_file):
-        if len(result_dict) >= max_return:
-            break
-        test_name = result_utils.GetTestName(module, testcase, test)
-        result = test.attrib.get(common._RESULT_ATTR_KEY, "")
-        if filter_func(test_name, result):
-            result_dict[test_name] = result
-
-    return result_dict
-
-
-def _LoadSrcResults(src_xml, max_return, bitness=""):
-    """Loads test results from XML to dictionary.
-
-    If number of results exceeds max_return, only failures are returned.
-    If number of failures exceeds max_return, the results are truncated.
-
-    Args
-        src_xml: The file object in XML format.
-        max_return: Maximum number of returned results.
-        bitness: A string, the bitness of the returned results.
-
-    Returns:
-        A dict of {name: result} and a boolean which represents whether the
-        results are truncated.
-    """
-    def FilterBitness(name):
-        return not bitness or bitness == name[0]
-
-    results = _FilterTestResults(
-        src_xml, max_return + 1, lambda name, result: FilterBitness(name))
-
-    if len(results) > max_return:
-        src_xml.seek(0)
-        results = _FilterTestResults(
-            src_xml, max_return + 1,
-            lambda name, result: result == "fail" and FilterBitness(name))
-
-    exceed_max = len(results) > max_return
-    if results and exceed_max:
-        del results[max(results)]
-
-    return results, exceed_max
-
-
-def _LoadRefResults(ref_xml, base_results, ref_bitness="", base_bitness=""):
-    """Loads reference results from XML to dictionary.
-
-    A test result in ref_xml is returned if the test fails in base_results.
-
-    Args:
-        ref_xml: The file object in XML format.
-        base_results: A dict of {name: result} containing the test names to be
-                      loaded from ref_xml.
-        ref_bitness: A string, the bitness of the results to be loaded from
-                     ref_xml.
-        base_bitness: A string, the bitness of the returned results. If this
-                      argument is specified, the function ignores bitness when
-                      comparing test names.
-
-    Returns:
-        A dict of {name: result}, the test name in base_results and the result
-        in ref_xml.
-    """
-    ref_results = dict()
-    for module, testcase, test in result_utils.IterateTestResults(ref_xml):
-        if len(ref_results) >= len(base_results):
-            break
-        result = test.attrib.get(common._RESULT_ATTR_KEY, "")
-        name = result_utils.GetTestName(module, testcase, test)
-
-        if ref_bitness and name[0] != ref_bitness:
-            continue
-        if base_bitness:
-            name_in_base = (base_bitness, ) + name[1:]
-        else:
-            name_in_base = name
-
-        if base_results.get(name_in_base, "") == "fail":
-            ref_results[name_in_base] = result
-
-    return ref_results
-
-
-def _WriteResultsToCsv(result_list, writer):
-    """Writes a list of test names and results to a CSV file.
-
-    Args:
-        result_list: The list of (name, result).
-        writer: The object of CSV writer.
-    """
-    writer.writerow(_TABLE_HEADER)
-    writer.writerows(name + (result,) for name, result in result_list)
-
-
-def _WriteComparisonToCsv(result_list, reference_dict, writer):
-    """Writes test names, results, and reference results to a CSV file.
-
-    Args:
-        result_list: The list of (name, result).
-        reference_dict: The dict of {name: reference_result}.
-        writer: The object of CSV writer.
-    """
-    writer.writerow(_CMP_TABLE_HEADER)
-    for name, result in result_list:
-        if result == "fail":
-            reference = reference_dict.get(name, "no_data")
-        else:
-            reference = ""
-        writer.writerow(name + (result, reference))
diff --git a/harnesses/host_controller/command_processor/command_sheet_test.py b/harnesses/host_controller/command_processor/command_sheet_test.py
deleted file mode 100644
index 1c61349..0000000
--- a/harnesses/host_controller/command_processor/command_sheet_test.py
+++ /dev/null
@@ -1,328 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import tempfile
-import unittest
-import zipfile
-
-try:
-    from unittest import mock
-except ImportError:
-    # TODO: Remove when we stop supporting Python 2
-    import mock
-
-from host_controller import common
-from host_controller.command_processor import command_sheet
-
-# Input
-_EXTRA_ROWS = ("logs,gs://a/b", "logs,gs://c/{suite_plan}")
-
-_XML_HEAD = """\
-<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
-<?xml-stylesheet type="text/xsl" href="compatibility_result.xsl"?>
-<Result start="1528285394762" end="1528286467560" start_display="Wed Jun 06 04:43:14 PDT 2018" end_display="Wed Jun 06 05:01:07 PDT 2018" suite_name="VTS" suite_version="9.0_R1" suite_plan="vts" suite_build_number="4000000" report_version="5.0" command_line_args="vts" devices="TEST123456" host_name="unit.test" os_name="Linux" os_version="4.13.0-41-generic" os_arch="amd64" java_vendor="Oracle Corporation" java_version="1.8.0_171">
-  <Build build_abis_64="arm64-v8a" build_manufacturer="Google" build_reference_fingerprint2="" build_board="unit_test" build_serial="TEST123456" build_system_fingerprint="system_fp" build_reference_fingerprint="null" build_fingerprint="vendor_fp" build_abis="arm64-v8a,armeabi-v7a,armeabi" build_device="unit_test" build_abi="arm64-v8a" build_abi2="null" build_version_release="9" build_version_base_os="" build_type="userdebug" build_vendor_model="Unit Test" build_abis_32="armeabi-v7a,armeabi" build_product="unit_test" build_brand="google" build_abi22="" build_version_security_patch="2018-06-05" build_vendor_manufacturer="Google" build_version_sdk="28" build_id="test_build" build_model="Unit Test" build_vendor_fingerprint="vendor_fp" build_version_incremental="4000000" build_fingerprint2="system_fp" build_tags="test-keys" />
-"""
-
-_XML_1 = _XML_HEAD + """\
-  <Summary pass="1" failed="3" modules_done="2" modules_total="2" />
-  <Module name="module1" abi="armeabi-v7a" runtime="1" done="true" pass="0">
-    <TestCase name="testcase1">
-      <Test result="fail" name="test1" />
-    </TestCase>
-  </Module>
-  <Module name="module2" abi="arm64-v8a" runtime="1" done="true" pass="1">
-    <TestCase name="testcase2">
-      <Test result="pass" name="test1" />
-      <Test result="fail" name="test2" />
-      <Test result="fail" name="test3" />
-    </TestCase>
-  </Module>
-</Result>
-"""
-
-_XML_2 = _XML_HEAD + """\
-  <Summary pass="3" failed="1" modules_done="2" modules_total="2" />
-  <Module name="module1" abi="armeabi-v7a" runtime="1" done="true" pass="1">
-    <TestCase name="testcase1">
-      <Test result="pass" name="test1,test2" />
-    </TestCase>
-  </Module>
-  <Module name="module2" abi="arm64-v8a" runtime="1" done="true" pass="2">
-    <TestCase name="testcase2">
-      <Test result="pass" name="test1" />
-      <Test result="pass" name="test2" />
-      <Test result="fail" name="test3" />
-    </TestCase>
-  </Module>
-</Result>
-"""
-
-# Expected output
-_CSV_HEAD = """\
-logs,gs://a/b
-logs,gs://c/vts
-suite_name,VTS
-suite_plan,vts
-suite_version,9.0_R1
-suite_build_number,4000000
-start_display,Wed Jun 06 04:43:14 PDT 2018
-end_display,Wed Jun 06 05:01:07 PDT 2018
-build_fingerprint,vendor_fp
-build_system_fingerprint,system_fp
-build_vendor_fingerprint,vendor_fp
-"""
-
-_ALL_RESULTS_1 = _CSV_HEAD + """\
-pass,1
-failed,3
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT
-32,module1,testcase1,test1,fail
-64,module2,testcase2,test1,pass
-64,module2,testcase2,test2,fail
-64,module2,testcase2,test3,fail
-"""
-
-_FAILING_RESULTS_1 = _CSV_HEAD + """\
-pass,1
-failed,3
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT
-32,module1,testcase1,test1,fail
-64,module2,testcase2,test2,fail
-64,module2,testcase2,test3,fail
-"""
-
-_TRUNCATED_RESULTS_1 = _CSV_HEAD + """\
-pass,1
-failed,3
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT
-32,module1,testcase1,test1,fail
-too many to be displayed
-"""
-
-_PRIMARY_ABI_RESULTS_1 = _CSV_HEAD + """\
-pass,1
-failed,3
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT
-64,module2,testcase2,test1,pass
-64,module2,testcase2,test2,fail
-64,module2,testcase2,test3,fail
-"""
-
-_COMPARISON_1_2 = _CSV_HEAD + """\
-pass,1
-failed,3
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT,REFERENCE_RESULT
-32,module1,testcase1,test1,fail,no_data
-64,module2,testcase2,test2,fail,pass
-64,module2,testcase2,test3,fail,fail
-"""
-
-_PRIMARY_ABI_COMPARISON_1_2 = _CSV_HEAD + """\
-pass,1
-failed,3
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT,REFERENCE_RESULT
-64,module2,testcase2,test1,pass,
-64,module2,testcase2,test2,fail,pass
-64,module2,testcase2,test3,fail,fail
-"""
-
-_COMPARISON_2_1 = _CSV_HEAD + """\
-pass,3
-failed,1
-modules_total,2
-modules_done,2
-BITNESS,TEST_MODULE,TEST_CLASS,TEST_CASE,RESULT,REFERENCE_RESULT
-32,module1,testcase1,"test1,test2",pass,
-64,module2,testcase2,test1,pass,
-64,module2,testcase2,test2,pass,
-64,module2,testcase2,test3,fail,fail
-"""
-
-
-@mock.patch("host_controller.command_processor.command_sheet.gspread")
-@mock.patch("host_controller.command_processor.command_sheet."
-            "ServiceAccountCredentials")
-class CommandSheetTest(unittest.TestCase):
-    """Unit test for CommandSheet.
-
-    Attributes:
-        _cmd: The CommandSheet being tested.
-        _temp_files: The paths to the temporary files.
-    """
-
-    def setUp(self):
-        """Creates CommandSheet."""
-        self._cmd = command_sheet.CommandSheet()
-        mock_console = mock.Mock()
-        mock_console.FormatString = lambda x: x.replace("{suite_plan}", "vts")
-        self._cmd._SetUp(mock_console)
-        self._temp_files = []
-
-    def tearDown(self):
-        """Deletes CommandSheet and temoprary files."""
-        self._cmd._TearDown()
-        for temp_file in self._temp_files:
-            os.remove(temp_file)
-
-    def _CreateXml(self, xml_string):
-        """Creates a test result in XML format.
-
-        Args:
-            xml_string: The file contents.
-
-        Returns:
-            The path to the XML file.
-        """
-        with tempfile.NamedTemporaryFile(
-                suffix=".xml", delete=False) as temp_file:
-            self._temp_files.append(temp_file.name)
-            temp_file.write(xml_string)
-            return temp_file.name
-
-    def _CreateZip(self, xml_string):
-        """Creates a zipped test result.
-
-        Args:
-            xml_string: The file contents.
-
-        Returns:
-            The path to the ZIP file.
-        """
-        with tempfile.NamedTemporaryFile(
-                suffix=".zip", delete=False) as temp_file:
-            self._temp_files.append(temp_file.name)
-            with zipfile.ZipFile(temp_file, "w") as zip_file:
-                zip_file.writestr(common._TEST_RESULT_XML, xml_string)
-                return temp_file.name
-
-    def testUploadZip(self, mock_credentials, mock_gspread):
-        """Tests uploading zipped result."""
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s" %
-                      (self._CreateZip(_XML_1), " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123", _ALL_RESULTS_1)
-
-    def testShowFailureOnly(self, mock_credentials, mock_gspread):
-        """Tests showing only failing tests."""
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s --max 3" %
-                      (self._CreateXml(_XML_1), " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123", _FAILING_RESULTS_1)
-
-    def testTruncate(self, mock_credentials, mock_gspread):
-        """Tests truncating output."""
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s --max 1" %
-                      (self._CreateXml(_XML_1), " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123", _TRUNCATED_RESULTS_1)
-
-    def testPrimaryAbiOnly(self, mock_credentials, mock_gspread):
-        """Tests showing only results for primary ABI."""
-        """Tests showing only failing tests."""
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s --primary_abi_only" %
-                      (self._CreateXml(_XML_1), " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123", _PRIMARY_ABI_RESULTS_1)
-
-    def testCompareLocal(self, mock_credentials, mock_gspread):
-        """Tests comparing two local XML files."""
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --ref %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s --max 3" %
-                      (self._CreateXml(_XML_1), self._CreateZip(_XML_2),
-                       " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123", _COMPARISON_1_2)
-
-    def testComparePrimaryAbi(self, mock_credentials, mock_gspread):
-        """Tests comparing primary ABI only."""
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --ref %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s --primary_abi_only" %
-                      (self._CreateXml(_XML_1), self._CreateZip(_XML_2),
-                       " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123",
-                                                  _PRIMARY_ABI_COMPARISON_1_2)
-
-    @mock.patch("host_controller.command_processor.command_sheet.gcs_utils")
-    def testCompareGcs(self, mock_gcs_utils, mock_credentials, mock_gspread):
-        """Tests comparing a local XML with a ZIP on GCS."""
-
-        zip_name = "results_123.zip"
-        gcs_dir = "gs://unit/test"
-        zip_url = gcs_dir + "/" + zip_name
-
-        def MockCopy(gsutil_path, gcs_url, local_dir):
-            self.assertEqual(zip_url, gcs_url)
-            with zipfile.ZipFile(os.path.join(local_dir, zip_name),
-                                 "w") as zip_file:
-                zip_file.writestr(common._TEST_RESULT_XML, _XML_1)
-            return True
-
-        mock_gcs_utils.GetGsutilPath.return_value = "mock_gsutil"
-        mock_gcs_utils.IsGcsFile.return_value = False
-        mock_gcs_utils.List.return_value = [zip_url]
-        mock_gcs_utils.Copy = MockCopy
-
-        mock_client = mock.Mock()
-        mock_gspread.authorize.return_value = mock_client
-
-        self._cmd.Run("--src %s --ref %s --dest 123 --client_secret /abc "
-                      "--extra_rows %s" %
-                      (self._CreateXml(_XML_2), gcs_dir,
-                       " ".join(_EXTRA_ROWS)))
-
-        mock_client.import_csv.assert_called_with("123", _COMPARISON_2_1)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/command_processor/command_shell.py b/harnesses/host_controller/command_processor/command_shell.py
deleted file mode 100644
index abe3274..0000000
--- a/harnesses/host_controller/command_processor/command_shell.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from host_controller.command_processor import base_command_processor
-
-from vts.utils.python.common import cmd_utils
-
-
-class CommandShell(base_command_processor.BaseCommandProcessor):
-    """Command processor for shell command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "shell"
-    command_detail = "Runs a shell command on the host OS."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for device command."""
-        self.arg_parser.add_argument(
-            "command",
-            metavar="COMMAND",
-            nargs="+",
-            help="The command to be executed. If the command contains "
-            "arguments starting with \"-\", place the command at end of line "
-            "after \"--\".")
-
-    # @Override
-    def Run(self, arg_line):
-        """Runs a shell command."""
-        args = self.arg_parser.ParseLine(arg_line)
-        cmd_list = self.ReplaceVars(args.command)
-        stdout, stderr, retcode = cmd_utils.ExecuteOneShellCommand(
-            " ".join(cmd_list))
-        if stdout:
-            logging.info(stdout)
-        if stderr:
-            logging.error(stderr)
-        if retcode != 0:
-            return False
diff --git a/harnesses/host_controller/command_processor/command_sleep.py b/harnesses/host_controller/command_processor/command_sleep.py
deleted file mode 100644
index 9517496..0000000
--- a/harnesses/host_controller/command_processor/command_sleep.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import time
-
-from host_controller.command_processor import base_command_processor
-
-
-class CommandSleep(base_command_processor.BaseCommandProcessor):
-    """Command processor for sleep command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "sleep"
-    command_detail = "Sleeps for N seconds."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for device command."""
-        self.arg_parser.add_argument(
-            "seconds",
-            metavar="COMMAND",
-            nargs=1,
-            help=("an integer indicating the amount of time to sleep "
-                  "in seconds"))
-
-    # @Override
-    def Run(self, arg_line):
-        """Blocks for a specified time interval."""
-        args = self.arg_parser.ParseLine(arg_line)
-        try:
-            time.sleep(int(args.seconds[0]))
-        except ValueError as e:
-            logging.exception(e)
-            return False
diff --git a/harnesses/host_controller/command_processor/command_test.py b/harnesses/host_controller/command_processor/command_test.py
deleted file mode 100644
index 8e5adb7..0000000
--- a/harnesses/host_controller/command_processor/command_test.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-import shutil
-import subprocess
-import tempfile
-import threading
-import zipfile
-
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.parser import xml_utils
-from vts.runners.host import utils
-
-
-class CommandTest(base_command_processor.BaseCommandProcessor):
-    """Command processor for test command.
-
-    Attributes:
-        _RESULT_ATTRIBUTES: The attributes of <Result> in the XML report.
-                            After test execution, the attributes are loaded
-                            from report to console's dictionary.
-        _result_dir: the path to the temporary result directory.
-    """
-
-    command = "test"
-    command_detail = "Executes a command on TF."
-    _RESULT_TAG = "Result"
-    _RESULT_ATTRIBUTES = ["suite_plan"]
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for test command."""
-        self._result_dir = None
-        self.arg_parser.add_argument(
-            "--suite",
-            default="vts",
-            choices=("vts", "cts", "gts", "sts"),
-            help="To specify the type of a test suite to be run.")
-        self.arg_parser.add_argument(
-            "--serial",
-            "-s",
-            default=None,
-            help="The target device serial to run the command. "
-            "A comma-separate list.")
-        self.arg_parser.add_argument(
-            "--test-exec-mode",
-            default="subprocess",
-            help="The target exec model.")
-        self.arg_parser.add_argument(
-            "--keep-result",
-            action="store_true",
-            help="Keep the path to the result in the console instance.")
-        self.arg_parser.add_argument(
-            "command",
-            metavar="COMMAND",
-            nargs="+",
-            help="The command to be executed. If the command contains "
-            "arguments starting with \"-\", place the command after "
-            "\"--\" at end of line. format: plan -m module -t testcase")
-
-    def _ClearResultDir(self):
-        """Deletes all files in the result directory."""
-        if self._result_dir is None:
-            self._result_dir = tempfile.mkdtemp()
-            return
-
-        for file_name in os.listdir(self._result_dir):
-            shutil.rmtree(os.path.join(self._result_dir, file_name))
-
-    @staticmethod
-    def _GenerateTestSuiteCommand(bin_path, command, serials, result_dir=None):
-        """Generates a *ts-tradefed command.
-
-        Args:
-            bin_path: the path to *ts-tradefed.
-            command: a list of strings, the command arguments.
-            serials: a list of strings, the serial numbers of the devices.
-            result_dir: the path to the temporary directory where the result is
-                        saved.
-
-        Returns:
-            a list of strings, the *ts-tradefed command.
-        """
-        cmd = [bin_path, "run", "commandAndExit"]
-        cmd.extend(str(c) for c in command)
-
-        for serial in serials:
-            cmd.extend(["-s", str(serial)])
-
-        if result_dir:
-            cmd.extend(["--log-file-path", result_dir, "--use-log-saver"])
-
-        return cmd
-
-    @staticmethod
-    def _ExecuteCommand(cmd):
-        """Executes a command and logs output in real time.
-
-        Args:
-            cmd: a list of strings, the command to execute.
-        """
-
-        def LogOutputStream(log_level, stream):
-            try:
-                while True:
-                    line = stream.readline()
-                    if not line:
-                        break
-                    logging.log(log_level, line.rstrip())
-            finally:
-                stream.close()
-
-        proc = subprocess.Popen(
-            cmd,
-            stdin=subprocess.PIPE,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE)
-
-        out_thread = threading.Thread(
-            target=LogOutputStream, args=(logging.INFO, proc.stdout))
-        err_thread = threading.Thread(
-            target=LogOutputStream, args=(logging.ERROR, proc.stderr))
-        out_thread.daemon = True
-        err_thread.daemon = True
-        out_thread.start()
-        err_thread.start()
-        proc.wait()
-        logging.info("Return code: %d", proc.returncode)
-        proc.stdin.close()
-        out_thread.join()
-        err_thread.join()
-
-    # @Override
-    def Run(self, arg_line):
-        """Executes a command using a *TS-TF instance.
-
-        Args:
-            arg_line: string, line of command arguments.
-        """
-        args = self.arg_parser.ParseLine(arg_line)
-        if args.serial:
-            serials = args.serial.split(",")
-        elif self.console.GetSerials():
-            serials = self.console.GetSerials()
-        else:
-            serials = []
-
-        if args.test_exec_mode == "subprocess":
-            if args.suite not in self.console.test_suite_info:
-                logging.error("test_suite_info doesn't have '%s': %s",
-                              args.suite, self.console.test_suite_info)
-                return
-
-            if args.keep_result:
-                self._ClearResultDir()
-                result_dir = self._result_dir
-            else:
-                result_dir = None
-
-            cmd = self._GenerateTestSuiteCommand(
-                self.console.test_suite_info[args.suite], args.command,
-                serials, result_dir)
-
-            logging.info("Command: %s", cmd)
-            self._ExecuteCommand(cmd)
-
-            if result_dir:
-                result_paths = [
-                    os.path.join(dir_name, file_name)
-                    for dir_name, file_name in utils.iterate_files(result_dir)
-                    if file_name.startswith("log-result")
-                    and file_name.endswith(".zip")
-                ]
-
-                if len(result_paths) != 1:
-                    logging.warning("Unexpected number of results: %s",
-                                    result_paths)
-
-                self.console.test_result.clear()
-                result = {}
-                if len(result_paths) > 0:
-                    with zipfile.ZipFile(
-                            result_paths[0], mode="r") as result_zip:
-                        with result_zip.open(
-                                "log-result.xml", mode="rU") as result_xml:
-                            result = xml_utils.GetAttributes(
-                                result_xml, self._RESULT_TAG,
-                                self._RESULT_ATTRIBUTES)
-                            if not result:
-                                logging.warning("Nothing loaded from report.")
-                    result["result_zip"] = result_paths[0]
-
-                result_paths_full = [
-                    os.path.join(dir_name, file_name)
-                    for dir_name, file_name in utils.iterate_files(result_dir)
-                    if file_name.endswith(".zip")
-                ]
-                result["result_full"] = " ".join(result_paths_full)
-                result["suite_name"] = args.suite
-
-                logging.debug(result)
-                self.console.test_result.update(result)
-        else:
-            logging.error("unsupported exec mode: %s", args.test_exec_mode)
-            return False
-
-    # @Override
-    def TearDown(self):
-        """Deletes the result directory."""
-        if self._result_dir:
-            shutil.rmtree(self._result_dir, ignore_errors=True)
diff --git a/harnesses/host_controller/command_processor/command_upload.py b/harnesses/host_controller/command_processor/command_upload.py
deleted file mode 100644
index db57089..0000000
--- a/harnesses/host_controller/command_processor/command_upload.py
+++ /dev/null
@@ -1,346 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-import shutil
-import socket
-import time
-
-from host_controller import common
-from host_controller.command_processor import base_command_processor
-from host_controller.utils.gcp import gcs_utils
-from host_controller.utils.parser import xml_utils
-
-from vts.utils.python.common import cmd_utils
-
-from vti.dashboard.proto import TestSuiteResultMessage_pb2 as SuiteResMsg
-from vti.test_serving.proto import TestScheduleConfigMessage_pb2 as SchedCfgMsg
-
-
-class CommandUpload(base_command_processor.BaseCommandProcessor):
-    """Command processor for upload command.
-
-    Attributes:
-        arg_parser: ConsoleArgumentParser object, argument parser.
-        console: cmd.Cmd console object.
-        command: string, command name which this processor will handle.
-        command_detail: string, detailed explanation for the command.
-    """
-
-    command = "upload"
-    command_detail = "Upload <src> file to <dest> Google Cloud Storage. In <src> and <dest>, variables enclosed in {} are replaced with the values stored in the console."
-
-    # @Override
-    def SetUp(self):
-        """Initializes the parser for upload command."""
-        self.arg_parser.add_argument(
-            "--src",
-            required=True,
-            default="latest-system.img",
-            help="Path to a source file to upload. Only single file can be "
-            "uploaded per once. Use 'latest- prefix to upload the latest "
-            "fetch images. e.g. --src=latest-system.img  If argument "
-            "value is not given, the recently fetched system.img will be "
-            "uploaded.")
-        self.arg_parser.add_argument(
-            "--dest",
-            required=True,
-            help="Google Cloud Storage URL to which the file is uploaded.")
-        self.arg_parser.add_argument(
-            "--report_path",
-            help="Google Cloud Storage URL, the dest path of a report file")
-        self.arg_parser.add_argument(
-            "--clear_dest",
-            action="store_true",
-            help="Delete dest recursively before the upload.")
-        self.arg_parser.add_argument(
-            "--clear_results",
-            default=False,
-            help="True to clear all the results after the upload.")
-        self.arg_parser.add_argument(
-            "--result_from_suite",
-            default="",
-            choices=("", "vts", "cts", "gts", "sts"),
-            help="To specify the type of a test suite report, since there can "
-            "be multiple numbers of result sets from different test "
-            "suites. If not specified, the HC will upload the report "
-            "from last run suite and plan.")
-        self.arg_parser.add_argument(
-            "--result_from_plan",
-            default="",
-            help="To specify the type of the plan name from which "
-            "the report is generated.")
-
-    # @Override
-    def Run(self, arg_line):
-        """Upload args.src file to args.dest Google Cloud Storage."""
-        args = self.arg_parser.ParseLine(arg_line)
-
-        gsutil_path = gcs_utils.GetGsutilPath()
-        if not gsutil_path:
-            logging.error("Please check gsutil is installed and on your PATH")
-            return False
-
-        if args.src.startswith("latest-"):
-            src_name = args.src[7:]
-            if src_name in self.console.device_image_info:
-                src_paths = self.console.device_image_info[src_name]
-            else:
-                logging.error(
-                    "Unable to find {} in device_image_info".format(src_name))
-                return False
-        else:
-            try:
-                src_paths = self.console.FormatString(args.src)
-            except KeyError as e:
-                logging.error("Unknown or uninitialized variable in src: %s",
-                              e)
-                return False
-
-        src_path_list_tmp = src_paths.split(" ")
-        src_path_list = []
-        if src_path_list_tmp:
-            for src_path in src_path_list_tmp:
-                file_path = src_path.strip()
-                if os.path.isfile(file_path):
-                    src_path_list.append(file_path)
-                else:
-                    logging.error("Cannot find a file: {}".format(file_path))
-        src_paths = " ".join(src_path_list)
-
-        try:
-            dest_path = self.console.FormatString(args.dest)
-        except KeyError as e:
-            logging.error("Unknown or uninitialized variable in dest: %s", e)
-            return False
-
-        if not dest_path.startswith("gs://"):
-            logging.error("{} is not correct GCS url.".format(dest_path))
-            return False
-        """ TODO(jongmok) : Before upload, login status, authorization,
-                            and dest check are required. """
-        if args.clear_dest:
-            if not gcs_utils.Remove(gsutil_path, dest_path, recursive=True):
-                logging.error("Fail to remove %s", dest_path)
-
-        if not gcs_utils.Copy(gsutil_path, src_paths, dest_path):
-            logging.error("Fail to copy %s to %s", src_paths, dest_path)
-
-        if args.report_path or args.clear_results:
-            tools_path = ""
-            if args.result_from_suite:
-                tools_path = os.path.dirname(
-                    self.console.test_suite_info[args.result_from_suite])
-            else:
-                try:
-                    tools_path = os.path.dirname(self.console.test_suite_info[
-                        self.console.FormatString("{suite_name}")])
-                except KeyError:
-                    if self.console.vti_endpoint_client.CheckBootUpStatus():
-                        logging.error(
-                            "No test results found from any fetched test suite."
-                            " Please fetch a test suite and run 'test' command,"
-                            " then try running 'upload' command again.")
-                        return False
-            results_base_path = os.path.join(tools_path,
-                                             common._RESULTS_BASE_PATH)
-
-            if args.report_path:
-                report_path = self.console.FormatString(args.report_path)
-                if not report_path.startswith("gs://"):
-                    logging.error(
-                        "{} is not correct GCS url.".format(report_path))
-                else:
-                    self.UploadReport(
-                        gsutil_path, report_path, dest_path, results_base_path,
-                        args.result_from_suite, args.result_from_plan)
-
-            if args.clear_results:
-                shutil.rmtree(results_base_path, ignore_errors=True)
-
-    def UploadReport(self, gsutil_path, report_path, log_path, results_path,
-                     suite_name, plan_name):
-        """Uploads report summary file to the given path.
-
-        Args:
-            gsutil_path: string, the path of a gsutil binary.
-            report_path: string, the dest GCS URL to which the summarized report
-                                 file will be uploaded.
-            log_path: string, GCS URL where the log files from the test run
-                              have been uploaded.
-            results_path: string, the base path for the results.
-        """
-        suite_res_msg = SuiteResMsg.TestSuiteResultMessage()
-        suite_res_msg.result_path = log_path
-        suite_res_msg.branch = self.console.FormatString("{branch}")
-        suite_res_msg.target = self.console.FormatString("{target}")
-        vti = self.console.vti_endpoint_client
-        suite_res_msg.boot_success = vti.CheckBootUpStatus()
-        suite_res_msg.test_type = vti.GetJobTestType()
-
-        device_fetch_info = self.console.detailed_fetch_info[
-            common._ARTIFACT_TYPE_DEVICE]
-        gsi_fetch_info = None
-        if common._ARTIFACT_TYPE_GSI in self.console.detailed_fetch_info:
-            gsi_fetch_info = self.console.detailed_fetch_info[
-                common._ARTIFACT_TYPE_GSI]
-
-        if vti.CheckBootUpStatus():
-            former_results = [
-                result for result in os.listdir(results_path)
-                if os.path.isdir(os.path.join(results_path, result))
-                and not os.path.islink(os.path.join(results_path, result))
-            ]
-
-            if not former_results:
-                logging.error("No test result found.")
-                return False
-
-            former_results.sort()
-            latest_result = former_results[-1]
-            latest_result_xml_path = os.path.join(results_path, latest_result,
-                                                  common._TEST_RESULT_XML)
-
-            result_attrs = xml_utils.GetAttributes(
-                latest_result_xml_path, common._RESULT_TAG, [
-                    common._SUITE_NAME_ATTR_KEY, common._SUITE_PLAN_ATTR_KEY,
-                    common._SUITE_VERSION_ATTR_KEY,
-                    common._SUITE_BUILD_NUM_ATTR_KEY,
-                    common._START_TIME_ATTR_KEY, common._END_TIME_ATTR_KEY,
-                    common._HOST_NAME_ATTR_KEY
-                ])
-            build_attrs = xml_utils.GetAttributes(
-                latest_result_xml_path, common._BUILD_TAG, [
-                    common._FINGERPRINT_ATTR_KEY,
-                    common._SYSTEM_FINGERPRINT_ATTR_KEY,
-                    common._VENDOR_FINGERPRINT_ATTR_KEY
-                ])
-            summary_attrs = xml_utils.GetAttributes(
-                latest_result_xml_path, common._SUMMARY_TAG, [
-                    common._PASSED_ATTR_KEY, common._FAILED_ATTR_KEY,
-                    common._MODULES_TOTAL_ATTR_KEY,
-                    common._MODULES_DONE_ATTR_KEY
-                ])
-
-            suite_res_msg.build_id = result_attrs[
-                common._SUITE_BUILD_NUM_ATTR_KEY]
-            suite_res_msg.suite_name = result_attrs[
-                common._SUITE_NAME_ATTR_KEY]
-            suite_res_msg.suite_plan = result_attrs[
-                common._SUITE_PLAN_ATTR_KEY]
-            suite_res_msg.suite_version = result_attrs[
-                common._SUITE_VERSION_ATTR_KEY]
-            suite_res_msg.suite_build_number = result_attrs[
-                common._SUITE_BUILD_NUM_ATTR_KEY]
-            suite_res_msg.start_time = long(
-                result_attrs[common._START_TIME_ATTR_KEY])
-            suite_res_msg.end_time = long(
-                result_attrs[common._END_TIME_ATTR_KEY])
-            suite_res_msg.host_name = result_attrs[common._HOST_NAME_ATTR_KEY]
-            if common._SYSTEM_FINGERPRINT_ATTR_KEY in build_attrs:
-                suite_res_msg.build_system_fingerprint = build_attrs[
-                    common._SYSTEM_FINGERPRINT_ATTR_KEY]
-            else:
-                suite_res_msg.build_system_fingerprint = build_attrs[
-                    common._FINGERPRINT_ATTR_KEY]
-            if common._VENDOR_FINGERPRINT_ATTR_KEY in build_attrs:
-                suite_res_msg.build_vendor_fingerprint = build_attrs[
-                    common._VENDOR_FINGERPRINT_ATTR_KEY]
-            else:
-                suite_res_msg.build_vendor_fingerprint = build_attrs[
-                    common._FINGERPRINT_ATTR_KEY]
-            suite_res_msg.passed_test_case_count = int(
-                summary_attrs[common._PASSED_ATTR_KEY])
-            suite_res_msg.failed_test_case_count = int(
-                summary_attrs[common._FAILED_ATTR_KEY])
-            suite_res_msg.modules_done = int(
-                summary_attrs[common._MODULES_DONE_ATTR_KEY])
-            suite_res_msg.modules_total = int(
-                summary_attrs[common._MODULES_TOTAL_ATTR_KEY])
-        else:
-            suite_res_msg.build_id = self.console.fetch_info["build_id"]
-            suite_res_msg.suite_name = suite_name
-            suite_res_msg.suite_plan = plan_name
-            suite_res_msg.suite_version = ""
-            suite_res_msg.suite_build_number = suite_res_msg.build_id
-            suite_res_msg.start_time = long(time.time() * 1000)
-            suite_res_msg.end_time = suite_res_msg.start_time
-            suite_res_msg.host_name = socket.gethostname()
-            suite_res_msg.build_vendor_fingerprint = "%s/%s/%s" % (
-                device_fetch_info["branch"], device_fetch_info["target"],
-                device_fetch_info["build_id"])
-            if gsi_fetch_info:
-                suite_res_msg.build_system_fingerprint = "%s/%s/%s" % (
-                    gsi_fetch_info["branch"], gsi_fetch_info["target"],
-                    gsi_fetch_info["build_id"])
-            else:
-                suite_res_msg.build_system_fingerprint = suite_res_msg.build_vendor_fingerprint
-            suite_res_msg.passed_test_case_count = 0
-            suite_res_msg.failed_test_case_count = 0
-            suite_res_msg.modules_done = 0
-            suite_res_msg.modules_total = 0
-
-        suite_res_msg.infra_log_path = self.console.FormatString(
-            "{hc_log_upload_path}")
-        repack_path_list = []
-        repack_path_list.append(self.console.FormatString("{repack_path}"))
-        suite_res_msg.repacked_image_path.extend(repack_path_list)
-
-        suite_res_msg.schedule_config.build_target.extend(
-            [SchedCfgMsg.BuildScheduleConfigMessage()])
-        build_target_msg = suite_res_msg.schedule_config.build_target[0]
-        build_target_msg.test_schedule.extend(
-            [SchedCfgMsg.TestScheduleConfigMessage()])
-        test_schedule_msg = build_target_msg.test_schedule[0]
-
-        suite_res_msg.vendor_build_id = device_fetch_info["build_id"]
-        suite_res_msg.schedule_config.manifest_branch = str(
-            device_fetch_info["branch"])
-        build_target_msg.name = str(device_fetch_info["target"])
-        if device_fetch_info["account_id"]:
-            suite_res_msg.schedule_config.pab_account_id = str(
-                device_fetch_info["account_id"])
-        if device_fetch_info["fetch_signed_build"]:
-            build_target_msg.require_signed_device_build = device_fetch_info[
-                "fetch_signed_build"]
-        if gsi_fetch_info:
-            test_schedule_msg.gsi_branch = str(gsi_fetch_info["branch"])
-            test_schedule_msg.gsi_build_target = str(gsi_fetch_info["target"])
-            suite_res_msg.gsi_build_id = str(gsi_fetch_info["build_id"])
-            if gsi_fetch_info["account_id"]:
-                test_schedule_msg.gsi_pab_account_id = str(
-                    gsi_fetch_info["account_id"])
-            test_schedule_msg.gsi_vendor_version = str(
-                self.console.FormatString("{gsispl.vendor_version}"))
-        test_schedule_msg.test_pab_account_id = str(
-            self.console.FormatString("{account_id}"))
-        build_target_msg.has_bootloader_img = "bootloader.img" in self.console.device_image_info
-        build_target_msg.has_radio_img = "radio.img" in self.console.device_image_info
-
-        report_file_path = os.path.join(
-            self.console.tmp_logdir,
-            self.console.FormatString("{timestamp_time}.bin"))
-        with open(report_file_path, "w") as fd:
-            fd.write(suite_res_msg.SerializeToString())
-            fd.close()
-
-        copy_command = "{} cp {} {}".format(
-            gsutil_path, report_file_path,
-            os.path.join(report_path, os.path.basename(report_file_path)))
-        _, stderr, err_code = cmd_utils.ExecuteOneShellCommand(copy_command)
-        if err_code:
-            logging.error(stderr)
diff --git a/harnesses/host_controller/command_processor/command_upload_test.py b/harnesses/host_controller/command_processor/command_upload_test.py
deleted file mode 100644
index 67ccb69..0000000
--- a/harnesses/host_controller/command_processor/command_upload_test.py
+++ /dev/null
@@ -1,312 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import common
-from host_controller.command_processor import command_upload
-
-
-def side_effect(value):
-    return value
-
-
-class CommandUploadTest(unittest.TestCase):
-    """Tests for upload command processor"""
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.open")
-    @mock.patch("host_controller.command_processor.command_upload.cmd_utils")
-    @mock.patch("host_controller.command_processor.command_upload.SuiteResMsg")
-    @mock.patch("host_controller.command_processor.command_upload.SchedCfgMsg")
-    def testUploadReportBootupErr(self, mock_sched_config_msg,
-                                  mock_suite_res_msg, mock_cmd_util, mock_open,
-                                  mock_console):
-        mock_open.__enter__ = mock.Mock(return_value=mock_open)
-        mock_open.__exit__ = mock.Mock(return_value=None)
-        mock_cmd_util.ExecuteOneShellCommand = mock.Mock(
-            return_value=("", "", 0))
-        mock_console.vti_endpoint_client.CheckBootUpStatus.return_value = False
-        mock_console.FormatString.side_effect = side_effect
-        mock_console.fetch_info = {
-            "branch": "git_device_branch",
-            "target": "device-userdebug",
-            "build_id": "1234567",
-            "account_id": common._DEFAULT_ACCOUNT_ID,
-        }
-        mock_console.detailed_fetch_info = {
-            "device": {
-                "branch": "git_device_branch",
-                "target": "device-userdebug",
-                "build_id": "1234567",
-                "account_id": common._DEFAULT_ACCOUNT_ID,
-                "fetch_signed_build": False,
-            },
-            "gsi": {
-                "branch": "git_aosp_gsi_branch",
-                "target": "gsi-userdebug",
-                "build_id": "2345678",
-                "account_id": common._DEFAULT_ACCOUNT_ID_INTERNAL,
-            }
-        }
-        mock_console.tmp_logdir = "tmp/log"
-        mock_console.device_image_info = {
-            "bootloader.img": "path/to/bootloader.img"
-        }
-        mock_pb2 = mock.Mock()
-        mock_pb2.repacked_image_path = []
-        mock_pb2.schedule_config.build_target = []
-        mock_build_sched_config_pb2 = mock.Mock()
-        mock_build_sched_config_pb2.test_schedule = []
-        mock_test_sched_config_pb2 = mock.Mock()
-        mock_suite_res_msg.TestSuiteResultMessage.return_value = mock_pb2
-        mock_sched_config_msg.BuildScheduleConfigMessage.return_value = (
-            mock_build_sched_config_pb2)
-        mock_sched_config_msg.TestScheduleConfigMessage.return_value = (
-            mock_test_sched_config_pb2)
-        command = command_upload.CommandUpload()
-        command._SetUp(mock_console)
-        command.UploadReport("/path/to/bin/gsutil", "gs://report-bucket/",
-                             "tmp/console.log", "tmp/result.log", "vts",
-                             "some_plan")
-        self.assertEqual(mock_pb2.build_id, "1234567")
-        self.assertEqual(mock_pb2.suite_name, "vts")
-        self.assertEqual(mock_pb2.suite_plan, "some_plan")
-        self.assertEqual(mock_pb2.suite_build_number, mock_pb2.build_id)
-        self.assertEqual(mock_pb2.build_system_fingerprint,
-                         "git_aosp_gsi_branch/gsi-userdebug/2345678")
-        self.assertEqual(mock_pb2.build_vendor_fingerprint,
-                         "git_device_branch/device-userdebug/1234567")
-        self.assertEqual(mock_pb2.repacked_image_path, ["{repack_path}"])
-        self.assertEqual(mock_pb2.schedule_config.manifest_branch,
-                         "git_device_branch")
-        self.assertEqual(mock_pb2.schedule_config.pab_account_id,
-                         common._DEFAULT_ACCOUNT_ID)
-
-        self.assertTrue(mock_build_sched_config_pb2.has_bootloader_img)
-        self.assertFalse(mock_build_sched_config_pb2.has_radio_img)
-
-        self.assertEqual(mock_test_sched_config_pb2.gsi_branch,
-                         "git_aosp_gsi_branch")
-        self.assertEqual(mock_test_sched_config_pb2.gsi_build_target,
-                         "gsi-userdebug")
-        self.assertEqual(mock_test_sched_config_pb2.gsi_pab_account_id,
-                         common._DEFAULT_ACCOUNT_ID_INTERNAL)
-        mock_cmd_util.ExecuteOneShellCommand.assert_called_with(
-            "/path/to/bin/gsutil cp tmp/log/{timestamp_time}.bin "
-            "gs://report-bucket/{timestamp_time}.bin")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.open")
-    @mock.patch("host_controller.command_processor.command_upload.cmd_utils")
-    @mock.patch("host_controller.command_processor.command_upload.SuiteResMsg")
-    @mock.patch("host_controller.command_processor.command_upload.os")
-    @mock.patch("host_controller.command_processor.command_upload.xml_utils")
-    @mock.patch("host_controller.command_processor.command_upload.SchedCfgMsg")
-    def testUploadReportBootupOk(self, mock_sched_config_msg, mock_xml_util,
-                                 mock_os, mock_suite_res_msg, mock_cmd_util,
-                                 mock_open, mock_console):
-        mock_open.__enter__ = mock.Mock(return_value=mock_open)
-        mock_open.__exit__ = mock.Mock(return_value=None)
-        mock_cmd_util.ExecuteOneShellCommand = mock.Mock(
-            return_value=("", "", 0))
-        mock_console.vti_endpoint_client.CheckBootUpStatus.return_value = True
-        mock_console.FormatString.side_effect = side_effect
-        mock_console.tmp_logdir = "tmp/log"
-        mock_pb2 = mock.Mock()
-        mock_pb2.repacked_image_path = []
-        mock_pb2.schedule_config.build_target = []
-        mock_build_sched_config_pb2 = mock.Mock()
-        mock_build_sched_config_pb2.test_schedule = []
-        mock_test_sched_config_pb2 = mock.Mock()
-        mock_suite_res_msg.TestSuiteResultMessage.return_value = mock_pb2
-        mock_sched_config_msg.BuildScheduleConfigMessage.return_value = (
-            mock_build_sched_config_pb2)
-        mock_sched_config_msg.TestScheduleConfigMessage.return_value = (
-            mock_test_sched_config_pb2)
-        mock_os.listdir.return_value = ["1", "2", "3"]
-        mock_os.path.isdir.return_value = True
-        mock_os.path.islink.return_value = False
-        mock_os.path.join = os.path.join
-        mock_os.path.basename = os.path.basename
-        mock_xml_util.GetAttributes.return_value = {
-            common._SUITE_NAME_ATTR_KEY:
-            "vts",
-            common._SUITE_PLAN_ATTR_KEY:
-            "some_plan",
-            common._SUITE_VERSION_ATTR_KEY:
-            "8.0_R1",
-            common._SUITE_BUILD_NUM_ATTR_KEY:
-            "1234567",
-            common._START_TIME_ATTR_KEY:
-            "0",
-            common._END_TIME_ATTR_KEY:
-            "1",
-            common._HOST_NAME_ATTR_KEY:
-            "this-host",
-            common._FINGERPRINT_ATTR_KEY:
-            "git_device_branch/device-userdebug/1234567",
-            common._SYSTEM_FINGERPRINT_ATTR_KEY:
-            "git_aosp_gsi_branch/gsi-userdebug/2345678",
-            common._VENDOR_FINGERPRINT_ATTR_KEY:
-            "git_device_branch/device-userdebug/1234567",
-            common._PASSED_ATTR_KEY:
-            "1265",
-            common._FAILED_ATTR_KEY:
-            "43",
-            common._MODULES_TOTAL_ATTR_KEY:
-            "100",
-            common._MODULES_DONE_ATTR_KEY:
-            "98",
-        }
-        command = command_upload.CommandUpload()
-        command._SetUp(mock_console)
-        command.UploadReport("/path/to/bin/gsutil", "gs://report-bucket/",
-                             "tmp/console.log", "tmp/vts/results", "vts",
-                             "some_plan")
-        self.assertEqual(mock_pb2.build_id, "1234567")
-        self.assertEqual(mock_pb2.suite_name, "vts")
-        self.assertEqual(mock_pb2.suite_plan, "some_plan")
-        self.assertEqual(mock_pb2.suite_version, "8.0_R1")
-        self.assertEqual(mock_pb2.suite_build_number, mock_pb2.build_id)
-        self.assertEqual(mock_pb2.start_time, 0)
-        self.assertEqual(mock_pb2.end_time, 1)
-        self.assertEqual(mock_pb2.host_name, "this-host")
-        self.assertEqual(mock_pb2.build_system_fingerprint,
-                         "git_aosp_gsi_branch/gsi-userdebug/2345678")
-        self.assertEqual(mock_pb2.build_vendor_fingerprint,
-                         "git_device_branch/device-userdebug/1234567")
-        self.assertEqual(mock_pb2.passed_test_case_count, 1265)
-        self.assertEqual(mock_pb2.failed_test_case_count, 43)
-        self.assertEqual(mock_pb2.modules_total, 100)
-        self.assertEqual(mock_pb2.modules_done, 98)
-        self.assertEqual(mock_pb2.repacked_image_path, ["{repack_path}"])
-        mock_cmd_util.ExecuteOneShellCommand.assert_called_with(
-            "/path/to/bin/gsutil cp tmp/log/{timestamp_time}.bin "
-            "gs://report-bucket/{timestamp_time}.bin")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.os")
-    @mock.patch("host_controller.command_processor.command_upload.logging")
-    def testUploadReportResultDirAbsent(self, mock_logger, mock_os,
-                                        mock_console):
-        mock_console.vti_endpoint_client.CheckBootUpStatus.return_value = True
-        mock_console.FormatString.side_effect = side_effect
-        mock_console.tmp_logdir = "tmp/log"
-        mock_os.listdir.return_value = []
-        command = command_upload.CommandUpload()
-        command._SetUp(mock_console)
-        ret = command.UploadReport("/path/to/bin/gsutil",
-                                   "gs://report-bucket/", "tmp/console.log",
-                                   "tmp/result.log", "vts", "some_plan")
-        self.assertFalse(ret)
-        mock_logger.error.assert_called_with("No test result found.")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_upload.logging")
-    def testCommandUploadGsutilAbsent(self, mock_logger, mock_gcs_util,
-                                      mock_console):
-        mock_gcs_util.GetGsutilPath.return_value = ""
-        command = command_upload.CommandUpload()
-        command.UploadReport = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run("--src=tmp/result.log --dest=gs://report-bucket/")
-        self.assertFalse(ret)
-        mock_logger.error.assert_called_with(
-            "Please check gsutil is installed and on your PATH")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_upload.logging")
-    def testCommandUploadLatestSrc(self, mock_logger, mock_gcs_util,
-                                   mock_console):
-        mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil"
-        command = command_upload.CommandUpload()
-        command.UploadReport = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run(
-            "--src=latest-something.img --dest=gs://report-bucket/")
-        self.assertFalse(ret)
-        mock_logger.error.assert_called_with(
-            "Unable to find something.img in device_image_info")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_upload.os")
-    def testCommandUploadLatestLegitSrc(self, mock_os, mock_gcs_util,
-                                        mock_console):
-        mock_os.path.isfile.return_value = True
-        mock_console.device_image_info = {"system.img": "path/to/system.img"}
-        mock_console.FormatString.side_effect = side_effect
-        mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil"
-        command = command_upload.CommandUpload()
-        command.UploadReport = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run(
-            "--src=latest-system.img --dest=gs://report-bucket/dir "
-            "--clear_dest")
-        self.assertIsNone(ret)
-        mock_gcs_util.Remove.assert_called_with(
-            "/path/to/bin/gsutil", "gs://report-bucket/dir", recursive=True)
-        mock_gcs_util.Copy.assert_called_with('/path/to/bin/gsutil',
-                                              'path/to/system.img',
-                                              'gs://report-bucket/dir')
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_upload.os")
-    @mock.patch("host_controller.command_processor.command_upload.logging")
-    def testCommandUploadFalseDest(self, mock_logger, mock_os, mock_gcs_util,
-                                   mock_console):
-        mock_os.path.isfile.return_value = True
-        mock_console.device_image_info = {"system.img": "path/to/system.img"}
-        mock_console.FormatString.side_effect = side_effect
-        mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil"
-        command = command_upload.CommandUpload()
-        command.UploadReport = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run("--src=latest-system.img --dest=/report-bucket/")
-        self.assertFalse(ret)
-        mock_logger.error.assert_called_with(
-            "/report-bucket/ is not correct GCS url.")
-
-    @mock.patch("host_controller.console.Console")
-    @mock.patch("host_controller.command_processor.command_upload.gcs_utils")
-    @mock.patch("host_controller.command_processor.command_upload.os")
-    def testCommandUploadMultipleFiles(self, mock_os, mock_gcs_util,
-                                       mock_console):
-        mock_os.path.isfile.return_value = True
-        mock_console.FormatString.side_effect = side_effect
-        mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil"
-        command = command_upload.CommandUpload()
-        command.UploadReport = mock.Mock()
-        command._SetUp(mock_console)
-        ret = command._Run("--src=result.zip --dest=gs://report-bucket/")
-        self.assertIsNone(ret)
-        mock_gcs_util.Copy.assert_called_with(
-            '/path/to/bin/gsutil', 'result.zip', 'gs://report-bucket/')
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/common.py b/harnesses/host_controller/common.py
deleted file mode 100644
index 76bb697..0000000
--- a/harnesses/host_controller/common.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# The default Partner Android Build (PAB) public account.
-# To obtain access permission, please reach out to Android partner engineering
-# department of Google LLC.
-
-from vti.test_serving.proto import TestScheduleConfigMessage_pb2 as pb
-
-_DEFAULT_ACCOUNT_ID = '543365459'
-
-# The default Partner Android Build (PAB) internal account.
-_DEFAULT_ACCOUNT_ID_INTERNAL = '541462473'
-
-# The key value used for getting a fetched .zip android img file.
-FULL_ZIPFILE = "full-zipfile"
-# The key of an item that stores the unziped files of a full image zip file.
-FULL_ZIPFILE_DIR = "full-zipfile-dir"
-
-# The key of an item that stores the fetch GSI image (.zip) file.
-GSI_ZIPFILE = "gsi-zipfile"
-# The key of an item that stores the unziped files of a GSI image zip file.
-GSI_ZIPFILE_DIR = "gsi-zipfile-dir"
-
-# The default value for "flash --current".
-_DEFAULT_FLASH_IMAGES = [
-    FULL_ZIPFILE,
-    FULL_ZIPFILE_DIR,
-    "bootloader.img",
-    "boot.img",
-    "cache.img",
-    "radio.img",
-    "system.img",
-    "userdata.img",
-    "vbmeta.img",
-    "vendor.img",
-]
-
-# The environment variable for default serial numbers.
-_ANDROID_SERIAL = "ANDROID_SERIAL"
-
-_DEVICE_STATUS_DICT = {
-    "unknown": 0,
-    "fastboot": 1,
-    "online": 2,
-    "ready": 3,
-    "use": 4,
-    "error": 5,
-    "no-response": 6
-}
-
-_STORAGE_TYPE_DICT = {
-    pb.UNKNOWN_BUILD_STORAGE_TYPE: "unknown",
-    pb.BUILD_STORAGE_TYPE_PAB: "pab",
-    pb.BUILD_STORAGE_TYPE_GCS: "gcs",
-}
-
-_STORAGE_TYPE_DICT_REVERSE = {
-    "unknown": pb.UNKNOWN_BUILD_STORAGE_TYPE,
-    "pab": pb.BUILD_STORAGE_TYPE_PAB,
-    "gcs": pb.BUILD_STORAGE_TYPE_GCS,
-}
-
-# Default SPL date, used for gsispl command
-_SPL_DEFAULT_DAY = 5
-
-# Maximum number of leased jobs per host.
-_MAX_LEASED_JOBS = 14
-
-# Defualt access point for dut wifi_on command.
-_DEFAULT_WIFI_AP = "GoogleGuest"
-
-# SoC name list.
-K39TV1_BSP = "k39tv1_bsp"
-K39TV1_BSP_1G = "k39tv1_bsp_1g"
-
-SDM845 = "sdm845"
-
-UNIVERSAL9810 = "universal9810"
-
-# Lib files from SDM845 vendor system image need to be re-pushed
-# into GSI system image to boot the devices up properly.
-SDM845_LIB_LIST = [
-    "libdrm.so",
-    "vendor.display.color@1.0.so",
-    "vendor.display.config@1.0.so",
-    "vendor.display.config@1.1.so",
-    "vendor.display.postproc@1.0.so",
-    "vendor.qti.hardware.perf@1.0.so",
-]
-
-# Dir name in which the addtional files need to be repacked.
-_ADDITIONAL_FILES_DIR = "additional_file"
-
-# Relative path to the "results" directory from the tools directory.
-_RESULTS_BASE_PATH = "../results"
-
-# Test result file contains invoked test plan results.
-_TEST_RESULT_XML = "test_result.xml"
-
-_LOG_RESULT_XML = "log-result.xml"
-
-# XML tag name whose attributes represent a module.
-_MODULE_TAG = "Module"
-
-# XML tag name whose attribute is test plan.
-_RESULT_TAG = "Result"
-
-# XML tag name whose attributes represent a test case in a module.
-_TESTCASE_TAG = "TestCase"
-
-# XML tag name whose attributes represent a test result in a test case.
-_TEST_TAG = "Test"
-
-# XML tag name whose attributes are about the build info of the device.
-_BUILD_TAG = "Build"
-
-# XML tag name whose attributes are pass/fail count, modules run/total count.
-_SUMMARY_TAG = "Summary"
-
-# The key value for retrieving test plan and etc. from the result xml
-_SUITE_PLAN_ATTR_KEY = "suite_plan"
-
-_SUITE_BUILD_NUM_ATTR_KEY = "suite_build_number"
-
-_SUITE_VERSION_ATTR_KEY = "suite_version"
-
-_HOST_NAME_ATTR_KEY = "host_name"
-
-_START_TIME_ATTR_KEY = "start"
-
-_START_DISPLAY_TIME_ATTR_KEY = "start_display"
-
-_END_TIME_ATTR_KEY = "end"
-
-_END_DISPLAY_TIME_ATTR_KEY = "end_display"
-
-_SUITE_NAME_ATTR_KEY = "suite_name"
-
-# The key value for retrieving build fingerprint values from the result xml.
-_ABIS_ATTR_KEY = "build_abis"
-
-_FINGERPRINT_ATTR_KEY = "build_fingerprint"
-
-_SYSTEM_FINGERPRINT_ATTR_KEY = "build_system_fingerprint"
-
-_VENDOR_FINGERPRINT_ATTR_KEY = "build_vendor_fingerprint"
-
-# The key value for retrieving passed testcase count
-_PASSED_ATTR_KEY = "pass"
-
-# The key value for retrieving failed testcase count
-_FAILED_ATTR_KEY = "failed"
-
-# The key value for retrieving total module count
-_MODULES_TOTAL_ATTR_KEY = "modules_total"
-
-# The key value for retrieving run module count
-_MODULES_DONE_ATTR_KEY = "modules_done"
-
-# The key value for retrieving name of a test, testcase, or module.
-_NAME_ATTR_KEY = "name"
-
-# The key value for retrieving ABI of a module.
-_ABI_ATTR_KEY = "abi"
-
-# The key value for retrieving result of a test.
-_RESULT_ATTR_KEY = "result"
-
-# VTSLAB package version file
-_VTSLAB_VERSION_TXT = "version.txt"
-
-_VTSLAB_VERSION_DEFAULT_VALUE = "000000_000000:00000000"
-
-# String representations of the artifact types can be fetched.
-_ARTIFACT_TYPE_DEVICE = "device"
-_ARTIFACT_TYPE_GSI = "gsi"
-_ARTIFACT_TYPE_TEST_SUITE = "test_suite"
-# Artifact type that are usually for custom tools fetched from GCS.
-_ARTIFACT_TYPE_INFRA = "infra"
-
-# List of artifact types.
-_ARTIFACT_TYPE_LIST = [
-    _ARTIFACT_TYPE_DEVICE,
-    _ARTIFACT_TYPE_GSI,
-    _ARTIFACT_TYPE_TEST_SUITE,
-    _ARTIFACT_TYPE_INFRA,
-]
-# Directory relative to the home directory, in which the devices' lock files will be.
-_DEVLOCK_DIR = ".devlock"
-
-# Default timeout for "adb reboot/fastboot getvar" command in secs.
-DEFAULT_DEVICE_TIMEOUT_SECS = 300
-
-# Maximum number of concurrent adb/fastboot processes.
-MAX_ADB_FASTBOOT_PROCESS = 2
-
-# Default number of the actual retry runs for the "retry" command.
-DEFAULT_RETRY_COUNT = 30
\ No newline at end of file
diff --git a/harnesses/host_controller/console.py b/harnesses/host_controller/console.py
deleted file mode 100644
index 6ab0722..0000000
--- a/harnesses/host_controller/console.py
+++ /dev/null
@@ -1,920 +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.
-#
-
-import cmd
-import ctypes
-import datetime
-import imp  # Python v2 compatibility
-import logging
-import multiprocessing
-import multiprocessing.pool
-import os
-import re
-import shutil
-import signal
-import socket
-import sys
-import tempfile
-import threading
-import time
-import urlparse
-
-from host_controller import common
-from host_controller.command_processor import command_adb
-from host_controller.command_processor import command_build
-from host_controller.command_processor import command_config
-from host_controller.command_processor import command_config_local
-from host_controller.command_processor import command_copy
-from host_controller.command_processor import command_device
-from host_controller.command_processor import command_dut
-from host_controller.command_processor import command_exit
-from host_controller.command_processor import command_fastboot
-from host_controller.command_processor import command_fetch
-from host_controller.command_processor import command_flash
-from host_controller.command_processor import command_gsispl
-from host_controller.command_processor import command_info
-from host_controller.command_processor import command_lease
-from host_controller.command_processor import command_list
-from host_controller.command_processor import command_password
-from host_controller.command_processor import command_release
-from host_controller.command_processor import command_retry
-from host_controller.command_processor import command_request
-from host_controller.command_processor import command_repack
-from host_controller.command_processor import command_sheet
-from host_controller.command_processor import command_shell
-from host_controller.command_processor import command_sleep
-from host_controller.command_processor import command_test
-from host_controller.command_processor import command_reproduce
-from host_controller.command_processor import command_upload
-from host_controller.build import build_info
-from host_controller.build import build_provider_ab
-from host_controller.build import build_provider_gcs
-from host_controller.build import build_provider_local_fs
-from host_controller.build import build_provider_pab
-from host_controller.utils.ipc import file_lock
-from host_controller.utils.ipc import shared_dict
-from host_controller.vti_interface import vti_endpoint_client
-from vts.runners.host import logger
-from vts.utils.python.common import cmd_utils
-
-COMMAND_PROCESSORS = [
-    command_adb.CommandAdb,
-    command_build.CommandBuild,
-    command_config.CommandConfig,
-    command_config_local.CommandConfigLocal,
-    command_copy.CommandCopy,
-    command_device.CommandDevice,
-    command_dut.CommandDUT,
-    command_exit.CommandExit,
-    command_fastboot.CommandFastboot,
-    command_fetch.CommandFetch,
-    command_flash.CommandFlash,
-    command_gsispl.CommandGsispl,
-    command_info.CommandInfo,
-    command_lease.CommandLease,
-    command_list.CommandList,
-    command_password.CommandPassword,
-    command_release.CommandRelease,
-    command_retry.CommandRetry,
-    command_request.CommandRequest,
-    command_repack.CommandRepack,
-    command_sheet.CommandSheet,
-    command_shell.CommandShell,
-    command_sleep.CommandSleep,
-    command_test.CommandTest,
-    command_reproduce.CommandReproduce,
-    command_upload.CommandUpload,
-]
-
-
-class NonDaemonizedProcess(multiprocessing.Process):
-    """Process class which is not daemonized."""
-
-    def _get_daemon(self):
-        return False
-
-    def _set_daemon(self, value):
-        pass
-
-    daemon = property(_get_daemon, _set_daemon)
-
-
-class NonDaemonizedPool(multiprocessing.pool.Pool):
-    """Pool class which is not daemonized."""
-
-    Process = NonDaemonizedProcess
-
-
-def JobMain(vti_address, in_queue, out_queue, device_status, password, hosts):
-    """Main() for a child process that executes a leased job.
-
-    Currently, lease jobs must use VTI (not TFC).
-
-    Args:
-        vti_client: VtiEndpointClient needed to create Console.
-        in_queue: Queue to get new jobs.
-        out_queue: Queue to put execution results.
-        device_status: SharedDict, contains device status information.
-                       shared between processes.
-        password: multiprocessing.managers.ValueProxy, a proxy instance of a
-                  string(ctypes.c_char_p) represents the password which is
-                  to be passed to the prompt when executing certain command
-                  as root user.
-        hosts: A list of HostController objects. Needed for the device command.
-    """
-
-    def SigTermHandler(signum, frame):
-        """Signal handler for exiting pool process explicitly.
-
-        Added to resolve orphaned pool process issue.
-        """
-        sys.exit(0)
-
-    signal.signal(signal.SIGTERM, SigTermHandler)
-
-    vti_client = vti_endpoint_client.VtiEndpointClient(vti_address)
-    console = Console(vti_client, None, None, hosts, job_pool=True)
-    console.device_status = device_status
-    console.password = password
-    multiprocessing.util.Finalize(console, console.__exit__, exitpriority=0)
-
-    while True:
-        command = in_queue.get()
-        if command == "exit":
-            break
-        elif command == "lease":
-            filepath, kwargs = vti_client.LeaseJob(socket.gethostname(), True)
-            logging.debug("Job %s -> %s" % (os.getpid(), kwargs))
-            if filepath is not None:
-                # TODO: redirect console output and add
-                # console command to access them.
-
-                console._build_provider[
-                    "pab"] = build_provider_pab.BuildProviderPAB()
-                console._build_provider[
-                    "gcs"] = build_provider_gcs.BuildProviderGCS()
-
-                for serial in kwargs["serial"]:
-                    console.ChangeDeviceState(
-                        serial, common._DEVICE_STATUS_DICT["use"])
-                print_to_console = True
-                if not print_to_console:
-                    sys.stdout = out
-                    sys.stderr = err
-
-                ret, gcs_log_url = console.ProcessConfigurableScript(
-                    os.path.join(os.getcwd(), "host_controller", "campaigns",
-                                 filepath), **kwargs)
-                if ret:
-                    job_status = "complete"
-                else:
-                    job_status = "infra-err"
-
-                vti_client.StopHeartbeat(job_status, gcs_log_url)
-                logging.info("Job execution complete. "
-                             "Setting job status to {}".format(job_status))
-
-                if not print_to_console:
-                    sys.stdout = sys.__stdout__
-                    sys.stderr = sys.__stderr__
-
-                for serial in kwargs["serial"]:
-                    console.ChangeDeviceState(
-                        serial, common._DEVICE_STATUS_DICT["ready"])
-
-                del console._build_provider["pab"]
-                del console._build_provider["gcs"]
-                console.fetch_info = {}
-                console._detailed_fetch_info = {}
-        else:
-            logging.error("Unknown job command %s", command)
-
-    out_queue.put("exit")
-
-
-class Console(cmd.Cmd):
-    """The console for host controllers.
-
-    Attributes:
-        command_processors: dict of string:BaseCommandProcessor,
-                            map between command string and command processors.
-        device_image_info: dict containing info about device image files.
-        prompt: The prompt string at the beginning of each command line.
-        test_result: dict containing info about the last test result.
-        test_suite_info: dict containing info about test suite package files.
-        tools_info: dict containing info about custom tool files.
-        scheduler_thread: dict containing threading.Thread instances(s) that
-                          update configs regularly.
-        _build_provider_pab: The BuildProviderPAB used to download artifacts.
-        _vti_address: string, VTI service URI.
-        _vti_client: VtiEndpoewrClient, used to upload data to a test
-                     scheduling infrastructure.
-        _tfc_client: The TfcClient that the host controllers connect to.
-        _hosts: A list of HostController objects.
-        _in_file: The input file object.
-        _out_file: The output file object.
-        _serials: A list of string where each string is a device serial.
-        _device_status: SharedDict, shared with process pool.
-                        contains status data on each devices.
-        _job_pool: bool, True if Console is created from job pool process
-                   context.
-        _password: multiprocessing.managers.ValueProxy, a proxy instance of a
-                   string(ctypes.c_char_p) represents the password which is
-                   to be passed to the prompt when executing certain command
-                   as root user.
-        _manager: SyncManager. an instance of a manager for shared objects and
-                  values between processes.
-        _vtslab_version: string, contains version information of vtslab package.
-                         (<git commit timestamp>:<git commit hash value>)
-        _detailed_fetch_info: A nested dict, holds the branch and target value
-                              of the device, gsi, or test suite artifact.
-        _file_lock: FileLock, an instance used for synchronizing the devices'
-                    use when the automated self-update happens.
-    """
-
-    def __init__(self,
-                 vti_endpoint_client,
-                 tfc,
-                 pab,
-                 host_controllers,
-                 vti_address=None,
-                 in_file=sys.stdin,
-                 out_file=sys.stdout,
-                 job_pool=False,
-                 password=None):
-        """Initializes the attributes and the parsers."""
-        # cmd.Cmd is old-style class.
-        cmd.Cmd.__init__(self, stdin=in_file, stdout=out_file)
-        self._build_provider = {}
-        self._job_pool = job_pool
-        if not self._job_pool:
-            self._build_provider["pab"] = pab
-            self._build_provider["gcs"] = build_provider_gcs.BuildProviderGCS()
-            self._build_provider[
-                "local_fs"] = build_provider_local_fs.BuildProviderLocalFS()
-            self._build_provider["ab"] = build_provider_ab.BuildProviderAB()
-            self._manager = multiprocessing.Manager()
-            self._device_status = shared_dict.SharedDict(self._manager)
-            self._password = self._manager.Value(ctypes.c_char_p, password)
-            try:
-                with open(common._VTSLAB_VERSION_TXT, "r") as file:
-                    self._vtslab_version = file.readline().strip()
-                    file.close()
-                    logging.info("VTSLAB version: %s" % self._vtslab_version)
-            except IOError as e:
-                logging.exception(e)
-                logging.error("Version info missing in vtslab package. "
-                              "Setting version as %s",
-                              common._VTSLAB_VERSION_DEFAULT_VALUE)
-                self._vtslab_version = common._VTSLAB_VERSION_DEFAULT_VALUE
-            self._logfile_upload_path = ""
-
-        self._vti_endpoint_client = vti_endpoint_client
-        self._vti_address = vti_address
-        self._tfc_client = tfc
-        self._hosts = host_controllers
-        self._in_file = in_file
-        self._out_file = out_file
-        self.prompt = "> "
-        self.command_processors = {}
-        self.device_image_info = build_info.BuildInfo()
-        self.test_result = {}
-        self.test_suite_info = build_info.BuildInfo()
-        self.tools_info = build_info.BuildInfo()
-        self.fetch_info = {}
-        self._detailed_fetch_info = {}
-        self.test_results = {}
-        self._file_lock = file_lock.FileLock()
-        self.repack_dest_path = ""
-
-        if common._ANDROID_SERIAL in os.environ:
-            self._serials = [os.environ[common._ANDROID_SERIAL]]
-        else:
-            self._serials = []
-
-        self.InitCommandModuleParsers()
-        self.SetUpCommandProcessors()
-
-        tempdir_base = os.path.join(os.getcwd(), "tmp")
-        if not os.path.exists(tempdir_base):
-            os.mkdir(tempdir_base)
-        self._tmpdir_default = tempfile.mkdtemp(dir=tempdir_base)
-        self._tmp_logdir = tempfile.mkdtemp(dir=tempdir_base)
-        if not self._job_pool:
-            self._logfile_path = logger.setupTestLogger(
-                self._tmp_logdir, create_symlink=False)
-
-    def __exit__(self):
-        """Finalizes the build provider attributes explicitly when exited."""
-        for bp in self._build_provider:
-            self._build_provider[bp].__del__()
-        if os.path.exists(self._tmp_logdir):
-            shutil.rmtree(self._tmp_logdir)
-
-    @property
-    def job_pool(self):
-        """getter for self._job_pool"""
-        return self._job_pool
-
-    @property
-    def device_status(self):
-        """getter for self._device_status"""
-        return self._device_status
-
-    @device_status.setter
-    def device_status(self, device_status):
-        """setter for self._device_status"""
-        self._device_status = device_status
-
-    @property
-    def build_provider(self):
-        """getter for self._build_provider"""
-        return self._build_provider
-
-    @property
-    def tmpdir_default(self):
-        """getter for self._password"""
-        return self._tmpdir_default
-
-    @tmpdir_default.setter
-    def tmpdir_default(self, tmpdir):
-        """getter for self._password"""
-        self._tmpdir_default = tmpdir
-
-    @property
-    def password(self):
-        """getter for self._password"""
-        return self._password
-
-    @password.setter
-    def password(self, password):
-        """getter for self._password"""
-        self._password = password
-
-    @property
-    def logfile_path(self):
-        """getter for self._logfile_path"""
-        return self._logfile_path
-
-    @property
-    def tmp_logdir(self):
-        """getter for self._tmp_logdir"""
-        return self._tmp_logdir
-
-    @property
-    def vti_endpoint_client(self):
-        """getter for self._vti_endpoint_client"""
-        return self._vti_endpoint_client
-
-    @property
-    def vtslab_version(self):
-        """getter for self._vtslab_version"""
-        return self._vtslab_version
-
-    @property
-    def detailed_fetch_info(self):
-        return self._detailed_fetch_info
-
-    def UpdateFetchInfo(self, artifact_type):
-        if artifact_type in common._ARTIFACT_TYPE_LIST:
-            self._detailed_fetch_info[artifact_type] = {}
-            self._detailed_fetch_info[artifact_type].update(self.fetch_info)
-        else:
-            logging.error("Unrecognized artifact type: %s", artifact_type)
-
-    @property
-    def file_lock(self):
-        """getter for self._file_lock"""
-        return self._file_lock
-
-    def ChangeDeviceState(self, serial, state):
-        """Changes a device's state and (un)locks the file lock if necessary.
-
-        Args:
-            serial: string, serial number of a device.
-            state: int, devices' status value pre-defined in
-                   common._DEVICE_STATUS_DICT.
-        Returns:
-            True if the state change and locking/unlocking are successful.
-            False otherwise.
-        """
-        if state == common._DEVICE_STATUS_DICT["use"]:
-            ret = self._file_lock.LockDevice(serial)
-            if ret == False:
-                return False
-
-        current_status = self.device_status[serial]
-        self.device_status[serial] = state
-
-        if (current_status in (common._DEVICE_STATUS_DICT["use"],
-                               common._DEVICE_STATUS_DICT["error"])
-                and current_status != state):
-            self._file_lock.UnlockDevice(serial)
-
-    def InitCommandModuleParsers(self):
-        """Init all console command modules"""
-        for name in dir(self):
-            if name.startswith('_Init') and name.endswith('Parser'):
-                attr_func = getattr(self, name)
-                if hasattr(attr_func, '__call__'):
-                    attr_func()
-
-    def SetUpCommandProcessors(self):
-        """Sets up all command processors."""
-        for command_processor in COMMAND_PROCESSORS:
-            cp = command_processor()
-            cp._SetUp(self)
-            do_text = "do_%s" % cp.command
-            help_text = "help_%s" % cp.command
-            setattr(self, do_text, cp._Run)
-            setattr(self, help_text, cp._Help)
-            self.command_processors[cp.command] = cp
-
-    def TearDown(self):
-        """Removes all command processors."""
-        for command_processor in self.command_processors.itervalues():
-            command_processor._TearDown()
-        self.command_processors.clear()
-        self.__exit__()
-
-    def FormatString(self, format_string):
-        """Replaces variables with the values in the console's dictionaries.
-
-        Args:
-            format_string: The string containing variables enclosed in {}.
-
-        Returns:
-            The formatted string.
-
-        Raises:
-            KeyError if a variable is not found in the dictionaries or the
-            value is empty.
-        """
-
-        def ReplaceVariable(match):
-            """Replacement functioon for re.sub().
-
-            replaces string encased in braces with values in the console's dict.
-
-            Args:
-                match: regex, used for extracting the variable name.
-
-            Returns:
-                string value corresponding to the input variable name.
-            """
-            name = match.group(1)
-            if name in ("build_id", "branch", "target", "account_id"):
-                value = self.fetch_info[name]
-            elif name in ("result_full", "result_zip", "suite_plan",
-                          "suite_name"):
-                value = self.test_result[name]
-            elif "timestamp" in name:
-                current_datetime = datetime.datetime.now()
-                value_date = current_datetime.strftime("%Y%m%d")
-                value_time = current_datetime.strftime("%H%M%S")
-                if "_date" in name:
-                    value = value_date
-                elif "_time" in name:
-                    value = value_time
-                elif "_year" in name:
-                    value = value_date[0:4]
-                elif "_month" in name:
-                    value = value_date[4:6]
-                elif "_day" in name:
-                    value = value_date[6:8]
-                else:
-                    value = "%s-%s" % (value_date, value_time)
-            elif name in ("hc_log", "hc_log_file", "hc_log_upload_path"):
-                # hc_log: full abs path to the current process's infra log.
-                # hc_log_file: infra log file name, with no path information.
-                # hc_log_upload_path: path of the infra log file in GCS.
-                value = self._logfile_path
-                if name == "hc_log_file":
-                    value = os.path.basename(value)
-                elif name == "hc_log_upload_path":
-                    value = self._logfile_upload_path
-            elif name in ("repack_path"):
-                value = self.repack_dest_path
-                self.repack_dest_path = ""
-            elif name in ("hostname"):
-                value = socket.gethostname()
-            elif "." in name and name.split(".")[0] in self.command_processors:
-                command, arg = name.split(".")
-                try:
-                    value = self.command_processors[command].arg_buffer[arg]
-                except KeyError as e:
-                    logging.exception(e)
-                    value = ""
-                if value is None:
-                    value = ""
-            else:
-                value = None
-
-            if value is None:
-                raise KeyError(name)
-
-            return value
-
-        return re.sub("{([^}]+)}", ReplaceVariable, format_string)
-
-    def ProcessScript(self, script_file_path):
-        """Processes a .py script file.
-
-        A script file implements a function which emits a list of console
-        commands to execute. That function emits an empty list or None if
-        no more command needs to be processed.
-
-        Args:
-            script_file_path: string, the path of a script file (.py file).
-
-        Returns:
-            True if successful; False otherwise
-        """
-        if not script_file_path.endswith(".py"):
-            logging.error("Script file is not .py file: %s" % script_file_path)
-            return False
-
-        script_module = imp.load_source('script_module', script_file_path)
-
-        commands = script_module.EmitConsoleCommands()
-        if commands:
-            for command in commands:
-                ret = self.onecmd(command)
-                if ret == False:
-                    return False
-        return True
-
-    def ProcessConfigurableScript(self, script_file_path, **kwargs):
-        """Processes a .py script file.
-
-        A script file implements a function which emits a list of console
-        commands to execute. That function emits an empty list or None if
-        no more command needs to be processed.
-
-        Args:
-            script_file_path: string, the path of a script file (.py file).
-            kwargs: extra args for the interface function defined in
-                    the script file.
-
-        Returns:
-            True if successful; False otherwise
-            String which represents URL to the upload infra log file.
-        """
-        if script_file_path and not script_file_path.endswith(".py"):
-            script_file_path += ".py"
-
-        if not script_file_path.endswith(".py"):
-            logging.error("Script file is not .py file: %s", script_file_path)
-            return False
-
-        ret = True
-
-        self._logfile_path, file_handler = logger.addLogFile(self._tmp_logdir)
-        src = self.FormatString("{hc_log}")
-        dest = self.FormatString(
-            "gs://vts-report/infra_log/{hostname}/%s_{timestamp}/{hc_log_file}"
-            % kwargs["build_target"])
-        self._logfile_upload_path = dest
-
-        script_module = imp.load_source('script_module', script_file_path)
-
-        commands = script_module.EmitConsoleCommands(**kwargs)
-        logging.info("Command list: %s", commands)
-        if commands:
-            logging.info("Console commands: %s", commands)
-            for command in commands:
-                ret = self.onecmd(command)
-                if ret == False:
-                    break
-        else:
-            ret = False
-
-        file_handler.flush()
-        infra_log_upload_command = "upload"
-        infra_log_upload_command += " --src=%s" % src
-        infra_log_upload_command += " --dest=%s" % dest
-        for serial in kwargs["serial"]:
-            if self.device_status[serial] == common._DEVICE_STATUS_DICT[
-                    "error"]:
-                self.vti_endpoint_client.SetJobStatusFromLeasedTo("bootup-err")
-                break
-        if not self.vti_endpoint_client.CheckBootUpStatus():
-            infra_log_upload_command += (" --report_path=gs://vts-report/"
-                                         "suite_result/{timestamp_year}/"
-                                         "{timestamp_month}/{timestamp_day}")
-            suite_name, plan_name = kwargs["test_name"].split("/")
-            infra_log_upload_command += (
-                " --result_from_suite=%s" % suite_name)
-            infra_log_upload_command += (" --result_from_plan=%s" % plan_name)
-        self.onecmd(infra_log_upload_command)
-        if self.GetSerials():
-            self.onecmd("device --update=stop")
-        logging.getLogger().removeHandler(file_handler)
-        os.remove(self._logfile_path)
-        return (ret != False), dest
-
-    def _Print(self, string):
-        """Prints a string and a new line character.
-
-        Args:
-            string: The string to be printed.
-        """
-        self._out_file.write(string + "\n")
-
-    def _PrintObjects(self, objects, attr_names):
-        """Shows objects as a table.
-
-        Args:
-            object: The objects to be shown, one object in a row.
-            attr_names: The attributes to be shown, one attribute in a column.
-        """
-        width = [len(name) for name in attr_names]
-        rows = [attr_names]
-        for dev_info in objects:
-            attrs = [
-                _ToPrintString(getattr(dev_info, name, ""))
-                for name in attr_names
-            ]
-            rows.append(attrs)
-            for index, attr in enumerate(attrs):
-                width[index] = max(width[index], len(attr))
-
-        for row in rows:
-            self._Print("  ".join(
-                attr.ljust(width[index]) for index, attr in enumerate(row)))
-
-    def DownloadTestResources(self, request_id):
-        """Download all of the test resources for a TFC request id.
-
-        Args:
-            request_id: int, TFC request id
-        """
-        resources = self._tfc_client.TestResourceList(request_id)
-        for resource in resources:
-            self.DownloadTestResource(resource['url'])
-
-    def DownloadTestResource(self, url):
-        """Download a test resource with build provider, given a url.
-
-        Args:
-            url: a resource locator (not necessarily HTTP[s])
-                with the scheme specifying the build provider.
-        """
-        parsed = urlparse.urlparse(url)
-        path = (parsed.netloc + parsed.path).split('/')
-        if parsed.scheme == "pab":
-            if len(path) != 5:
-                logging.error("Invalid pab resource locator: %s", url)
-                return
-            account_id, branch, target, build_id, artifact_name = path
-            cmd = ("fetch"
-                   " --type=pab"
-                   " --account_id=%s"
-                   " --branch=%s"
-                   " --target=%s"
-                   " --build_id=%s"
-                   " --artifact_name=%s") % (account_id, branch, target,
-                                             build_id, artifact_name)
-            self.onecmd(cmd)
-        elif parsed.scheme == "ab":
-            if len(path) != 4:
-                logging.error("Invalid ab resource locator: %s", url)
-                return
-            branch, target, build_id, artifact_name = path
-            cmd = ("fetch"
-                   "--type=ab"
-                   " --branch=%s"
-                   " --target=%s"
-                   " --build_id=%s"
-                   " --artifact_name=%s") % (branch, target, build_id,
-                                             artifact_name)
-            self.onecmd(cmd)
-        elif parsed.scheme == gcs:
-            cmd = "fetch --type=gcs --path=%s" % url
-            self.onecmd(cmd)
-        else:
-            logging.error("Invalid URL: %s", url)
-
-    def SetSerials(self, serials):
-        """Sets the default serial numbers for flashing and testing.
-
-        Args:
-            serials: A list of strings, the serial numbers.
-        """
-        self._serials = serials
-
-    def FlashImgPackage(self, package_path_gcs):
-        """Fetches a repackaged image set from GCS and flashes to the device(s).
-
-        Args:
-            package_path_gcs: GCS URL to the packaged img zip file. May contain
-                              the GSI imgs.
-        """
-        self.onecmd("fetch --type=gcs --path=%s --full_device_images=True" %
-                    package_path_gcs)
-        if common.FULL_ZIPFILE not in self.device_image_info:
-            logging.error("Failed to fetch the given file: %s",
-                          package_path_gcs)
-            return False
-
-        if not self._serials:
-            logging.error("Please specify the serial number(s) of target "
-                          "device(s) for flashing.")
-            return False
-
-        campaign_common = imp.load_source(
-            'campaign_common',
-            os.path.join(os.getcwd(), "host_controller", "campaigns",
-                         "campaign_common.py"))
-        flash_command_list = []
-
-        for serial in self._serials:
-            flash_commands = []
-            cmd_utils.ExecuteOneShellCommand(
-                "adb -s %s reboot bootloader" % serial)
-            _, stderr, retcode = cmd_utils.ExecuteOneShellCommand(
-                "fastboot -s %s getvar product" % serial)
-            if retcode == 0:
-                res = stderr.splitlines()[0].rstrip()
-                if ":" in res:
-                    product = res.split(":")[1].strip()
-                elif "waiting for %s" % serial in res:
-                    res = stderr.splitlines()[1].rstrip()
-                    product = res.split(":")[1].strip()
-                else:
-                    product = "error"
-            else:
-                product = "error"
-            logging.info("Device %s product type: %s", serial, product)
-            if product in campaign_common.FLASH_COMMAND_EMITTER:
-                flash_commands.append(
-                    campaign_common.FLASH_COMMAND_EMITTER[product](
-                        serial, repacked_imageset=True))
-            elif product != "error":
-                flash_commands.append(
-                    "flash --current --serial %s --skip-vbmeta=True" % serial)
-            else:
-                logging.error(
-                    "Device %s does not exist. Omitting the flashing "
-                    "to the device.", serial)
-                continue
-            flash_command_list.append(flash_commands)
-
-        ret = self.onecmd(flash_command_list)
-        if ret == False:
-            logging.error("Flash failed on device %s.", self._serials)
-        else:
-            logging.info("Flash succeeded on device %s.", self._serials)
-
-        return ret
-
-    def GetSerials(self):
-        """Returns the serial numbers saved in the console.
-
-        Returns:
-            A list of strings, the serial numbers.
-        """
-        return self._serials
-
-    def ResetSerials(self):
-        """Clears all the serial numbers set to this console obj."""
-        self._serials = []
-
-    def JobThread(self):
-        """Job thread which monitors and uploads results."""
-        thread = threading.currentThread()
-        while getattr(thread, "keep_running", True):
-            time.sleep(1)
-
-        if self._job_pool:
-            self._job_pool.close()
-            self._job_pool.terminate()
-            self._job_pool.join()
-
-    def StartJobThreadAndProcessPool(self):
-        """Starts a background thread to control leased jobs."""
-        self._job_in_queue = multiprocessing.Queue()
-        self._job_out_queue = multiprocessing.Queue()
-        self._job_pool = NonDaemonizedPool(
-            common._MAX_LEASED_JOBS, JobMain,
-            (self._vti_address, self._job_in_queue, self._job_out_queue,
-             self._device_status, self._password, self._hosts))
-
-        self._job_thread = threading.Thread(target=self.JobThread)
-        self._job_thread.daemon = True
-        self._job_thread.start()
-
-    def StopJobThreadAndProcessPool(self):
-        """Terminates the thread and processes that runs the leased job."""
-        if hasattr(self, "_job_thread"):
-            self._job_thread.keep_running = False
-            self._job_thread.join()
-
-    def WaitForJobsToExit(self):
-        """Wait for the running jobs to complete before exiting HC."""
-        if self._job_pool:
-            pool_process_count = common._MAX_LEASED_JOBS
-            for _ in range(common._MAX_LEASED_JOBS):
-                self._job_in_queue.put("exit")
-
-            while True:
-                response = self._job_out_queue.get()
-                if response == "exit":
-                    pool_process_count -= 1
-                if pool_process_count <= 0:
-                    break
-
-    # @Override
-    def onecmd(self, line, depth=1, ret_out_queue=None):
-        """Executes command(s) and prints any exception.
-
-        Parallel execution only for 2nd-level list element.
-
-        Args:
-            line: a list of string or string which keeps the command to run.
-        """
-        if not line:
-            return
-
-        if type(line) == list:
-            if depth == 1:  # 1 to use multi-threading
-                jobs = []
-                ret_queue = multiprocessing.Queue()
-                for sub_command in line:
-                    p = multiprocessing.Process(
-                        target=self.onecmd,
-                        args=(
-                            sub_command,
-                            depth + 1,
-                            ret_queue,
-                        ))
-                    jobs.append(p)
-                    p.start()
-                for job in jobs:
-                    job.join()
-
-                ret_cmd_list = True
-                while not ret_queue.empty():
-                    ret_from_subprocess = ret_queue.get()
-                    ret_cmd_list = ret_cmd_list and ret_from_subprocess
-                if ret_cmd_list == False:
-                    return False
-            else:
-                for sub_command in line:
-                    ret_cmd_list = self.onecmd(sub_command, depth + 1)
-                    if ret_cmd_list == False and ret_out_queue:
-                        ret_out_queue.put(False)
-                        return False
-            return
-
-        logging.info("Command: %s", line)
-        try:
-            ret_cmd = cmd.Cmd.onecmd(self, line)
-            if ret_cmd == False and ret_out_queue:
-                ret_out_queue.put(ret_cmd)
-            return ret_cmd
-        except Exception as e:
-            self._Print("%s: %s" % (type(e).__name__, e))
-            if ret_out_queue:
-                ret_out_queue.put(False)
-            return False
-
-    # @Override
-    def emptyline(self):
-        """Ignores empty lines."""
-        pass
-
-    # @Override
-    def default(self, line):
-        """Handles unrecognized commands.
-
-        Returns:
-            True if receives EOF; otherwise delegates to default handler.
-        """
-        if line == "EOF":
-            return self.do_exit(line)
-        return cmd.Cmd.default(self, line)
-
-
-def _ToPrintString(obj):
-    """Converts an object to printable string on console.
-
-    Args:
-        obj: The object to be printed.
-    """
-    if isinstance(obj, (list, tuple, set)):
-        return ",".join(str(x) for x in obj)
-    return str(obj)
diff --git a/harnesses/host_controller/console_argument_parser.py b/harnesses/host_controller/console_argument_parser.py
deleted file mode 100644
index 71a756f..0000000
--- a/harnesses/host_controller/console_argument_parser.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import argparse
-import logging
-
-
-class ConsoleArgumentError(Exception):
-    """Raised when the console fails to parse commands."""
-    pass
-
-
-class ConsoleArgumentParser(argparse.ArgumentParser):
-    """The argument parser for a console command."""
-
-    def __init__(self, command_name, description):
-        """Initializes the ArgumentParser without --help option.
-
-        Args:
-            command_name: A string, the first argument of the command.
-            description: The help message about the command.
-        """
-        super(ConsoleArgumentParser, self).__init__(
-            prog=command_name, description=description, add_help=False)
-
-    def ParseLine(self, line):
-        """Parses a command line.
-
-        Args:
-            line: A string, the command line.
-
-        Returns:
-            An argparse.Namespace object.
-        """
-        return self.parse_args(line.split())
-
-    # @Override
-    def error(self, message):
-        """Raises an exception when failing to parse the command.
-
-        Args:
-            message: The error message.
-
-        Raises:
-            ConsoleArgumentError.
-        """
-        raise ConsoleArgumentError(message)
\ No newline at end of file
diff --git a/harnesses/host_controller/console_test.py b/harnesses/host_controller/console_test.py
deleted file mode 100644
index bd4906a..0000000
--- a/harnesses/host_controller/console_test.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-try:
-    import StringIO as string_io_module
-except ImportError:
-    import io as string_io_module
-
-from host_controller.build import build_flasher
-from host_controller.tfc import command_task
-from host_controller.tfc import device_info
-from host_controller import common
-from host_controller import console
-
-
-class ConsoleTest(unittest.TestCase):
-    """A test for console.Console.
-
-    Attribute:
-        _out_file: The console output buffer.
-        _host_controller: A mock tfc_host_controller.HostController.
-        _build_provider_pab: A mock build_provider_pab.BuildProviderPAB.
-        _tfc_client: A mock tfc_client.TfcClient.
-        _vti_client A mock vti_endpoint_client.VtiEndpointClient.
-        _console: The console being tested.
-    """
-    _DEVICES = [
-        device_info.DeviceInfo(
-            device_serial="ABC001",
-            run_target="sailfish",
-            state="Available",
-            build_id="111111",
-            sdk_version="27")
-    ]
-    _TASKS = [
-        command_task.CommandTask(
-            request_id="1",
-            task_id="1-0",
-            command_id="2",
-            command_line="vts -m SampleShellTest",
-            device_serials=["ABC001"])
-    ]
-
-    def setUp(self):
-        """Creates the console."""
-        self._out_file = string_io_module.StringIO()
-        self._host_controller = mock.Mock()
-        self._build_provider_pab = mock.Mock()
-        self._tfc_client = mock.Mock()
-        self._vti_client = mock.Mock()
-        self._console = console.Console(
-            self._vti_client,
-            self._tfc_client,
-            self._build_provider_pab, [self._host_controller],
-            None,
-            out_file=self._out_file)
-        self._console.device_image_info = {}
-
-    def tearDown(self):
-        """Closes the output file."""
-        self._out_file.close()
-
-    def _IssueCommand(self, command_line):
-        """Issues a command in the console.
-
-        Args:
-            command_line: A string, the input to the console.
-
-        Returns:
-            A string, the output of the console.
-        """
-        out_position = self._out_file.tell()
-        self._console.onecmd(command_line)
-        self._out_file.seek(out_position)
-        return self._out_file.read()
-
-    def testLease(self):
-        """Tests the lease command."""
-        self._host_controller.LeaseCommandTasks.return_value = self._TASKS
-        output = self._IssueCommand("lease")
-        expected = (
-            "request_id  command_id  task_id  device_serials  command_line          \n"
-            "1           2           1-0      ABC001          vts -m SampleShellTest\n"
-        )
-        self.assertEqual(expected, output)
-        output = self._IssueCommand("lease --host 0")
-        self.assertEqual(expected, output)
-
-    def testRequest(self):
-        """Tests the request command."""
-        user = "user0"
-        cluster = "cluster0"
-        run_target = "sailfish"
-        command_line = "vts -m SampleShellTest"
-        self._IssueCommand("request --user %s --cluster %s --run-target %s "
-                           "-- %s" % (user, cluster, run_target, command_line))
-        req = self._tfc_client.NewRequest.call_args[0][0]
-        self.assertEqual(user, req.user)
-        self.assertEqual(cluster, req.cluster)
-        self.assertEqual(run_target, req.run_target)
-        self.assertEqual(command_line, req.command_line)
-
-    def testListHosts(self):
-        """Tests the list command."""
-        self._host_controller.hostname = "host0"
-        output = self._IssueCommand("list hosts")
-        self.assertEqual("index  name\n" "[  0]  host0\n", output)
-
-    def testListDevices(self):
-        """Tests the list command."""
-        self._host_controller.ListDevices.return_value = self._DEVICES
-        self._host_controller.hostname = "host0"
-        output = self._IssueCommand("list devices")
-        expected = (
-            "[  0]  host0\n"
-            "device_serial  state      run_target  build_id  sdk_version  stub\n"
-            "ABC001         Available  sailfish    111111    27               \n"
-        )
-        self.assertEqual(expected, output)
-        output = self._IssueCommand("list devices --host 0")
-        self.assertEqual(expected, output)
-
-    def testWrongHostIndex(self):
-        """Tests host index out of range."""
-        output = self._IssueCommand("list devices --host 1")
-        expected = "IndexError: "
-        self.assertTrue(output.startswith(expected))
-        output = self._IssueCommand("lease --host 1")
-        self.assertTrue(output.startswith(expected))
-
-    @mock.patch('host_controller.build.build_flasher.BuildFlasher')
-    def testFetchPOSTAndFlash(self, mock_class):
-        """Tests fetching from pab and flashing."""
-        self._build_provider_pab.GetArtifact.return_value = ({
-            "system.img":
-            "/mock/system.img",
-            "odm.img":
-            "/mock/odm.img"
-        }, {}, {
-            "build_id":
-            "build_id"
-        }, {})
-        self._build_provider_pab.GetFetchedArtifactType.return_value = common._ARTIFACT_TYPE_DEVICE
-        self._IssueCommand(
-            "fetch --branch=aosp-master-ndk --target=darwin_mac "
-            "--account_id=100621237 "
-            "--artifact_name=foo-{build_id}.tar.bz2 --method=POST")
-        self._build_provider_pab.GetArtifact.assert_called_with(
-            account_id='100621237',
-            branch='aosp-master-ndk',
-            target='darwin_mac',
-            artifact_name='foo-{build_id}.tar.bz2',
-            build_id='latest',
-            method='POST',
-            full_device_images=False)
-        self.assertEqual(self._console.device_image_info, {
-            "system.img": "/mock/system.img",
-            "odm.img": "/mock/odm.img"
-        })
-
-        flasher = mock.Mock()
-        mock_class.return_value = flasher
-        self._IssueCommand("flash --current system=system.img odm=odm.img")
-        flasher.Flash.assert_called_with({
-            "system": "/mock/system.img",
-            "odm": "/mock/odm.img"
-        }, False)
-
-    def testFetchAndEnvironment(self):
-        """Tests fetching from pab and check stored os environment"""
-        build_id_return = "4328532"
-        target_return = "darwin_mac"
-        expected_fetch_info = {"build_id": build_id_return}
-
-        self._build_provider_pab.GetArtifact.return_value = ({
-            "system.img":
-            "/mock/system.img",
-            "odm.img":
-            "/mock/odm.img"
-        }, {}, expected_fetch_info, {})
-        self._IssueCommand(
-            "fetch --branch=aosp-master-ndk --target=%s "
-            "--account_id=100621237 "
-            "--artifact_name=foo-{id}.tar.bz2 --method=POST" % target_return)
-        self._build_provider_pab.GetArtifact.assert_called_with(
-            account_id='100621237',
-            branch='aosp-master-ndk',
-            target='darwin_mac',
-            artifact_name='foo-{id}.tar.bz2',
-            build_id='latest',
-            full_device_images=False,
-            method='POST')
-
-        expected = expected_fetch_info["build_id"]
-        self.assertEqual(build_id_return, expected)
-
-    @mock.patch('host_controller.build.build_flasher.BuildFlasher')
-    def testFlashGSI(self, mock_class):
-        flasher = mock.Mock()
-        mock_class.return_value = flasher
-        self._IssueCommand("flash --gsi=system.img")
-        flasher.FlashGSI.assert_called_with(
-            'system.img', None, skip_vbmeta=False)
-
-    @mock.patch('host_controller.build.build_flasher.BuildFlasher')
-    def testFlashGSIWithVbmeta(self, mock_class):
-        flasher = mock.Mock()
-        mock_class.return_value = flasher
-        self._IssueCommand("flash --gsi=system.img --vbmeta=vbmeta.img")
-        flasher.FlashGSI.assert_called_with(
-            'system.img', 'vbmeta.img', skip_vbmeta=False)
-
-    @mock.patch('host_controller.build.build_flasher.BuildFlasher')
-    def testFlashall(self, mock_class):
-        flasher = mock.Mock()
-        mock_class.return_value = flasher
-        self._IssueCommand("flash --build_dir=path/to/dir/")
-        flasher.Flashall.assert_called_with('path/to/dir/')
-
-    @mock.patch('host_controller.command_processor.command_flash.importlib')
-    @mock.patch('host_controller.command_processor.command_flash.issubclass')
-    def testImportFlasher(self, mock_issubclass, mock_importlib):
-        mock_issubclass.return_value = True
-        flasher_module = mock.Mock()
-        flasher = mock.Mock()
-        mock_importlib.import_module.return_value = flasher_module
-        flasher_module.Flasher.return_value = flasher
-        self._IssueCommand("flash --serial ABC001 "
-                           "--flasher_type test.flasher.Flasher "
-                           "--flasher_path /test/flasher "
-                           "-- --unit test")
-        mock_issubclass.assert_called_once_with(flasher_module.Flasher,
-                                                build_flasher.BuildFlasher)
-        mock_importlib.import_module.assert_called_with("test.flasher")
-        flasher_module.Flasher.assert_called_with("ABC001", "/test/flasher")
-        flasher.Flash.assert_called_with({}, {}, "--unit", "test")
-        flasher.WaitForDevice.assert_called_with()
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/gsi/change_security_patch_ver.sh b/harnesses/host_controller/gsi/change_security_patch_ver.sh
deleted file mode 100755
index 1a09178..0000000
--- a/harnesses/host_controller/gsi/change_security_patch_ver.sh
+++ /dev/null
@@ -1,288 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-# This script modifies the original GSI to match the vendor version and
-# the security patch level.
-#
-# Usage: change_security_patch_ver.sh <system.img> [<output_system.img> \
-#                 [<new_security_patch_level> [<input_file_contexts.bin>]]] \
-#                 [-v <vendor_version>]
-#
-# Examples:
-# change_security_patch_ver.sh system.img
-#   - Shows current version information.
-# change_security_patch_ver.sh system.img new_system.img 2018-04-05
-#   - Make new_system.img that has replaced SPL with 2018-04-05.
-# change_security_patch_ver.sh system.img new_system.img -v 8.1.0
-#   - Make new_system.img that includes the patches for vendor version 8.1.0.
-# change_security_patch_ver.sh system.img new_system.img 2018-04-05 -v 8.1.0
-#   - Make new_system.img that has both new SPL and vendor version.
-
-function unmount() {
-  echo "Unmounting..."
-  sudo umount "${MOUNT_POINT}/"
-}
-
-SCRIPT_NAME=$(basename $0)
-
-declare -a SUPPORTED_VENDOR_VERSIONS=(
-  8.1.0
-  9
-)
-SUPPORTED_VENDOR_VERSIONS="${SUPPORTED_VENDOR_VERSIONS[@]}"
-
-param_count=0
-while [[ $# -gt 0 ]]
-do
-case $1 in
--v|--vendor) # set vendor version
-  VENDOR_VERSION=$2
-  shift
-  shift
-  ;;
-*) # set the ordered parameters
-  ((param_count++))
-  case $param_count in
-  1) # The input file name for original GSI
-    SYSTEM_IMG=$1
-    shift
-    ;;
-  2) # The output file name for modified GSI
-    OUTPUT_SYSTEM_IMG=$1
-    shift
-    ;;
-  3) # New Security Patch Level to be written. It must be YYYY-MM-DD format.
-    NEW_SPL=$1
-    shift
-    ;;
-  4) # Selinux file context
-    FILE_CONTEXTS_BIN=$1
-    shift
-    ;;
-  *)
-    ERROR=true
-    break
-    ;;
-  esac
-  ;;
-esac
-done
-
-if ((param_count == 0)) || [ "$ERROR" == "true" ]; then
-  echo "Usage: $SCRIPT_NAME <system.img> [<output_system.img> [<new_security_patch_level> [<input_file_contexts.bin>]]] [-v <vendor_version>]"
-  exit 1
-fi
-
-# SPL must have YYYY-MM-DD format
-if ((param_count >= 3)) && [[ ! ${NEW_SPL} =~ ^[0-9]{4}-(0[0-9]|1[012])-([012][0-9]|3[01])$ ]]; then
-  echo "<new_security_patch_level> must have YYYY-MM-DD format"
-  exit 1
-fi
-
-if [ "$VENDOR_VERSION" != "" ] && [[ ! ${VENDOR_VERSION} =~ ^(${SUPPORTED_VENDOR_VERSIONS// /\|})$ ]]; then
-  echo "Available vendor_version: $SUPPORTED_VENDOR_VERSIONS"
-  exit 1
-fi
-
-if [ "$VENDOR_VERSION" != "" ] && [ "$OUTPUT_SYSTEM_IMG" == "" ]; then
-  echo "<output_system.img> must be provided to set vendor version"
-  exit 1
-fi
-
-REQUIRED_BINARIES_LIST=(
-  "img2simg"
-  "simg2img"
-)
-if [ ! -z "${FILE_CONTEXTS_BIN}" ]; then
-  REQUIRED_BINARIES_LIST+=("mkuserimg_mke2fs")
-fi
-
-# number of binaries to find.
-BIN_COUNT=${#REQUIRED_BINARIES_LIST[@]}
-
-# use an associative array to store binary path
-declare -A BIN_PATH
-for bin in ${REQUIRED_BINARIES_LIST[@]}; do
-  BIN_PATH[${bin}]=""
-done
-
-# check current PATH environment first
-for bin in ${REQUIRED_BINARIES_LIST[@]}; do
-  if command -v ${bin} >/dev/null 2>&1; then
-    echo "found ${bin} in PATH."
-    BIN_PATH[${bin}]=${bin}
-    ((BIN_COUNT--))
-  fi
-done
-
-if [ ${BIN_COUNT} -gt 0 ]; then
-  # listed in the recommended order.
-  PATH_LIST=("${PWD}")
-  if [ "${PWD##*/}" == "testcases" ] && [ -d "${PWD}/../bin" ]; then
-    PATH_LIST+=("${PWD}/../bin")
-  fi
-  if [ -d "${ANDROID_HOST_OUT}" ]; then
-    PATH_LIST+=("${ANDROID_HOST_OUT}/bin")
-  fi
-
-  for dir in ${PATH_LIST[@]}; do
-    for bin in ${REQUIRED_BINARIES_LIST[@]}; do
-      if [ -z "${BIN_PATH[${bin}]}" ] && [ -f "${dir}/${bin}" ]; then
-        echo "found ${bin} in ${dir}."
-        BIN_PATH[${bin}]=${dir}/${bin}
-        ((BIN_COUNT--))
-        if [ ${BIN_COUNT} -eq 0 ]; then break; fi
-      fi
-    done
-  done
-fi
-
-if [ ${BIN_COUNT} -gt 0 ]; then
-  echo "Cannot find the required binaries. Need lunch; or run in a correct path."
-  exit 1
-fi
-echo "Found all binaries."
-
-MOUNT_POINT="${PWD}/temp_mnt"
-SPL_PROPERTY_NAME="ro.build.version.security_patch"
-RELEASE_VERSION_PROPERTY_NAME="ro.build.version.release"
-VNDK_VERSION_PROPERTY="ro.vndk.version"
-VNDK_VERSION_PROPERTY_OMR1="${VNDK_VERSION_PROPERTY}=27"
-
-UNSPARSED_SYSTEM_IMG="${SYSTEM_IMG}.raw"
-SYSTEM_IMG_MAGIC="$(xxd -g 4 -l 4 "$SYSTEM_IMG" | head -n1 | awk '{print $2}')"
-if [ "$SYSTEM_IMG_MAGIC" = "3aff26ed" ]; then
-  echo "Unsparsing ${SYSTEM_IMG}..."
-  ${BIN_PATH["simg2img"]} "$SYSTEM_IMG" "$UNSPARSED_SYSTEM_IMG"
-else
-  echo "Copying unsparse input system image ${SYSTEM_IMG}..."
-  cp "$SYSTEM_IMG" "$UNSPARSED_SYSTEM_IMG"
-fi
-
-IMG_SIZE=$(stat -c%s "$UNSPARSED_SYSTEM_IMG")
-
-echo "Mounting..."
-mkdir -p "$MOUNT_POINT"
-sudo mount -t ext4 -o loop "$UNSPARSED_SYSTEM_IMG" "${MOUNT_POINT}/"
-
-# check the property file path
-BUILD_PROP_PATH_LIST=(
-  "/system/build.prop"  # layout of A/B support
-  "/build.prop"         # layout of non-A/B support
-)
-BUILD_PROP_MOUNT_PATH=""
-BUILD_PROP_PATH=""
-
-echo "Finding build.prop..."
-for path in ${BUILD_PROP_PATH_LIST[@]}; do
-  if [ -f "${MOUNT_POINT}${path}" ]; then
-    BUILD_PROP_MOUNT_PATH="${MOUNT_POINT}${path}"
-    BUILD_PROP_PATH=${path}
-    echo "  ${path}"
-    break
-  fi
-done
-
-PROP_DEFAULT_PATH_LIST=(
-  "/system/etc/prop.default"  # layout of A/B support
-  "/etc/prop.default"         # layout of non-A/B support
-)
-
-if [ "$BUILD_PROP_MOUNT_PATH" != "" ]; then
-  if [ "$OUTPUT_SYSTEM_IMG" != "" ]; then
-    echo "Replacing..."
-  fi
-  CURRENT_SPL=`sudo sed -n -r "s/^${SPL_PROPERTY_NAME}=(.*)$/\1/p" ${BUILD_PROP_MOUNT_PATH}`
-  CURRENT_VERSION=`sudo sed -n -r "s/^${RELEASE_VERSION_PROPERTY_NAME}=(.*)$/\1/p" ${BUILD_PROP_MOUNT_PATH}`
-  echo "  Current security patch level: ${CURRENT_SPL}"
-  echo "  Current release version: ${CURRENT_VERSION}"
-
-  # Update SPL to <new_security_patch_level>
-  if [[ "$OUTPUT_SYSTEM_IMG" != "" && "$NEW_SPL" != "" ]]; then
-    if [[ "$CURRENT_SPL" == "" ]]; then
-      echo "ERROR: Cannot find ${SPL_PROPERTY_NAME} in ${BUILD_PROP_PATH}"
-    else
-      echo "  New security patch level: ${NEW_SPL}"
-      seek=$(sudo grep --byte-offset "${SPL_PROPERTY_NAME}=" "${BUILD_PROP_MOUNT_PATH}" | cut -d':' -f 1)
-      seek=$(($seek + ${#SPL_PROPERTY_NAME} + 1))   # 1 is for '='
-      echo "${NEW_SPL}" | sudo dd of="${BUILD_PROP_MOUNT_PATH}" seek="$seek" bs=1 count=10 conv=notrunc
-    fi
-  fi
-
-  # Update release version to <vendor_version>
-  if [[ "$OUTPUT_SYSTEM_IMG" != "" && "$VENDOR_VERSION" != "" ]]; then
-    if [[ "$CURRENT_VERSION" == "" ]]; then
-      echo "ERROR: Cannot find ${RELEASE_VERSION_PROPERTY_NAME} in ${BUILD_PROP_PATH}"
-    else
-      echo "  New release version for vendor.img: ${VENDOR_VERSION}"
-      sudo sed -i -e "s/^${RELEASE_VERSION_PROPERTY_NAME}=.*$/${RELEASE_VERSION_PROPERTY_NAME}=${VENDOR_VERSION}/" ${BUILD_PROP_MOUNT_PATH}
-    fi
-
-    if [[ "$VENDOR_VERSION" == "8.1.0" ]]; then
-      # add ro.vndk.version for O-MR1
-      echo "Finding prop.default..."
-      for path in ${PROP_DEFAULT_PATH_LIST[@]}; do
-        if [ -f "${MOUNT_POINT}${path}" ]; then
-          PROP_DEFAULT_PATH=${path}
-          echo "  ${path}"
-          break
-        fi
-      done
-
-      if [[ "$PROP_DEFAULT_PATH" != "" ]]; then
-        CURRENT_VNDK_VERSION=`sudo sed -n -r "s/^${VNDK_VERSION_PROPERTY}=(.*)$/\1/p" ${MOUNT_POINT}${PROP_DEFAULT_PATH}`
-        if [[ "$CURRENT_VNDK_VERSION" != "" ]]; then
-          echo "WARNING: ${VNDK_VERSION_PROPERTY} is already set to ${CURRENT_VNDK_VERSION} in ${PROP_DEFAULT_PATH}"
-        else
-          echo "  Add \"${VNDK_VERSION_PROPERTY_OMR1}\" to ${PROP_DEFAULT_PATH} for O-MR1 vendor image."
-          sudo sed -i -e "\$a\#\n\# FOR O-MR1 DEVICES\n\#\n${VNDK_VERSION_PROPERTY_OMR1}" ${MOUNT_POINT}${PROP_DEFAULT_PATH}
-        fi
-      else
-        echo "ERROR: Cannot find prop.default."
-      fi
-    fi
-  fi
-else
-  echo "ERROR: Cannot find build.prop."
-fi
-
-if [ "$OUTPUT_SYSTEM_IMG" != "" ]; then
-  if [ "$FILE_CONTEXTS_BIN" != "" ]; then
-    echo "Writing ${OUTPUT_SYSTEM_IMG}..."
-
-    (cd $ANDROID_BUILD_TOP
-     if [[ "$(whereis mkuserimg_mke2fs | wc -w)" < 2 ]]; then
-       make mkuserimg_mke2fs -j
-     fi
-     NON_AB=$(expr "$BUILD_PROP_PATH" == "/build.prop")
-     if [ $NON_AB -eq 1 ]; then
-       sudo /bin/bash -c "PATH=out/host/linux-x86/bin/:\$PATH mkuserimg_mke2fs -s ${MOUNT_POINT} $OUTPUT_SYSTEM_IMG ext4 system $IMG_SIZE -D ${MOUNT_POINT} -L system $FILE_CONTEXTS_BIN"
-     else
-       sudo /bin/bash -c "PATH=out/host/linux-x86/bin/:\$PATH mkuserimg_mke2fs -s ${MOUNT_POINT} $OUTPUT_SYSTEM_IMG ext4 / $IMG_SIZE -D ${MOUNT_POINT}/system -L / $FILE_CONTEXTS_BIN"
-     fi)
-
-    unmount
-  else
-    unmount
-
-    echo "Writing ${OUTPUT_SYSTEM_IMG}..."
-    ${BIN_PATH["img2simg"]} "$UNSPARSED_SYSTEM_IMG" "$OUTPUT_SYSTEM_IMG"
-  fi
-else
-  unmount
-fi
-
-echo "Done."
diff --git a/harnesses/host_controller/invocation_thread.py b/harnesses/host_controller/invocation_thread.py
deleted file mode 100644
index b8760f3..0000000
--- a/harnesses/host_controller/invocation_thread.py
+++ /dev/null
@@ -1,169 +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.
-#
-
-import logging
-import socket
-import threading
-
-import httplib2
-from googleapiclient import errors
-
-from host_controller.tfc import command_attempt
-from host_controller.tradefed import remote_operation
-
-
-class InvocationThread(threading.Thread):
-    """The thread that remotely executes a command task.
-
-    Attributes:
-        _remote_client: The RemoteClient which executes the command.
-        _tfc_client: The TfcClient to which the command events are sent.
-        _attempt: The CommandAttempt whose events are sent to TFC.
-        _command: A list of strings, the command and arguments.
-        device_serials: A list of strings, the serial numbers of the devices
-                        which need to be allocated to the task.
-        _allocated_serials: A list of strings, the serial numbers of the devices
-                            which are successfully allocated.
-        _tfc_heartbeat_interval: The interval of TestRunInProgress events in
-                                 seconds.
-    """
-
-    def __init__(self,
-                 remote_client,
-                 tfc_client,
-                 attempt,
-                 command,
-                 device_serials,
-                 tfc_heartbeat_interval=5 * 60):
-        """Initializes the attributes."""
-        super(InvocationThread, self).__init__()
-        self._remote_client = remote_client
-        self._tfc_client = tfc_client
-        self._attempt = attempt
-        self._command = command
-        self.device_serials = device_serials
-        self._allocated_serials = None
-        # The value in Java implementation is 5 minutes.
-        self._tfc_heartbeat_interval = tfc_heartbeat_interval
-
-    def _AllocateDevices(self):
-        """Allocates all of device_serial."""
-        for serial in self.device_serials:
-            self._remote_client.SendOperation(
-                    remote_operation.AllocateDevice(serial))
-            self._allocated_serials.append(serial)
-
-    def _StartInvocation(self):
-        """Starts executing command and sends the event to TFC."""
-        self._remote_client.SendOperation(
-                remote_operation.ExecuteCommand(self.device_serials[0],
-                                                *self._command))
-        event = self._attempt.CreateCommandEvent(
-                command_attempt.EventType.INVOCATION_STARTED)
-        self._tfc_client.SubmitCommandEvents([event])
-
-    def _WaitForCommandResult(self):
-        """Waits for command result and keeps sending heartbeat to TFC
-
-        Returns:
-            A JSON object returned from TradeFed remote manager.
-        """
-        while True:
-            result = self._remote_client.WaitForCommandResult(
-                    self.device_serials[0], self._tfc_heartbeat_interval)
-            if result:
-                return result
-            event = self._attempt.CreateCommandEvent(
-                    command_attempt.EventType.TEST_RUN_IN_PROGRESS)
-            self._tfc_client.SubmitCommandEvents([event])
-
-    def _CompleteInvocation(self, result):
-        """Sends InvocationCompleted event according to the result.
-
-        Args:
-            result: A JSON object returned from TradeFed remote manager.
-        """
-        if result["status"] == "INVOCATION_SUCCESS":
-            event = self._attempt.CreateInvocationCompletedEvent(
-                    str(result), 1, 0)
-        else:
-            event = self._attempt.CreateInvocationCompletedEvent(
-                    str(result), 1, 1, error=str(result))
-        self._tfc_client.SubmitCommandEvents([event])
-
-    def _FreeAllocatedDevices(self):
-        """Frees allocated devices and tolerates RemoteOperationException."""
-        for serial in self._allocated_serials:
-            try:
-                self._remote_client.SendOperation(
-                        remote_operation.FreeDevice(serial))
-            except remote_operation.RemoteOperationException as e:
-                logging.exception(e)
-            except socket.error as e:
-                logging.exception(e)
-                break
-        self._allocated_serials = []
-
-    def _SubmitErrorEvent(self, event_type, error_msg):
-        """Submits an error event and tolerates http exceptions.
-
-        Args:
-            event_type: A string, the type of the command event.
-            error_msg: A string, the error message.
-        """
-        try:
-            self._tfc_client.SubmitCommandEvents(
-                [self._attempt.CreateCommandEvent(event_type, error_msg)])
-        except (httplib2.HttpLib2Error, errors.HttpError) as e:
-            logging.exception(e)
-
-    # @Override
-    def run(self):
-        """Executes a command task with exception handling."""
-        self._allocated_serials = []
-        last_error = None
-        error_event = command_attempt.EventType.ALLOCATION_FAILED
-        try:
-            self._AllocateDevices()
-            error_event = command_attempt.EventType.EXECUTE_FAILED
-            self._StartInvocation()
-            result = self._WaitForCommandResult()
-            self._CompleteInvocation(result)
-            error_event = None
-        except errors.HttpError as e:
-            logging.exception(e)
-            last_error = e
-        except remote_operation.RemoteOperationException as e:
-            logging.exception(e)
-            last_error = e
-            # ConfigurationException on TradeFed remote manager.
-            if str(e).startswith("Config error: "):
-                error_event = command_attempt.EventType.CONFIGURATION_ERROR
-        except httplib2.HttpLib2Error as e:
-            logging.exception("Cannot communicate with TradeFed cluster: %s\n"
-                              "Skip submitting event %s.", e, error_event)
-            last_error = e
-            error_event = None
-        except socket.error as e:
-            logging.exception("Cannot communicate with TradeFed remote "
-                              "manager: %s\nSkip freeing devices %s.",
-                              e, self._allocated_serials)
-            last_error = e
-            self._allocated_serials = []
-        finally:
-            if error_event:
-                self._SubmitErrorEvent(error_event, str(last_error))
-            self._FreeAllocatedDevices()
diff --git a/harnesses/host_controller/invocation_thread_test.py b/harnesses/host_controller/invocation_thread_test.py
deleted file mode 100644
index 07847b9..0000000
--- a/harnesses/host_controller/invocation_thread_test.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import invocation_thread
-from host_controller.tfc import command_attempt
-from host_controller.tradefed import remote_operation
-
-
-class InvocationThreadTest(unittest.TestCase):
-    """A test for invocation_thread.InvocationThread.
-
-    Attributes:
-        _remote_client: A mock remote_client.RemoteClient.
-        _tfc_client: A mock tfc_client.TfcClient.
-        _inv_thread: The InvocationThread being tested.
-    """
-
-    def setUp(self):
-        """Creates the InvocationThread."""
-        self._remote_client = mock.Mock()
-        self._tfc_client = mock.Mock()
-        attempt = command_attempt.CommandAttempt(
-                task_id="321-0",
-                attempt_id="abcd-1234",
-                hostname="host0",
-                device_serial="ABCDEF")
-        command = ["vts", "-m", "SampleShellTest"]
-        serials = ["serial123", "serial456"]
-        self._inv_thread = invocation_thread.InvocationThread(
-                self._remote_client, self._tfc_client,
-                attempt, command, serials)
-
-    def _GetSubmittedEventTypes(self):
-        """Gets the types of the events submitted by the mock TfcClient.
-
-        Returns:
-            A list of strings, the event types.
-        """
-        event_types = []
-        for args, kwargs in self._tfc_client.SubmitCommandEvents.call_args_list:
-            event_types.extend(event["type"] for event in args[0])
-        return event_types
-
-    def _GetSentOperationTypes(self):
-        """Gets the types of the operations sent by the mock RemoteClient.
-
-        Returns:
-            A list of strings, the operation types.
-        """
-        operation_types = [args[0].type for args, kwargs in
-                           self._remote_client.SendOperation.call_args_list]
-        return operation_types
-
-    def testAllocationFailed(self):
-        """Tests AllocationFailed event."""
-        self._remote_client.SendOperation.side_effect = (
-                lambda op: _RaiseExceptionForOperation(op, "ALLOCATE_DEVICE"))
-        self._inv_thread.run()
-        self.assertEqual([command_attempt.EventType.ALLOCATION_FAILED],
-                         self._GetSubmittedEventTypes())
-        self.assertEqual(["ALLOCATE_DEVICE"],
-                         self._GetSentOperationTypes())
-
-    def testExecuteFailed(self):
-        """Tests ExecuteFailed event."""
-        self._remote_client.SendOperation.side_effect = (
-                lambda op: _RaiseExceptionForOperation(op, "EXEC_COMMAND"))
-        self._inv_thread.run()
-        self.assertEqual([command_attempt.EventType.EXECUTE_FAILED],
-                         self._GetSubmittedEventTypes())
-        self.assertEqual(["ALLOCATE_DEVICE",
-                          "ALLOCATE_DEVICE",
-                          "EXEC_COMMAND",
-                          "FREE_DEVICE",
-                          "FREE_DEVICE"],
-                         self._GetSentOperationTypes())
-
-    def testConfigurationError(self):
-        """Tests ConfigurationError event."""
-        self._remote_client.SendOperation.side_effect = (
-                lambda op: _RaiseExceptionForOperation(op, "EXEC_COMMAND",
-                                                       "Config error: test"))
-        self._inv_thread.run()
-        self.assertEqual([command_attempt.EventType.CONFIGURATION_ERROR],
-                         self._GetSubmittedEventTypes())
-        self.assertEqual(["ALLOCATE_DEVICE",
-                          "ALLOCATE_DEVICE",
-                          "EXEC_COMMAND",
-                          "FREE_DEVICE",
-                          "FREE_DEVICE"],
-                         self._GetSentOperationTypes())
-
-    def testInvocationCompleted(self):
-        """Tests InvocationCompleted event."""
-        self._remote_client.WaitForCommandResult.side_effect = (
-                None, {"status": "INVOCATION_SUCCESS"})
-        self._inv_thread.run()
-        self.assertEqual([command_attempt.EventType.INVOCATION_STARTED,
-                          command_attempt.EventType.TEST_RUN_IN_PROGRESS,
-                          command_attempt.EventType.INVOCATION_COMPLETED],
-                         self._GetSubmittedEventTypes())
-        # GET_LAST_COMMAND_RESULT isn't called in mock WaitForCommandResult.
-        self.assertEqual(["ALLOCATE_DEVICE",
-                          "ALLOCATE_DEVICE",
-                          "EXEC_COMMAND",
-                          "FREE_DEVICE",
-                          "FREE_DEVICE"],
-                         self._GetSentOperationTypes())
-
-
-def _RaiseExceptionForOperation(operation, op_type, error_msg="unit test"):
-    """Raises exception for specific operation type.
-
-    Args:
-        operation: A remote_operation.RemoteOperation object.
-        op_type: A string, the expected type.
-        error_msg: The message in the exception.
-
-    Raises:
-        RemoteOperationException if the operation's type matches op_type.
-    """
-    if operation.type == op_type:
-        raise remote_operation.RemoteOperationException(error_msg)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/main.py b/harnesses/host_controller/main.py
deleted file mode 100644
index 348134e..0000000
--- a/harnesses/host_controller/main.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import argparse
-import json
-import logging
-import socket
-import time
-import threading
-import sys
-
-from host_controller import console
-from host_controller import tfc_host_controller
-from host_controller.build import build_provider_pab
-from host_controller.tfc import tfc_client
-from host_controller.vti_interface import vti_endpoint_client
-from host_controller.tradefed import remote_client
-from vts.utils.python.os import env_utils
-
-_ANDROID_BUILD_TOP = "ANDROID_BUILD_TOP"
-_SECONDS_PER_UNIT = {
-    "m": 60,
-    "h": 60 * 60,
-    "d": 60 * 60 * 24
-}
-
-
-def _ParseInterval(interval_str):
-    """Parses string to time interval.
-
-    Args:
-        interval_str: string, a floating-point number followed by time unit.
-
-    Returns:
-        float, the interval in seconds.
-
-    Raises:
-        ValueError if the argument format is wrong.
-    """
-    if not interval_str:
-        raise ValueError("Argument is empty.")
-
-    unit = interval_str[-1]
-    if unit not in _SECONDS_PER_UNIT:
-        raise ValueError("Unknown unit: %s" % unit)
-
-    interval = float(interval_str[:-1])
-    if interval < 0:
-        raise ValueError("Invalid time interval: %s" % interval)
-
-    return interval * _SECONDS_PER_UNIT[unit]
-
-
-def _ScriptLoop(hc_console, script_path, loop_interval):
-    """Runs a console script repeatedly.
-
-    Args:
-        hc_console: the host controller console.
-        script_path: string, the path to the script.
-        loop_interval: float or integer, the interval in seconds.
-    """
-    next_start_time = time.time()
-    while hc_console.ProcessScript(script_path):
-        if loop_interval == 0:
-            continue
-        current_time = time.time()
-        skip_cnt = (current_time - next_start_time) // loop_interval
-        if skip_cnt >= 1:
-            logging.warning("Script execution time is longer than loop "
-                            "interval. Skip %d iteration(s).", skip_cnt)
-        next_start_time += (skip_cnt + 1) * loop_interval
-        if next_start_time - current_time >= 0:
-            time.sleep(next_start_time - current_time)
-        else:
-            logging.error("Unexpected timestamps: current=%f, next=%f",
-                          current_time, next_start_time)
-
-
-def main():
-    """Parses arguments and starts console."""
-    parser = argparse.ArgumentParser()
-    parser.add_argument("--config-file",
-                        default=None,
-                        type=argparse.FileType('r'),
-                        help="The configuration file in JSON format")
-    parser.add_argument("--poll", action="store_true",
-                        help="Disable console and start host controller "
-                             "threads polling TFC.")
-    parser.add_argument("--use-tfc", action="store_true",
-                        help="Enable TFC (TradeFed Cluster).")
-    parser.add_argument("--vti",
-                        default=None,
-                        help="The base address of VTI endpoint APIs")
-    parser.add_argument("--script",
-                        default=None,
-                        help="The path to a script file in .py format")
-    parser.add_argument("--serial",
-                        default=None,
-                        help="The default serial numbers for flashing and "
-                             "testing in the console. Multiple serial numbers "
-                             "are separated by comma.")
-    parser.add_argument("--loop",
-                        default=None,
-                        metavar="INTERVAL",
-                        type=_ParseInterval,
-                        help="The interval of repeating the script. "
-                             "The format is a float followed by unit which is "
-                             "one of 'm' (minute), 'h' (hour), and 'd' (day). "
-                             "If this option is unspecified, the script will "
-                             "be processed once.")
-    parser.add_argument("--console", action="store_true",
-                        help="Whether to start a console after processing "
-                             "a script.")
-    parser.add_argument("--password",
-                        default=None,
-                        help="Password string to pass to the prompt "
-                             "when running certain command as root previlege.")
-    parser.add_argument("--flash",
-                        default=None,
-                        help="GCS URL to an img package. Fetches and flashes "
-                             "the device(s) given as the '--serial' flag.")
-    args = parser.parse_args()
-    if args.config_file:
-        config_json = json.load(args.config_file)
-    else:
-        config_json = {}
-        config_json["log_level"] = "DEBUG"
-        config_json["hosts"] = []
-        host_config = {}
-        host_config["cluster_ids"] = ["local-cluster-1",
-                                      "local-cluster-2"]
-        host_config["lease_interval_sec"] = 30
-        config_json["hosts"].append(host_config)
-
-    env_vars = env_utils.SaveAndClearEnvVars([_ANDROID_BUILD_TOP])
-
-    root_logger = logging.getLogger()
-    root_logger.setLevel(getattr(logging, config_json["log_level"]))
-
-    if args.vti:
-        vti_endpoint = vti_endpoint_client.VtiEndpointClient(args.vti)
-    else:
-        vti_endpoint = None
-
-    tfc = None
-    if args.use_tfc:
-        if args.config_file:
-            tfc = tfc_client.CreateTfcClient(
-                    config_json["tfc_api_root"],
-                    config_json["service_key_json_path"],
-                    api_name=config_json["tfc_api_name"],
-                    api_version=config_json["tfc_api_version"],
-                    scopes=config_json["tfc_scopes"])
-        else:
-            logging.warning("WARN: If --use_tfc is set, --config_file argument "
-                            "value must be provided. Starting without TFC.")
-
-    pab = build_provider_pab.BuildProviderPAB()
-
-    hosts = []
-    for host_config in config_json["hosts"]:
-        cluster_ids = host_config["cluster_ids"]
-        # If host name is not specified, use local host.
-        hostname = host_config.get("hostname", socket.gethostname())
-        port = host_config.get("port", remote_client.DEFAULT_PORT)
-        cluster_ids = host_config["cluster_ids"]
-        remote = remote_client.RemoteClient(hostname, port)
-        host = tfc_host_controller.HostController(remote, tfc, hostname,
-                                                  cluster_ids)
-        hosts.append(host)
-        if args.poll:
-            lease_interval_sec = host_config["lease_interval_sec"]
-            host_thread = threading.Thread(target=host.Run,
-                                           args=(lease_interval_sec,))
-            host_thread.daemon = True
-            host_thread.start()
-
-    if args.poll:
-        while True:
-            sys.stdin.readline()
-    else:
-        main_console = console.Console(vti_endpoint, tfc, pab, hosts,
-                                       vti_address=args.vti,
-                                       password=args.password)
-        if args.vti:
-            main_console.StartJobThreadAndProcessPool()
-        else:
-            logging.warning("vti address is not set. example : "
-                            "$ run --vti=<url>")
-
-        try:
-            if args.serial:
-                main_console.SetSerials(args.serial.split(","))
-            if args.script:
-                if args.loop is None:
-                    main_console.ProcessScript(args.script)
-                else:
-                    _ScriptLoop(main_console, args.script, args.loop)
-
-                if args.console:
-                    main_console.cmdloop()
-            elif args.flash:
-                main_console.FlashImgPackage(args.flash)
-            else:  # if not script, the default is console mode.
-                main_console.cmdloop()
-        finally:
-            main_console.TearDown()
-
-    env_utils.RestoreEnvVars(env_vars)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/harnesses/host_controller/script/pip_requirements.txt b/harnesses/host_controller/script/pip_requirements.txt
deleted file mode 100644
index 92a83cb..0000000
--- a/harnesses/host_controller/script/pip_requirements.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# Required pip packages for host controller.
-enum
-future
-futures
-google-api-python-client
-google-cloud-pubsub
-gspread
-httplib2
-multiprocessing
-protobuf
-requests
-selenium
-setuptools
diff --git a/harnesses/host_controller/script/release.sh b/harnesses/host_controller/script/release.sh
deleted file mode 100755
index 969cb6f..0000000
--- a/harnesses/host_controller/script/release.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-# VTS lab release script
-# Usage: <this script> prod|test
-# Caution: only used by a VTS lab release engineer
-rm out/host/linux-x86/vtslab/android-vtslab/testcases/tmp/ -rf
-. build/envsetup.sh
-lunch aosp_arm64
-make WifiUtil -j
-mkdir -p out/host/linux-x86/vtslab/android-vtslab/testcases/DATA/app
-cp out/target/product/generic_arm64/testcases/WifiUtil/ out/host/linux-x86/vtslab/android-vtslab/testcases/DATA/app/ -rf
-make vtslab -j
-
-if [ $# -eq 1 ]; then
-  ls -al out/host/linux-x86/vtslab/android-vtslab.zip
-  echo "To upload, please run:"
-  echo gsutil cp out/host/linux-x86/vtslab/android-vtslab.zip gs://vtslab-release/$1/android-vtslab-$(date +%F).zip
-fi
diff --git a/harnesses/host_controller/tfc/__init__.py b/harnesses/host_controller/tfc/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/tfc/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/tfc/api_message.py b/harnesses/host_controller/tfc/api_message.py
deleted file mode 100644
index d1b618e..0000000
--- a/harnesses/host_controller/tfc/api_message.py
+++ /dev/null
@@ -1,46 +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.
-#
-
-
-class ApiMessage(object):
-    """The class for the messages defined by TFC API."""
-
-    def __init__(self, all_keys, **kwargs):
-        """Initializes the attributes.
-
-        Args:
-            all_keys: A collection of attribute names.
-            **kwargs: The names and values of the attributes. The names must be
-                      in all_keys.
-
-        Raises:
-            KeyError if any key in kwargs is not in all_keys.
-        """
-        for key, value in kwargs.iteritems():
-            if key not in all_keys:
-                raise KeyError(key)
-            setattr(self, key, value)
-
-    def ToJson(self, keys):
-        """Creates a JSON object containing the specified keys.
-
-        Args:
-            keys: The attributes to be included in the object.
-
-        Returns:
-            A JSON object.
-        """
-        return dict((x, getattr(self, x)) for x in keys if hasattr(self, x))
diff --git a/harnesses/host_controller/tfc/command_attempt.py b/harnesses/host_controller/tfc/command_attempt.py
deleted file mode 100644
index 930ec71..0000000
--- a/harnesses/host_controller/tfc/command_attempt.py
+++ /dev/null
@@ -1,137 +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.
-#
-
-import time
-
-from host_controller.tfc import api_message
-
-
-class EventType(object):
-    """The types of command events."""
-    ALLOCATION_FAILED = "AllocationFailed"
-    CONFIGURATION_ERROR = "ConfigurationError"
-    EXECUTE_FAILED = "ExecuteFailed"
-    FETCH_FAILED = "FetchFailed"
-    INVOCATION_COMPLETED = "InvocationCompleted"
-    INVOCATION_STARTED = "InvocationStarted"
-    TEST_RUN_IN_PROGRESS = "TestRunInProgress"
-
-
-class CommandAttempt(api_message.ApiMessage):
-    """The command attempt defined by TFC API.
-
-    Attributes:
-        _COMMAND_EVENT: The parameters of command_events.submit.
-        _COMMAND_EVENT_DATA: The fields in "data" parameter of command_events.
-        _LIST_ATTEMPT: The fields returned by commandAttempts.list.
-    """
-    _COMMAND_EVENT = {
-            "attempt_id",
-            "data",
-            "device_serial",
-            "hostname",
-            "task_id",
-            "time",
-            "type"}
-    _COMMAND_EVENT_DATA = {
-            "error",
-            "failed_test_count",
-            "summary",
-            "test_run_name",
-            "total_test_count"}
-    _LIST_ATTEMPT = {
-            "attempt_id",
-            "command_id",
-            "create_time",
-            "end_time",
-            "error",
-            "device_serial",
-            "failed_test_count",
-            "hostname",
-            "request_id",
-            "start_time",
-            "state",
-            "status",
-            "summary",
-            "task_id",
-            "total_test_count",
-            "update_time"}
-
-    def __init__(self, task_id, attempt_id, hostname, device_serial, **kwargs):
-        """Initializes the attributes.
-
-        Args:
-            task_id: A string, the task id assigned by the server.
-            attempt_id: A string or UUID, the attempt id generated by the host.
-            hostname: The name of the TradeFed host.
-            device_serial: The serial number of the device.
-            **kwargs: The optional attributes.
-        """
-        super(CommandAttempt, self).__init__(self._LIST_ATTEMPT,
-                                             task_id=task_id,
-                                             attempt_id=str(attempt_id),
-                                             hostname=hostname,
-                                             device_serial=device_serial,
-                                             **kwargs)
-
-    def CreateCommandEvent(self, event_type, error=None, event_time=None):
-        """Creates an event defined by command_events.submit.
-
-        Args:
-            event_type: A string in EventType.
-            error: A string, the error message for *Failed, *Error, and
-                   *Completed events.
-            event_time: A float, Unix timestamp of the event in seconds.
-
-        Returns:
-            A JSON object.
-        """
-        obj = self.ToJson(self._COMMAND_EVENT)
-        obj["type"] = event_type
-        obj["time"] = int(event_time if event_time is not None else time.time())
-        data_obj = self.ToJson(self._COMMAND_EVENT_DATA)
-        if error is not None:
-            data_obj["error"] = error
-        if data_obj:
-            obj["data"] = data_obj
-        return obj
-
-    def CreateInvocationCompletedEvent(self,
-                                       summary,
-                                       total_test_count,
-                                       failed_test_count,
-                                       error=None,
-                                       event_time=None):
-        """Creates an InvocationCompleted event.
-
-        Args:
-            summary: A string, the result of the command.
-            total_test_count: Number of test cases.
-            failed_test_count: Number of failed test cases.
-            error: A string, the error message.
-            event_time: A float, Unix timestamp of the event in seconds.
-
-        Returns:
-            A JSON object.
-        """
-        obj = self.CreateCommandEvent(EventType.INVOCATION_COMPLETED,
-                                      error, event_time)
-        if "data" not in obj:
-            obj["data"] = dict()
-        obj["data"].update({"summary": summary,
-                            "total_test_count": total_test_count,
-                            "failed_test_count": failed_test_count})
-        return obj
diff --git a/harnesses/host_controller/tfc/command_task.py b/harnesses/host_controller/tfc/command_task.py
deleted file mode 100644
index d4aa53e..0000000
--- a/harnesses/host_controller/tfc/command_task.py
+++ /dev/null
@@ -1,39 +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.
-#
-
-from host_controller.tfc import api_message
-
-
-class CommandTask(api_message.ApiMessage):
-    """The task of executing a command defined by TFC API.
-
-    Attributes:
-        _LEASE_HOST_TASK: The fields returned by commandAttempts.list.
-    """
-    _LEASE_HOST_TASK = {
-            "request_id",
-            "command_id",
-            "task_id",
-            "command_line",
-            "request_type",
-            "device_serials"}
-
-    def __init__(self, task_id, command_line, device_serials, **kwargs):
-        super(CommandTask, self).__init__(self._LEASE_HOST_TASK,
-                                          task_id=task_id,
-                                          command_line=command_line,
-                                          device_serials=device_serials,
-                                          **kwargs)
diff --git a/harnesses/host_controller/tfc/device_info.py b/harnesses/host_controller/tfc/device_info.py
deleted file mode 100644
index 6a1b35d..0000000
--- a/harnesses/host_controller/tfc/device_info.py
+++ /dev/null
@@ -1,105 +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.
-#
-
-from host_controller.tfc import api_message
-from vts.utils.python.controllers import android_device
-
-
-class DeviceInfo(api_message.ApiMessage):
-    """The device information defined by TFC API.
-
-    Attributes:
-        _DEVICE_SNAPSHOT: The parameters of host_events.
-        _LEASE_HOST_TASKS: The parameters of leasehosttasks.
-        _OTHER: The data retrieved from TradeFed host but not used by the API.
-        _ALL_KEYS: Union of above.
-    """
-    _DEVICE_SNAPSHOT = {
-            "battery_level",
-            "build_id",
-            "device_serial",
-            "group_name",
-            "mac_address",
-            "product",
-            "product_variant",
-            "run_target",
-            "sim_operator",
-            "sim_state",
-            "sdk_version",
-            "state"}
-    _LEASE_HOST_TASKS = {
-            "device_serial",
-            "group_name",
-            "run_target",
-            "state"}
-    _OTHER = {"stub"}
-    _ALL_KEYS = (_DEVICE_SNAPSHOT | _LEASE_HOST_TASKS | _OTHER)
-
-    def __init__(self, device_serial, **kwargs):
-        """Initializes the attributes.
-
-        Args:
-            device_serial: The serial number of the device.
-            **kwargs: The optional attributes.
-        """
-        super(DeviceInfo, self).__init__(self._ALL_KEYS,
-                                         device_serial=device_serial, **kwargs)
-
-    def IsAvailable(self):
-        """Returns whether the device is available for running commands.
-
-        Returns:
-            A boolean.
-        """
-        return getattr(self, "state", None) == "Available"
-
-    def IsStub(self):
-        """Returns whether the device is a stub.
-
-        Returns:
-            A boolean.
-        """
-        return getattr(self, "stub", False)
-
-    def ToDeviceSnapshotJson(self):
-        """Converts to the parameter of host_events.
-
-        Returns:
-            A JSON object.
-        """
-        return self.ToJson(self._DEVICE_SNAPSHOT)
-
-    def ToLeaseHostTasksJson(self):
-        """Converts to the parameter of leasehosttasks.
-
-        Returns:
-            A JSON object.
-        """
-        return self.ToJson(self._LEASE_HOST_TASKS)
-
-    def Extend(self, properties):
-        """Adds properties to a DeviceInfo object, using AndroidDevice
-
-        Args:
-            properties: list of strings, list of properties to update
-        """
-        serial = getattr(self, "device_serial", None)
-        ad = android_device.AndroidDevice(serial)
-        for prop in properties:
-            val = getattr(ad, prop, None)
-            if val is None:
-                continue
-            setattr(self, prop, val)
diff --git a/harnesses/host_controller/tfc/request.py b/harnesses/host_controller/tfc/request.py
deleted file mode 100644
index a086bf2..0000000
--- a/harnesses/host_controller/tfc/request.py
+++ /dev/null
@@ -1,74 +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.
-#
-
-from host_controller.tfc import api_message
-
-
-class Request(api_message.ApiMessage):
-    """The requests defined by TFC API.
-
-    Attributes:
-        _BODY: The requests.new parameters that are put into http message body.
-        _PARAMETERS: The requests.new parameters put into http parameters.
-        _ALL_KEYS: Union of above.
-    """
-    _BODY = {
-            "command_line",
-            "user"}
-    _PARAMETERS = {
-            "branch",
-            "build_flavor",
-            "build_id",
-            "build_os",
-            "cluster",
-            "no_build_args",
-            "run_target",
-            "shard_count"
-            "run_count"}
-    _ALL_KEYS = (_BODY | _PARAMETERS)
-
-    def __init__(self, cluster, command_line, run_target, user, **kwargs):
-        """Initializes the attributes.
-
-        Args:
-            cluster: The ID of the cluster to send this request to.
-            command_line: The command to execute on a host.
-            run_target: The target device to run the command.
-            user: The name of the user sending this request.
-            **kwargs: The optional attributes.
-        """
-        super(Request, self).__init__(self._ALL_KEYS,
-                                      cluster=cluster,
-                                      command_line=command_line,
-                                      run_target=run_target,
-                                      user=user,
-                                      **kwargs)
-
-    def GetBody(self):
-        """Returns the http message body.
-
-        Returns:
-            A JSON object.
-        """
-        return self.ToJson(self._BODY)
-
-    def GetParameters(self):
-        """Returns the http parameters.
-
-        Returns:
-            A dict of strings.
-        """
-        return self.ToJson(self._PARAMETERS)
diff --git a/harnesses/host_controller/tfc/tfc_client.py b/harnesses/host_controller/tfc/tfc_client.py
deleted file mode 100644
index 8380573..0000000
--- a/harnesses/host_controller/tfc/tfc_client.py
+++ /dev/null
@@ -1,176 +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.
-#
-
-import httplib2
-import logging
-import threading
-import time
-
-from googleapiclient import discovery
-from googleapiclient import http
-from oauth2client.service_account import ServiceAccountCredentials
-
-from host_controller.tfc import command_task
-
-API_NAME = "tradefed_cluster"
-API_VERSION = "v1"
-SCOPES = ['https://www.googleapis.com/auth/userinfo.email']
-
-
-class TfcClient(object):
-    """The class for accessing TFC API.
-
-    Attributes:
-        _service: The TFC service.
-    """
-
-    def __init__(self, service):
-        self._service = service
-
-    def LeaseHostTasks(self, cluster_id, next_cluster_ids, hostname, device_infos):
-        """Calls leasehosttasks.
-
-        Args:
-            cluster_id: A string, the primary cluster to lease tasks from.
-            next_cluster_ids: A list of Strings, the secondary clusters to lease
-                              tasks from.
-            hostname: A string, the name of the TradeFed host.
-            device_infos: A list of DeviceInfo, the information about the
-                          devices connected to the host.
-
-        Returns:
-            A list of command_task.CommandTask, the leased tasks.
-        """
-        lease = {"hostname": hostname,
-                 "cluster": cluster_id,
-                 "next_cluster_ids": next_cluster_ids,
-                 "device_infos": [x.ToLeaseHostTasksJson()
-                                  for x in device_infos]}
-        logging.info("tasks.leasehosttasks body=%s", lease)
-        tasks = self._service.tasks().leasehosttasks(body=lease).execute()
-        logging.info("tasks.leasehosttasks response=%s", tasks)
-        if "tasks" not in tasks:
-            return []
-        return [command_task.CommandTask(**task) for task in tasks["tasks"]]
-
-    def TestResourceList(self, request_id):
-        """Calls testResource.list.
-
-        Args:
-            request_id: int, id of request to grab resources for
-
-        Returns:
-            A list of TestResources
-        """
-        logging.info("request.testResource.list request_id=%s", request_id)
-        test_resources = self._service.requests().testResource().list(request_id=request_id).execute()
-        logging.info("request.testResource.list response=%s", test_resources)
-        if 'test_resources' not in test_resources:
-            return {}
-        return test_resources['test_resources']
-
-    @staticmethod
-    def CreateDeviceSnapshot(cluster_id, hostname, dev_infos):
-        """Creates a DeviceSnapshot which can be uploaded as host event.
-
-        Args:
-            cluster_id: A string, the cluster to upload snapshot to.
-            hostname: A string, the name of the TradeFed host.
-            dev_infos: A list of DeviceInfo.
-
-        Returns:
-            A JSON object.
-        """
-        obj = {"time": int(time.time()),
-               "data": {},
-               "cluster": cluster_id,
-               "hostname": hostname,
-               "tf_version": "(unknown)",
-               "type": "DeviceSnapshot",
-               "device_infos": [x.ToDeviceSnapshotJson() for x in dev_infos]}
-        return obj
-
-    def SubmitHostEvents(self, host_events):
-        """Calls host_events.submit.
-
-        Args:
-            host_events: A list of JSON objects. Currently DeviceSnapshot is
-                         the only type of host events.
-        """
-        json_obj = {"host_events": host_events}
-        logging.info("host_events.submit body=%s", json_obj)
-        self._service.host_events().submit(body=json_obj).execute()
-
-    def SubmitCommandEvents(self, command_events):
-        """Calls command_events.submit.
-
-        Args:
-            command_events: A list of JSON objects converted from CommandAttempt.
-        """
-        json_obj = {"command_events": command_events}
-        logging.info("command_events.submit body=%s", json_obj)
-        self._service.command_events().submit(body=json_obj).execute()
-
-    def NewRequest(self, request):
-        """Calls requests.new.
-
-        Args:
-            request: An instance of Request.
-
-        Returns:
-            A JSON object, the new request queued in the cluster.
-
-            Sample
-            {'state': 'UNKNOWN',
-             'command_line': 'vts-codelab --run-target sailfish',
-             'id': '2',
-             'user': 'testuser'}
-        """
-        body = request.GetBody()
-        params = request.GetParameters()
-        logging.info("requests.new parameters=%s body=%s", params, body)
-        return self._service.requests().new(body=body, **params).execute()
-
-
-def CreateTfcClient(api_root, oauth2_service_json,
-                    api_name=API_NAME, api_version=API_VERSION, scopes=SCOPES):
-    """Builds an object of TFC service from a given URL.
-
-    Args:
-        api_root: The URL to the service.
-        oauth2_service_json: The path to service account key file.
-
-    Returns:
-        A TfcClient object.
-    """
-    discovery_url = "%s/discovery/v1/apis/%s/%s/rest" % (
-            api_root, api_name, api_version)
-    logging.info("Build service from: %s", discovery_url)
-    credentials = ServiceAccountCredentials.from_json_keyfile_name(
-            oauth2_service_json, scopes=scopes)
-    # httplib2.Http is not thread-safe. Use thread local object.
-    thread_local = threading.local()
-    thread_local.http = credentials.authorize(httplib2.Http())
-    def BuildHttpRequest(unused_http, *args, **kwargs):
-        if not hasattr(thread_local, "http"):
-            thread_local.http = credentials.authorize(httplib2.Http())
-        return http.HttpRequest(thread_local.http, *args, **kwargs)
-
-    service = discovery.build(
-            api_name, api_version, http=thread_local.http,
-            discoveryServiceUrl=discovery_url,
-            requestBuilder=BuildHttpRequest)
-    return TfcClient(service)
diff --git a/harnesses/host_controller/tfc/tfc_client_test.py b/harnesses/host_controller/tfc/tfc_client_test.py
deleted file mode 100644
index 10db850..0000000
--- a/harnesses/host_controller/tfc/tfc_client_test.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller.tfc import tfc_client
-from host_controller.tfc import command_attempt
-from host_controller.tfc import device_info
-from host_controller.tfc import request
-
-
-class TfcClientTest(unittest.TestCase):
-    """A test for tfc_client.TfcClient.
-
-    Attributes:
-        _client: The tfc_client.TfcClient being tested.
-        _service: The mock service that _client connects to.
-    """
-    _DEVICE_INFOS = [device_info.DeviceInfo(
-            device_serial="ABCDEF", group_name="group0",
-            run_target="sailfish", state="Available")]
-
-    def setUp(self):
-        """Creates a TFC client connecting to a mock service."""
-        self._service = mock.Mock()
-        self._client = tfc_client.TfcClient(self._service)
-
-    def testNewRequest(self):
-        """Tests requests.new."""
-        req = request.Request(cluster="cluster0",
-                              command_line="vts-codelab",
-                              run_target="sailfish",
-                              user="user0")
-        self._client.NewRequest(req)
-        self._service.assert_has_calls([
-                mock.call.requests().new().execute()])
-
-    def testLeaseHostTasks(self):
-        """Tests tasks.leasehosttasks."""
-        tasks = {"tasks": [{"request_id": "2",
-                            "command_line": "vts-codelab --serial ABCDEF",
-                            "task_id": "1-0",
-                            "device_serials": ["ABCDEF"],
-                            "command_id": "1"}]}
-        self._service.tasks().leasehosttasks().execute.return_value = tasks
-        self._client.LeaseHostTasks("cluster0", ["cluster1", "cluster2"],
-                                    "host0", self._DEVICE_INFOS)
-        self._service.assert_has_calls([
-                mock.call.tasks().leasehosttasks().execute()])
-
-    def testHostEvents(self):
-        """Tests host_events.submit."""
-        device_snapshots = [
-                self._client.CreateDeviceSnapshot("vts-staging", "host0",
-                                                  self._DEVICE_INFOS),
-                self._client.CreateDeviceSnapshot("vts-presubmit", "host0",
-                                                  self._DEVICE_INFOS)]
-        self._client.SubmitHostEvents(device_snapshots)
-        self._service.assert_has_calls([
-                mock.call.host_events().submit().execute()])
-
-    def testCommandEvents(self):
-        """Tests command_events.submit."""
-        cmd = command_attempt.CommandAttempt(
-                task_id="321-0",
-                attempt_id="abcd-1234",
-                hostname="host0",
-                device_serial="ABCDEF")
-        expected_event = {
-                "task_id": "321-0",
-                "attempt_id": "abcd-1234",
-                "hostname": "host0",
-                "device_serial": "ABCDEF",
-                "time": 1}
-
-        normal_event = cmd.CreateCommandEvent(
-                command_attempt.EventType.INVOCATION_STARTED,
-                event_time=1)
-        expected_event["type"] = command_attempt.EventType.INVOCATION_STARTED
-        self.assertDictEqual(expected_event, normal_event)
-
-        error_event = cmd.CreateCommandEvent(
-                command_attempt.EventType.EXECUTE_FAILED,
-                error="unit test", event_time=1.1)
-        expected_event["type"] = command_attempt.EventType.EXECUTE_FAILED
-        expected_event["data"] = {"error":"unit test"}
-        self.assertDictEqual(expected_event, error_event)
-
-        complete_event = cmd.CreateInvocationCompletedEvent(
-                summary="complete", total_test_count=2, failed_test_count=1,
-                error="unit test")
-        expected_event["type"] = command_attempt.EventType.INVOCATION_COMPLETED
-        expected_event["data"] = {"summary": "complete", "error": "unit test",
-                                  "total_test_count": 2, "failed_test_count": 1}
-        del expected_event["time"]
-        self.assertDictContainsSubset(expected_event, complete_event)
-        self.assertIn("time", complete_event)
-
-        self._client.SubmitCommandEvents([
-                normal_event, error_event, complete_event])
-        self._service.assert_has_calls([
-                mock.call.command_events().submit().execute()])
-
-    def testWrongParameter(self):
-        """Tests raising exception for wrong parameter name."""
-        self.assertRaisesRegexp(KeyError, "sdk", device_info.DeviceInfo,
-                                device_serial="123", sdk="25")
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/tfc_host_controller.py b/harnesses/host_controller/tfc_host_controller.py
deleted file mode 100644
index 6e8fb23..0000000
--- a/harnesses/host_controller/tfc_host_controller.py
+++ /dev/null
@@ -1,140 +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.
-#
-
-import logging
-import socket
-import time
-import uuid
-
-import httplib2
-from googleapiclient import errors
-
-from host_controller import invocation_thread
-from host_controller.tradefed import remote_operation
-from host_controller.tfc import command_attempt
-
-
-class HostController(object):
-    """The class that relays commands between a TradeFed host and clusters.
-
-    Attributes:
-        _remote_client: The RemoteClient which runs commands.
-        _tfc_client: The TfcClient from which the command tasks are leased.
-        _hostname: A string, the name of the TradeFed host.
-        _cluster_ids: A list of strings, the cluster IDs for leasing tasks.
-        _invocation_threads: The list of running InvocationThread.
-    """
-
-    def __init__(self, remote_client, tfc_client, hostname, cluster_ids):
-        """Initializes the attributes."""
-        self._remote_client = remote_client
-        self._tfc_client = tfc_client
-        self._hostname = hostname
-        self._cluster_ids = cluster_ids
-        self._invocation_threads = []
-
-    @property
-    def hostname(self):
-        """Returns the name of the host."""
-        return self._hostname
-
-    def _JoinInvocationThreads(self):
-        """Removes terminated threads from _invocation_threads."""
-        alive_threads = []
-        for inv_thread in self._invocation_threads:
-            inv_thread.join(0)
-            if inv_thread.is_alive():
-                alive_threads.append(inv_thread)
-        self._invocation_threads = alive_threads
-
-    def _CreateInvocationThread(self, task):
-        """Creates an invocation thread from a command task.
-
-        Args:
-            task: The CommandTask object.
-
-        Returns:
-            An InvocationThread.
-        """
-        attempt_id = uuid.uuid4()
-        attempt = command_attempt.CommandAttempt(
-                task.task_id, attempt_id,
-                self._hostname, task.device_serials[0])
-        inv_thread = invocation_thread.InvocationThread(
-                self._remote_client, self._tfc_client, attempt,
-                task.command_line.split(), task.device_serials)
-        return inv_thread
-
-    def ListDevices(self):
-        """Lists present devices on the host.
-
-        Returns:
-            A list of DeviceInfo.
-        """
-        devices = self._remote_client.ListDevices()
-        return [dev for dev in devices if not dev.IsStub()]
-
-    def ListAvailableDevices(self):
-        """Lists available devices for command tasks.
-
-        Returns:
-            A list of DeviceInfo.
-        """
-        self._JoinInvocationThreads()
-        allocated_serials = set()
-        for inv_thread in self._invocation_threads:
-            allocated_serials.update(inv_thread.device_serials)
-
-        present_devices = self.ListDevices()
-        return [dev for dev in present_devices if
-                dev.IsAvailable() and
-                dev.device_serial not in allocated_serials]
-
-    def LeaseCommandTasks(self):
-        """Leases command tasks and creates threads to execute them.
-
-        Returns:
-            A list of CommandTask. The leased command tasks.
-        """
-        available_devices = self.ListAvailableDevices()
-        if not available_devices:
-            return []
-
-        tasks = self._tfc_client.LeaseHostTasks(
-                self._cluster_ids[0], self._cluster_ids[1:],
-                self._hostname, available_devices)
-        for task in tasks:
-            inv_thread = self._CreateInvocationThread(task)
-            inv_thread.daemon = True
-            inv_thread.start()
-            self._invocation_threads.append(inv_thread)
-        return tasks
-
-    def Run(self, poll_interval):
-        """Starts polling TFC for tasks.
-
-        Args:
-            poll_interval: The poll interval in seconds.
-        """
-        while True:
-            try:
-                self.LeaseCommandTasks()
-            except (socket.error,
-                    remote_operation.RemoteOperationException,
-                    httplib2.HttpLib2Error,
-                    errors.HttpError) as e:
-                logging.exception(e)
-            time.sleep(poll_interval)
diff --git a/harnesses/host_controller/tfc_host_controller_test.py b/harnesses/host_controller/tfc_host_controller_test.py
deleted file mode 100644
index 0d4b8b5..0000000
--- a/harnesses/host_controller/tfc_host_controller_test.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import threading
-import unittest
-import time
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import tfc_host_controller
-from host_controller.tfc import command_task
-from host_controller.tfc import device_info
-
-
-class HostControllerTest(unittest.TestCase):
-    """A test for tfc_host_controller.HostController.
-
-    Args:
-        _remote_client: A mock remote_client.RemoteClient.
-        _tfc_client: A mock tfc_client.TfcClient.
-        _host_controller: The HostController being tested.
-    """
-    _AVAILABLE_DEVICE = device_info.DeviceInfo(
-            device_serial="ABC001",
-            run_target="sailfish",
-            state="Available")
-    _ALLOCATED_DEVICE = device_info.DeviceInfo(
-            device_serial="ABC002",
-            run_target="sailfish",
-            state="Allocated")
-    _STUB_DEVICE = device_info.DeviceInfo(
-            device_serial="emulator-5554",
-            run_target="unknown",
-            state="Available",
-            stub=True)
-    _DEVICES = [_AVAILABLE_DEVICE, _ALLOCATED_DEVICE, _STUB_DEVICE]
-    _TASKS = [command_task.CommandTask(task_id="1-0",
-                                       command_line="vts -m SampleShellTest",
-                                       device_serials=["ABC001"])]
-
-    def setUp(self):
-        """Creates the HostController."""
-        self._remote_client = mock.Mock()
-        self._tfc_client = mock.Mock()
-        self._host_controller = tfc_host_controller.HostController(
-                self._remote_client, self._tfc_client, "host1", ["cluster1"])
-
-    @mock.patch("host_controller.invocation_thread."
-                "InvocationThread.run")
-    def testDeviceStateDuringInvocation(self, mock_run):
-        """Tests LeaseHostTasks and ListAvailableDevices."""
-        self._remote_client.ListDevices.return_value = self._DEVICES
-        self._tfc_client.LeaseHostTasks.return_value = self._TASKS
-        run_event = threading.Event()
-        mock_run.side_effect = lambda: run_event.wait()
-
-        self._host_controller.LeaseCommandTasks()
-        devices = self._host_controller.ListAvailableDevices()
-        self.assertEqual([], devices)
-        run_event.set()
-        # Wait for thread termination
-        time.sleep(0.2)
-        devices = self._host_controller.ListAvailableDevices()
-        self.assertEqual([self._AVAILABLE_DEVICE], devices)
-
-    def testListDevices(self):
-        """Tests ListDevices."""
-        self._remote_client.ListDevices.return_value = self._DEVICES
-        devices = self._host_controller.ListDevices()
-        self.assertEqual([self._AVAILABLE_DEVICE, self._ALLOCATED_DEVICE],
-                         devices)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/tradefed/__init__.py b/harnesses/host_controller/tradefed/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/tradefed/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/tradefed/remote_client.py b/harnesses/host_controller/tradefed/remote_client.py
deleted file mode 100644
index e369ba3..0000000
--- a/harnesses/host_controller/tradefed/remote_client.py
+++ /dev/null
@@ -1,135 +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.
-#
-
-import logging
-import socket
-import time
-
-from host_controller.tradefed import remote_operation
-
-LOCALHOST = "localhost"
-DEFAULT_PORT = 30103
-
-
-class RemoteClient(object):
-    """The class for sending remote operations to TradeFed."""
-
-    def __init__(self, host=LOCALHOST, port=DEFAULT_PORT, timeout=None):
-        """Initializes the client of TradeFed remote manager.
-
-        Args:
-            _host: The host name of the remote manager.
-            _port: The port of the remote manager.
-            _timeout: The connect and receive timeout in seconds
-        """
-        self._host = host
-        self._port = port
-        self._timeout = timeout if timeout else socket.getdefaulttimeout()
-
-    def SendOperations(self, *operations):
-        """Sends a list of operations and waits for each response.
-
-        Args:
-            *operations: A list of remote_operation.RemoteOperation objects.
-
-        Returns:
-            A list of JSON objects.
-
-        Raises:
-            socket.error if fails to communicate with remote manager.
-            remote_operation.RemoteOperationException if any operation fails or
-            has no response.
-        """
-        op_socket = socket.create_connection((self._host, self._port),
-                                             self._timeout)
-        logging.info("Connect to %s:%d", self._host, self._port)
-        try:
-            if self._timeout is not None:
-                op_socket.settimeout(self._timeout)
-            ops_str = "\n".join(str(op) for op in operations)
-            logging.info("Send: %s", ops_str)
-            op_socket.send(ops_str)
-            op_socket.shutdown(socket.SHUT_WR)
-            resp_str = ""
-            while True:
-                buf = op_socket.recv(4096)
-                if not buf:
-                    break
-                resp_str += buf
-        finally:
-            op_socket.close()
-        logging.info("Receive: %s", resp_str)
-        resp_lines = [x for x in resp_str.split("\n") if x]
-        if len(resp_lines) != len(operations):
-            raise remote_operation.RemoteOperationException(
-                    "Unexpected number of responses: %d" % len(resp_lines))
-        return [operations[i].ParseResponse(resp_lines[i])
-                for i in range(len(resp_lines))]
-
-    def SendOperation(self, operation):
-        """Sends one operation and waits for its response.
-
-        Args:
-            operation: A remote_operation.RemoteOperation object.
-
-        Returns:
-            A JSON object.
-
-        Raises:
-            socket.error if fails to communicate with remote manager.
-            remote_operation.RemoteOperationException if the operation fails or
-            has no response.
-        """
-        return self.SendOperations(operation)[0]
-
-    def ListDevices(self):
-        """Sends ListDevices operation.
-
-        Returns:
-            A list of device_info.DeviceInfo which are the devices connected to
-            the host.
-        """
-        json_obj = self.SendOperation(remote_operation.ListDevices())
-        return remote_operation.ParseListDevicesResponse(json_obj)
-
-    def WaitForCommandResult(self, serial, timeout, poll_interval=5):
-        """Sends a series of operations to wait until a command finishes.
-
-        Args:
-            serial: The serial number of the device.
-            timeout: A float, the timeout in seconds.
-            poll_interval: A float, the interval of each GetLastCommandResult
-                           operation in seconds.
-
-        Returns:
-            A JSON object which is the result of the command.
-            None if timeout.
-
-            Sample
-            {'status': 'INVOCATION_SUCCESS',
-             'free_device_state': 'AVAILABLE'}
-        """
-        deadline = time.time() + timeout
-        get_result_op = remote_operation.GetLastCommandResult(serial)
-        while True:
-            result = self.SendOperation(get_result_op)
-            if result["status"] != "EXECUTING":
-                return result
-            if time.time() > deadline:
-                return None
-            time.sleep(poll_interval)
-            if time.time() > deadline:
-                return None
diff --git a/harnesses/host_controller/tradefed/remote_client_test.py b/harnesses/host_controller/tradefed/remote_client_test.py
deleted file mode 100644
index bc9cbb8..0000000
--- a/harnesses/host_controller/tradefed/remote_client_test.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import queue
-import socket
-import threading
-import unittest
-
-from host_controller.tradefed import remote_client
-from host_controller.tradefed import remote_operation
-
-
-class MockRemoteManagerThread(threading.Thread):
-    """A thread which mocks remote manager.
-
-    Attributes:
-        HOST: Local host name.
-        PORT: The port that the remote manager listens to.
-        _remote_mgr_socket: The remote manager socket.
-        _response_queue: A queue.Queue object containing the response strings.
-        _timeout: Socket timeout in seconds.
-        last_error: The exception which caused this thread to terminate.
-    """
-    HOST = remote_client.LOCALHOST
-    PORT = 32123
-
-    def __init__(self, timeout):
-        """Creates and listens to remote manager socket."""
-        super(MockRemoteManagerThread, self).__init__()
-        self._response_queue = queue.Queue()
-        self._timeout = timeout
-        self.last_error = None
-        self._remote_mgr_socket = socket.socket()
-        try:
-            self._remote_mgr_socket.settimeout(self._timeout)
-            self._remote_mgr_socket.bind((self.HOST, self.PORT))
-            self._remote_mgr_socket.listen(1)
-        except socket.error:
-            self._remote_mgr_socket.close()
-
-    def _Respond(self, response_str):
-        """Accepts a client connection and responds.
-
-        Args:
-            response_str: The response string.
-        """
-        (server_socket, client_address) = self._remote_mgr_socket.accept()
-        try:
-            server_socket.settimeout(self._timeout)
-            # Receive until connection is closed
-            while not server_socket.recv(4096):
-                pass
-            server_socket.send(response_str)
-        finally:
-            server_socket.close()
-
-    def AddResponse(self, response_str):
-        """Add a response string to the queue.
-
-        Args:
-            response_str: The response string.
-        """
-        self._response_queue.put_nowait(response_str)
-
-    def CloseSocket(self):
-        """Closes the remote manager socket."""
-        if self._remote_mgr_socket:
-            self._remote_mgr_socket.close()
-            self._remote_mgr_socket = None
-
-    # @Override
-    def run(self):
-        """Sends the queued responses to the clients."""
-        try:
-            while True:
-                response_str = self._response_queue.get()
-                self._response_queue.task_done()
-                if response_str is None:
-                    break
-                self._Respond(response_str)
-        except socket.error as e:
-            self.last_error = e
-        finally:
-            self.CloseSocket()
-
-
-class RemoteClientTest(unittest.TestCase):
-    """A test for remote_client.RemoteClient.
-
-    Attributes:
-        _remote_mgr_thread: An instance of MockRemoteManagerThread.
-        _client: The remote_client.RemoteClient being tested.
-    """
-
-    def setUp(self):
-        """Creates remote manager thread."""
-        self._remote_mgr_thread = MockRemoteManagerThread(5)
-        self._remote_mgr_thread.daemon = True
-        self._remote_mgr_thread.start()
-        self._client = remote_client.RemoteClient(self._remote_mgr_thread.HOST,
-                                                  self._remote_mgr_thread.PORT,
-                                                  5)
-
-    def tearDown(self):
-        """Terminates remote manager thread."""
-        self._remote_mgr_thread.AddResponse(None)
-        self._remote_mgr_thread.join(15)
-        self._remote_mgr_thread.CloseSocket()
-        self.assertFalse(self._remote_mgr_thread.is_alive(),
-                         "Cannot stop remote manager thread.")
-        if self._remote_mgr_thread.last_error:
-            raise self._remote_mgr_thread.last_error
-
-    def testListDevice(self):
-        """Tests ListDevices operation."""
-        self._remote_mgr_thread.AddResponse('{"serials": []}')
-        self._client.ListDevices()
-
-    def testAddCommand(self):
-        """Tests AddCommand operation."""
-        self._remote_mgr_thread.AddResponse('{}')
-        self._client.SendOperation(remote_operation.AddCommand(0, "COMMAND"))
-
-    def testMultipleOperations(self):
-        """Tests sending multiple operations via one connection."""
-        self._remote_mgr_thread.AddResponse('{}\n{}')
-        self._client.SendOperations(remote_operation.ListDevices(),
-                                    remote_operation.ListDevices())
-
-    def testExecuteCommand(self):
-        """Tests executing a command and waiting for result."""
-        self._remote_mgr_thread.AddResponse('{}')
-        self._client.SendOperation(remote_operation.AllocateDevice("serial123"))
-        self._remote_mgr_thread.AddResponse('{}')
-        self._client.SendOperation(remote_operation.ExecuteCommand(
-                "serial123", "vts", "-m", "SampleShellTest"))
-
-        self._remote_mgr_thread.AddResponse('{"status": "EXECUTING"}')
-        result = self._client.WaitForCommandResult("serial123",
-                                                   timeout=0.5, poll_interval=1)
-        self.assertIsNone(result, "Client returns result before command finishes.")
-
-        self._remote_mgr_thread.AddResponse('{"status": "EXECUTING"}')
-        self._remote_mgr_thread.AddResponse('{"status": "INVOCATION_SUCCESS"}')
-        result = self._client.WaitForCommandResult("serial123",
-                                                   timeout=5, poll_interval=1)
-        self._remote_mgr_thread.AddResponse('{}')
-        self._client.SendOperation(remote_operation.FreeDevice("serial123"))
-        self.assertIsNotNone(result, "Client doesn't return command result.")
-
-    def testSocketError(self):
-        """Tests raising exception when socket error occurs."""
-        self.assertRaises(socket.timeout, self._client.ListDevices)
-        self._remote_mgr_thread.AddResponse(None)
-        self.assertRaises(socket.error, self._client.ListDevices)
-
-    def testRemoteOperationException(self):
-        """Tests raising exception when response is an error."""
-        self._remote_mgr_thread.AddResponse('{"error": "unit test"}')
-        self.assertRaises(remote_operation.RemoteOperationException,
-                          self._client.ListDevices)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/tradefed/remote_operation.py b/harnesses/host_controller/tradefed/remote_operation.py
deleted file mode 100644
index 00839d4..0000000
--- a/harnesses/host_controller/tradefed/remote_operation.py
+++ /dev/null
@@ -1,172 +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.
-#
-
-import json
-
-from host_controller.tfc import device_info
-
-
-class RemoteOperationException(Exception):
-    """Raised when remote operation fails."""
-    pass
-
-
-class RemoteOperation(object):
-    """The operation sent to TradeFed remote manager.
-
-    Args:
-        _obj: A JSON object with at least 2 entries, "type" and "version".
-    """
-    CURRENT_PROTOCOL_VERSION = 8
-
-    def __init__(self, type, **kwargs):
-        """Initializes a remote operation.
-
-        Args:
-            type: A string, the type of the operation.
-            **kwargs: The arguments which are specific to the operation type.
-        """
-        self._obj = kwargs
-        self._obj["type"] = type
-        if "version" not in self._obj:
-            self._obj["version"] = self.CURRENT_PROTOCOL_VERSION
-
-    def ParseResponse(self, response_str):
-        """Parses the response to the operation.
-
-        Args:
-            response_str: A JSON string.
-
-        Returns:
-            A JSON object.
-
-        Raises:
-            RemoteOperationException if the response is an error.
-        """
-        response = json.loads(response_str)
-        if "error" in response:
-            raise RemoteOperationException(response["error"])
-        return response
-
-    @property
-    def type(self):
-        """Returns the type of this operation."""
-        return self._obj["type"]
-
-    def __str__(self):
-        """Converts the JSON object to string."""
-        return json.dumps(self._obj)
-
-
-def ListDevices():
-    """Creates an operation of listing devices."""
-    return RemoteOperation("LIST_DEVICES")
-
-
-def ParseListDevicesResponse(json_obj):
-    """Parses ListDevices response to a list of DeviceInfo.
-
-    Sample response:
-    {"serials": [
-        {"product": "unknown", "battery": "0", "variant": "unknown",
-         "stub": True, "state": "Available", "build": "unknown",
-         "serial": "emulator-5554", "sdk": "unknown"},
-    ]}
-
-    Args:
-        json_obj: A JSON object, the response to ListDevices.
-
-    Returns:
-        A list of DeviceInfo object.
-    """
-    dev_infos = []
-    for dev_obj in json_obj["serials"]:
-        if dev_obj["product"] == dev_obj["variant"]:
-            run_target = dev_obj["product"]
-        else:
-            run_target = dev_obj["product"] + ":" + dev_obj["variant"]
-        dev_info = device_info.DeviceInfo(
-                battery_level=dev_obj["battery"],
-                build_id=dev_obj["build"],
-                device_serial=dev_obj["serial"],
-                product=dev_obj["product"],
-                product_variant=dev_obj["variant"],
-                run_target=run_target,
-                sdk_version=dev_obj["sdk"],
-                state=dev_obj["state"],
-                stub=dev_obj["stub"])
-        dev_infos.append(dev_info)
-    return dev_infos
-
-
-def AllocateDevice(serial):
-    """Creates an operation of allocating a device.
-
-    Args:
-        serial: The serial number of the device.
-    """
-    return RemoteOperation("ALLOCATE_DEVICE", serial=serial)
-
-
-def FreeDevice(serial):
-    """Creates an operation of freeing a device.
-
-    Args:
-        serial: The serial number of the device.
-    """
-    return RemoteOperation("FREE_DEVICE", serial=serial)
-
-
-def Close():
-    """Creates an operation of stopping the remote manager."""
-    return RemoteOperation("CLOSE")
-
-
-def AddCommand(time, *command_args):
-    """Creates an operation of adding a command to the queue.
-
-    Args:
-        time: The time in ms that the command has been executing for. The value
-              is non-zero in handover situation.
-        command_args: The command to execute.
-    """
-    return RemoteOperation("ADD_COMMAND", time=time, commandArgs=command_args)
-
-
-def ExecuteCommand(serial, *command_args):
-    """Creates an operation of executing a command on a device.
-
-    Args:
-        serial: The serial number of the device.
-        command_args: The command to execute.
-    """
-    return RemoteOperation(
-            "EXEC_COMMAND", serial=serial, commandArgs=command_args)
-
-
-def GetLastCommandResult(serial):
-    """Creates an operation of getting last EXEC_COMMAND result on a device.
-
-    Sample response:
-    {"status": "INVOCATION_ERROR",
-     "invocation_error": "java.lang.NullPointerException",
-     "free_device_state": "AVAILABLE"
-    }
-
-    Args:
-        serial: The serial number of the device.
-    """
-    return RemoteOperation("GET_LAST_COMMAND_RESULT", serial=serial)
diff --git a/harnesses/host_controller/utils/__init__.py b/harnesses/host_controller/utils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/utils/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/utils/gcp/__init__.py b/harnesses/host_controller/utils/gcp/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/utils/gcp/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/utils/gcp/gcs_utils.py b/harnesses/host_controller/utils/gcp/gcs_utils.py
deleted file mode 100644
index ffe0913..0000000
--- a/harnesses/host_controller/utils/gcp/gcs_utils.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from vts.utils.python.common import cmd_utils
-
-
-def GetGsutilPath():
-    """Finds gsutil in PATH.
-
-    Instead of a Python library, gsutil binary is used to avoid packaging GCS
-    PIP package as part of VTS HC (Host Controller).
-
-    Returns:
-        The gsutil file path if found; None otherwise.
-    """
-    sh_stdout, sh_stderr, ret_code = cmd_utils.ExecuteOneShellCommand(
-        "which gsutil")
-    if ret_code == 0:
-        return sh_stdout.strip()
-    else:
-        logging.fatal("`gsutil` doesn't exist on the host; "
-                      "please install Google Cloud SDK before retrying.")
-        return None
-
-
-def IsGcsFile(gsutil_path, url):
-    """Checks whether a given path is for a GCS file.
-
-    Args:
-        gsutil_path: string, the path of a gsutil binary.
-        url: string, the GCS URL. e.g., gs://<bucket>/<file>.
-
-    Returns:
-        True if url is a file, False otherwise.
-    """
-    check_command = "%s stat %s" % (gsutil_path, url)
-    _, _, ret_code = cmd_utils.ExecuteOneShellCommand(check_command)
-    return ret_code == 0
-
-
-def Copy(gsutil_path, src_urls, dst_url):
-    """Copies files between local file system and GCS.
-
-    Args:
-        gsutil_path: string, the path of a gsutil binary.
-        src_urls: string, the source paths or GCS URLs separated by spaces.
-        dst_url: string, the destination path or GCS URL.
-
-    Returns:
-        True if the command succeeded, False otherwise.
-    """
-    copy_command = "%s cp %s %s" % (gsutil_path, src_urls, dst_url)
-    _, _, ret_code = cmd_utils.ExecuteOneShellCommand(copy_command)
-    return ret_code == 0
-
-
-def List(gsutil_path, url):
-    """Lists a directory or file on GCS.
-
-    Args:
-        gsutil_path: string, the path of a gsutil binary.
-        url: string, the GCS URL of the directory or file.
-
-    Returns:
-        list of strings, the GCS URLs of the listed files.
-    """
-    ls_command = "%s ls %s" % (gsutil_path, url)
-    stdout, _, ret_code = cmd_utils.ExecuteOneShellCommand(ls_command)
-    return stdout.strip("\n").split("\n") if ret_code == 0 else []
-
-
-def Remove(gsutil_path, url, recursive=False):
-    """Removes a directory or file on GCS.
-
-    Args:
-        gsutil_path: string, the path of a gsutil binary.
-        url: string, the GCS URL of the directory or file.
-        recursive: boolean, whether to remove the directory recursively.
-
-    Returns:
-        True if the command succeeded, False otherwise.
-    """
-    if "/" not in url.lstrip("gs://").rstrip("/"):
-        logging.error("Cannot remove bucket %s", url)
-        return False
-    rm_command = "%s rm -f%s %s" % (
-        gsutil_path, ("r" if recursive else ""), url)
-    ret_code = cmd_utils.ExecuteOneShellCommand(rm_command)
-    return ret_code == 0
diff --git a/harnesses/host_controller/utils/gsi/__init__.py b/harnesses/host_controller/utils/gsi/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/utils/gsi/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/utils/gsi/img_utils.py b/harnesses/host_controller/utils/gsi/img_utils.py
deleted file mode 100644
index ae197ab..0000000
--- a/harnesses/host_controller/utils/gsi/img_utils.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-#   Copyright 2018 - The Android Open Source Project
-#
-#   Licensed under the Apache License, Version 2.0 (the "License");
-#   you may not use this file except in compliance with the License.
-#   You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS,
-#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#   See the License for the specific language governing permissions and
-#   limitations under the License.
-
-import logging
-import struct
-
-OS_VERSOIN_OFFSET_BOOTIMG = 44
-SPL_YEAR_BASE_BOOTIMG = 2000
-SPL_YEAR_MASK_BOOTIMG = 127 << 4
-SPL_MONTH_MASK_BOOTIMG = 15
-
-
-def GetSPLVersionFromBootImg(img_file_path):
-    """Gets SPL version from given boot.img file path.
-
-    Args:
-        img_file_path : string, path to the boot.img file.
-    Returns:
-        A dict contains SPL version's year and date value.
-    """
-    try:
-        fo = open(img_file_path, "rb")
-        fo.seek(OS_VERSOIN_OFFSET_BOOTIMG, 0)
-
-        os_version = fo.read(4)
-    except IOError as e:
-        logging.error(e.strerror)
-        return {}
-
-    os_version_int = struct.unpack("i", os_version)[0]
-
-    year = (os_version_int & SPL_YEAR_MASK_BOOTIMG) >> 4
-    month = os_version_int & SPL_MONTH_MASK_BOOTIMG
-
-    version_date = {}
-    version_date["year"] = SPL_YEAR_BASE_BOOTIMG + year
-    version_date["month"] = month
-
-    return version_date
\ No newline at end of file
diff --git a/harnesses/host_controller/utils/ipc/__init__.py b/harnesses/host_controller/utils/ipc/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/utils/ipc/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/utils/ipc/file_lock.py b/harnesses/host_controller/utils/ipc/file_lock.py
deleted file mode 100644
index 67b6bf7..0000000
--- a/harnesses/host_controller/utils/ipc/file_lock.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import fcntl
-import logging
-import os
-
-from host_controller import common
-
-
-class FileLock(object):
-    """Class for using files as a locking mechanism for devices.
-
-    This is for checking whether a certain device is running a job or not when
-    the automated self-update happens.
-
-    Attributes:
-        _devlock_dir: string, represent the home directory of the user.
-        _lock_fd: dict, maps serial number of the devices and file descriptor.
-    """
-
-    def __init__(self, file_name=None, mode=None):
-        """Initializes the file lock managing class instance.
-
-        Args:
-            file_name: string, name of the file to be opened. Existing lock
-                       files will be opened if given as None
-            mode: string, the mode argument to open() function.
-        """
-        self._lock_fd = {}
-        self._devlock_dir = os.path.join(
-            os.path.expanduser("~"), common._DEVLOCK_DIR)
-        if not os.path.exists(self._devlock_dir):
-            os.mkdir(self._devlock_dir)
-
-        if file_name:
-            file_list = [file_name]
-        else:
-            file_list = [file_name for file_name in os.listdir(self._devlock_dir)]
-        logging.debug("file_list for file lock: %s", file_list)
-
-        for file_name in file_list:
-            if os.path.isfile(os.path.join(self._devlock_dir, file_name)):
-                self._OpenFile(file_name, mode)
-
-    def _OpenFile(self, serial, mode=None):
-        """Opens the given lock file and store the file descriptor to _lock_fd.
-
-        Args:
-            serial: string, serial number of a device.
-            mode: string, the mode argument to open() function.
-                  Set to "w+" if given as None.
-        """
-        if serial in self._lock_fd and self._lock_fd[serial]:
-            logging.info("Lock for the device %s already exists." % serial)
-            return
-
-        try:
-            if not mode:
-                mode = "w+"
-            self._lock_fd[serial] = open(
-                os.path.join(self._devlock_dir, serial), mode, 0)
-        except IOError as e:
-            logging.exception(e)
-            return False
-
-    def LockDevice(self, serial, suppress_lock_warning=False, block=False):
-        """Tries to lock the file corresponding to "serial".
-
-        Args:
-            serial: string, serial number of a device.
-            suppress_lock_warning: bool, True to suppress warning log output.
-            block: bool, True to block at the fcntl.lockf(), waiting for it
-                   to be unlocked.
-
-        Returns:
-            True if successfully acquired the lock. False otherwise.
-        """
-        if serial not in self._lock_fd:
-            ret = self._OpenFile(serial)
-            if ret == False:
-                return ret
-
-        try:
-            operation = fcntl.LOCK_EX
-            if not block:
-                operation |= fcntl.LOCK_NB
-            fcntl.lockf(self._lock_fd[serial], operation)
-        except IOError as e:
-            if not suppress_lock_warning:
-                logging.exception(e)
-            return False
-
-        return True
-
-    def UnlockDevice(self, serial):
-        """Releases the lock file corresponding to "serial".
-
-        Args:
-            serial: string, serial number of a device.
-        """
-        if serial not in self._lock_fd:
-            logging.error("Lock for the device %s does not exist." % serial)
-            return False
-
-        fcntl.lockf(self._lock_fd[serial], fcntl.LOCK_UN)
diff --git a/harnesses/host_controller/utils/ipc/file_lock_semaphore.py b/harnesses/host_controller/utils/ipc/file_lock_semaphore.py
deleted file mode 100644
index 724c7b0..0000000
--- a/harnesses/host_controller/utils/ipc/file_lock_semaphore.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import time
-
-from host_controller import common
-from host_controller.utils.ipc import file_lock
-
-MIN_SLEEP_TIME_IN_SECS = 1
-MAX_SLEEP_TIME_IN_SECS = 60
-
-
-class FileLockSemaphore(file_lock.FileLock):
-    """Class for system-wide semaphores for inter process-group sync.
-
-    Inherited FileLock to make the decrement and increment operation atomic,
-    thus any read and write operations to the file must be leaded by Lock()
-    and be followed by Unlock() operations, defined in FileLock
-
-    Attributes:
-        _name: string, name of the file used as semaphore.
-    """
-
-    def __init__(self, name):
-        super(FileLockSemaphore, self).__init__(name, "r+")
-        self._name = name
-        self._InitSemaphore()
-
-    def Acquire(self):
-        """P() operation for the FileLockSemaphore.
-
-        To minimize the starvation, the sleep time will decrease
-        for the processes that have waited longer than the others.
-        """
-        sleep_time = MAX_SLEEP_TIME_IN_SECS
-        while self.LockDevice(self._name, True, True):
-            if self.sem_value > 0:
-                break
-            self.UnlockDevice(self._name)
-            time.sleep(sleep_time)
-            sleep_time = max(sleep_time / 2, MIN_SLEEP_TIME_IN_SECS)
-
-        self._Decrement()
-        self.UnlockDevice(self._name)
-
-    def Release(self):
-        """V() operation for the FileLockSemaphore."""
-        self.LockDevice(self._name, True, True)
-        self._Increment()
-        self.UnlockDevice(self._name)
-
-    def _InitSemaphore(self):
-        """Initializes the file content for semaphore operations.
-
-        The value of the counter must remain in the range
-        [0, common.MAX_ADB_FASTBOOT_PROCESS] inclusive.
-        """
-        self.LockDevice(self._name, True, True)
-
-        try:
-            diff = common.MAX_ADB_FASTBOOT_PROCESS - self.sem_max_value
-            value_to_init = min(
-                max(0, self.sem_value + diff), common.MAX_ADB_FASTBOOT_PROCESS)
-        except IndexError:
-            value_to_init = common.MAX_ADB_FASTBOOT_PROCESS
-
-        self._lock_fd[self._name].seek(0)
-        self._lock_fd[self._name].truncate(0)
-        self._lock_fd[self._name].write(
-            "%s\n%s" % (common.MAX_ADB_FASTBOOT_PROCESS, value_to_init))
-
-        self.UnlockDevice(self._name)
-
-    @property
-    def sem_value(self):
-        """Reads the current counter value of the semaphore.
-
-        Returns:
-            int, the value of the current counter.
-        """
-        self._lock_fd[self._name].seek(0)
-        return int(self._lock_fd[self._name].read().split()[1])
-
-    @property
-    def sem_max_value(self):
-        """Reads the current maximum counter value of the semaphore.
-
-        Since the maximum counter value may vary at the deployment time,
-        the existing HC process group needs to look for the maximum value
-        every time it tries to access the semaphore
-
-        Returns:
-            int, the value of the maximum counter.
-        """
-        self._lock_fd[self._name].seek(0)
-        return int(self._lock_fd[self._name].read().split()[0])
-
-    def _Decrement(self):
-        """Decrements the internal counter of the semaphore."""
-        current_value = self.sem_value
-        current_max = self.sem_max_value
-        self._lock_fd[self._name].seek(len(str(current_max)) + 1)
-        self._lock_fd[self._name].write("%s" % max(0, (current_value - 1)))
-
-    def _Increment(self):
-        """Increments the internal counter of the semaphore."""
-        current_value = self.sem_value
-        current_max = self.sem_max_value
-        self._lock_fd[self._name].seek(len(str(current_max)) + 1)
-        self._lock_fd[self._name].write("%s" % min(current_max,
-                                                   (current_value + 1)))
diff --git a/harnesses/host_controller/utils/ipc/file_lock_semaphore_test.py b/harnesses/host_controller/utils/ipc/file_lock_semaphore_test.py
deleted file mode 100644
index e1bae8b..0000000
--- a/harnesses/host_controller/utils/ipc/file_lock_semaphore_test.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import threading
-import time
-import unittest
-
-try:
-    from unittest import mock
-except ImportError:
-    import mock
-
-from host_controller import common
-from host_controller.utils.ipc import file_lock_semaphore
-
-
-class FileLockSemaphoreTest(unittest.TestCase):
-    """Tests for FileLockSemaphore"""
-
-    def setUp(self):
-        self.sem = file_lock_semaphore.FileLockSemaphore("fls_test")
-
-    def tearDown(self):
-        os.remove(os.path.join(os.path.expanduser("~"), common._DEVLOCK_DIR, "fls_test"))
-
-    def testFileLockSemaphoreAcquire(self):
-        current_sem_value = self.sem.sem_value
-        self.sem.Acquire()
-        self.assertEqual(current_sem_value - 1, self.sem.sem_value)
-        self.sem.Release()
-
-    def testFileLockSemaphoreRelease(self):
-        self.sem.Acquire()
-        current_sem_value = self.sem.sem_value
-        self.sem.Release()
-        self.assertEqual(current_sem_value + 1, self.sem.sem_value)
-
-    def testFileLockSemaphoreOverflow(self):
-        current_sem_value = self.sem.sem_value
-        self.sem.Release()
-        self.assertEqual(current_sem_value, self.sem.sem_value)
-
-    def _AcquireRelease(self):
-        self.sem.Acquire()
-        self.assertEqual(self.sem.sem_value, 0)
-        self.sem.Release()
-
-    def testFileLockSemaphoreUnderflow(self):
-        for _ in range(common.MAX_ADB_FASTBOOT_PROCESS):
-            self.sem.Acquire()
-
-        file_lock_semaphore.MAX_SLEEP_TIME_IN_SECS = 2
-        self._thread = threading.Thread(target=self._AcquireRelease)
-        self._thread.daemon = True
-        self._thread.start()
-
-        time.sleep(1)
-        self.sem.Release()
-        self._thread.join()
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/harnesses/host_controller/utils/ipc/shared_dict.py b/harnesses/host_controller/utils/ipc/shared_dict.py
deleted file mode 100644
index a0e707f..0000000
--- a/harnesses/host_controller/utils/ipc/shared_dict.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import multiprocessing
-
-from host_controller import common
-
-
-class SharedDict(object):
-    """Class for the state of devices connected to the host.
-
-    shared between the main process and the process pool.
-
-    Attributes:
-        _manager: SyncManager. an instance of a manager for shared objects and
-                  values between processes.
-        _dict: multiprocessing.SyncManager.dict. A dictionary
-               shared among processes.
-    """
-
-    def __init__(self, manager=None):
-        if manager is not None:
-            self._manager = manager
-        else:
-            self._manager = multiprocessing.Manager()
-        self._dict = self._manager.dict()
-
-    def __getitem__(self, key):
-        """getitem for self._dict.
-
-        Args:
-            key: string, serial number of a device.
-
-        Returns:
-            integer value defined in _DEVICE_STATUS_DICT.
-        """
-        if key not in self._dict:
-            self._dict[key] = common._DEVICE_STATUS_DICT["unknown"]
-        return self._dict[key]
-
-    def __setitem__(self, key, value):
-        """setitem for self._dict.
-
-        if the value is not a defined one, device status is set to "unknown".
-
-        Args:
-            key: string, serial number of a device.
-            value: integer, status value defined in _DEVICE_STATUS_DICT.
-        """
-        if value not in range(len(common._DEVICE_STATUS_DICT)):
-            self._dict[key] = common._DEVICE_STATUS_DICT["unknown"]
-        else:
-            self._dict[key] = value
\ No newline at end of file
diff --git a/harnesses/host_controller/utils/parser/__init__.py b/harnesses/host_controller/utils/parser/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/utils/parser/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/utils/parser/pb2_utils.py b/harnesses/host_controller/utils/parser/pb2_utils.py
deleted file mode 100644
index af96588..0000000
--- a/harnesses/host_controller/utils/parser/pb2_utils.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import json
-import logging
-import requests
-
-# timeout seconds for requests
-REQUESTS_TIMEOUT_SECONDS = 60
-
-
-def FillDictAndPost(msg,
-                    dict_to_fill,
-                    url,
-                    headers,
-                    filters={},
-                    caller_name=""):
-    """Fills up a dict using contents of the pb2 message and uploads it.
-
-    Args:
-        msg: pb2 msg, containing info about all task schedules.
-        dict_to_fill: dict, to be converted into a json object before
-                      upload.
-        url: string, URL for the endpoit API to be called when
-                     the dict_to_fill fills up.
-
-    Returns:
-        True if successful, False otherwise.
-    """
-    terminal = True
-    ret = True
-    sub_msg_list = []
-    for field in msg.DESCRIPTOR.fields:
-        if field.type == field.TYPE_MESSAGE:
-            terminal = False
-            for sub_msg in msg.__getattribute__(field.name):
-                # make all the messages to be processed after other attrs,
-                # otherwise dict_to_fill would be incomplete.
-                sub_msg_list.append(sub_msg)
-        else:
-            if filters and field.name in filters:
-                filtered_key = filters[field.name]
-            else:
-                filtered_key = field.name
-
-            if field.label == field.LABEL_REPEATED:
-                dict_to_fill[filtered_key] = list(
-                    msg.__getattribute__(field.name))
-            else:
-                dict_to_fill[filtered_key] = msg.__getattribute__(field.name)
-
-    for sub_msg in sub_msg_list:
-        ret = ret and FillDictAndPost(sub_msg, dict_to_fill, url, headers,
-                                      filters, caller_name)
-
-    if terminal:
-        try:
-            response = requests.post(url, data=json.dumps(dict_to_fill),
-                                     headers=headers,
-                                     timeout=REQUESTS_TIMEOUT_SECONDS)
-        except requests.exceptions.Timeout as e:
-            logging.exception(e)
-            return False
-        if response.status_code != requests.codes.ok:
-            logging.error("%s error: %s", caller_name, response)
-            ret = ret and False
-
-    return ret
diff --git a/harnesses/host_controller/utils/parser/result_utils.py b/harnesses/host_controller/utils/parser/result_utils.py
deleted file mode 100644
index 9b9b51e..0000000
--- a/harnesses/host_controller/utils/parser/result_utils.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-import os
-
-from xml.etree import ElementTree
-
-from host_controller import common
-
-
-def ExtractResultZip(zip_file, output_dir, xml_only=True):
-    """Extracts XML result from a zip file.
-
-    Args:
-        zip_file: An object of zipfile.ZipFile.
-        output_dir: The directory where the zip is extracted.
-        xml_only: Whether to extract log-result.xml or test_result.xml only.
-
-    Returns:
-        The path to the XML in the output directory.
-        None if the zip does not contain the XML result.
-    """
-    try:
-        xml_name = next(x for x in zip_file.namelist() if
-                        x.endswith(common._TEST_RESULT_XML) or
-                        x.endswith(common._LOG_RESULT_XML))
-    except StopIteration:
-        return None
-
-    if not os.path.exists(output_dir):
-        os.makedirs(output_dir)
-    if xml_only:
-        return zip_file.extract(xml_name, path=output_dir)
-    else:
-        zip_file.extractall(path=output_dir)
-        return os.path.join(output_dir, xml_name)
-
-
-def LoadTestSummary(result_xml):
-    """Gets attributes of <Result>, <Build>, and <Summary>.
-
-    Args:
-        result_xml: A file object of the TradeFed report in XML format.
-
-    Returns:
-        3 dictionaries, the attributes of <Result>, <Build>, and <Summary>.
-    """
-    result_attrib = {}
-    build_attrib = {}
-    summary_attrib = {}
-    for event, elem in ElementTree.iterparse(result_xml, events=("start", )):
-        if all((result_attrib, build_attrib, summary_attrib)):
-            break
-        if elem.tag == common._RESULT_TAG:
-            result_attrib = dict(elem.attrib)
-        elif elem.tag == common._BUILD_TAG:
-            build_attrib = dict(elem.attrib)
-        elif elem.tag == common._SUMMARY_TAG:
-            summary_attrib = dict(elem.attrib)
-    return result_attrib, build_attrib, summary_attrib
-
-
-def IterateTestResults(result_xml):
-    """Yields test records in test_result.xml.
-
-    Args:
-        result_xml: A file object of the TradeFed report in XML format.
-
-    Yields:
-        A tuple of ElementTree.Element, (Module, TestCase, Test) for each
-        </Test>.
-    """
-    module_elem = None
-    testcase_elem = None
-    for event, elem in ElementTree.iterparse(
-            result_xml, events=("start", "end")):
-        if event == "start":
-            if elem.tag == common._MODULE_TAG:
-                module_elem = elem
-            elif elem.tag == common._TESTCASE_TAG:
-                testcase_elem = elem
-
-        if event == "end" and elem.tag == common._TEST_TAG:
-            yield module_elem, testcase_elem, elem
-
-
-def GetAbiBitness(abi):
-    """Gets bitness of an ABI.
-
-    Args:
-        abi: A string, the ABI name.
-
-    Returns:
-        32 or 64, the ABI bitness.
-    """
-    return 64 if "arm64" in abi or "x86_64" in abi else 32
-
-
-def GetTestName(module, testcase, test):
-    """Gets the bitness and the full test name.
-
-    Args:
-        module: The Element for <Module>.
-        testcase: The Element for <TestCase>.
-        test: The Element for <Test>.
-
-    Returns:
-        A tuple of (bitness, module_name, testcase_name, test_name).
-    """
-    abi = module.attrib.get(common._ABI_ATTR_KEY, "")
-    bitness = str(GetAbiBitness(abi))
-    module_name = module.attrib.get(common._NAME_ATTR_KEY, "")
-    testcase_name = testcase.attrib.get(common._NAME_ATTR_KEY, "")
-    test_name = test.attrib.get(common._NAME_ATTR_KEY, "")
-    return bitness, module_name, testcase_name, test_name
diff --git a/harnesses/host_controller/utils/parser/xml_utils.py b/harnesses/host_controller/utils/parser/xml_utils.py
deleted file mode 100644
index 3717d5a..0000000
--- a/harnesses/host_controller/utils/parser/xml_utils.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-
-from xml.etree import ElementTree
-
-
-def GetAttributes(xml_file, tag, attrs):
-    """Parses attributes in the given tag from xml file.
-
-    Args:
-        xml_file: The xml file object.
-        tag: a string, tag to parse from tag xml_file.
-        attrs: a list of attributes to look up inside the tag.
-
-    Returns:
-        A dict containing values of the attributes in tag from the xml file.
-    """
-    result = {}
-    for _, elem in ElementTree.iterparse(xml_file, ("start", )):
-        if elem.tag == tag:
-            for attr in attrs:
-                if attr in elem.attrib:
-                    result[attr] = elem.attrib[attr]
-                else:
-                    logging.warning(
-                        "Cannot find an attribute {} in <{}>".format(
-                            attr, tag))
-    return result
diff --git a/harnesses/host_controller/utils/usb/__init__.py b/harnesses/host_controller/utils/usb/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/utils/usb/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/utils/usb/usb_utils.py b/harnesses/host_controller/utils/usb/usb_utils.py
deleted file mode 100644
index 5c42c7b..0000000
--- a/harnesses/host_controller/utils/usb/usb_utils.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import fcntl
-import logging
-import os
-
-from vts.utils.python.common import cmd_utils
-
-# _IO('U', 20)
-USBDEVFS_RESET = ord("U") << 8 | 20
-
-
-def GetDevicesUSBFilePath():
-    """Sweeps through connected USB device info and maps serial number to them.
-
-    Returns:
-        A dict, serial numbers of the devices as the key, device file path
-        corresponding to the serial number as the value.
-    """
-    ret = {}
-
-    sh_stdout, sh_stderr, ret_code = cmd_utils.ExecuteOneShellCommand("which udevadm")
-    if ret_code != 0:
-        logging.error("`udevadm` doesn't exist on the host; "
-                      "please install 'udev' pkg before retrying.")
-        return ret
-
-    sh_stdout, _, _ = cmd_utils.ExecuteOneShellCommand(
-        "find /sys/bus/usb/devices/usb*/ -name dev")
-    lines = sh_stdout.split()
-    for line in lines:
-        syspath = os.path.dirname(line)
-        devname, _, _ = cmd_utils.ExecuteOneShellCommand(
-            "udevadm info -q name -p %s" % syspath)
-        if devname.startswith("bus/"):
-            serial, _, _ = cmd_utils.ExecuteOneShellCommand(
-                "udevadm info -q property --export -p %s | grep ID_SERIAL_SHORT"
-                % syspath)
-            if serial:
-                device_serial = serial.split("=")[1].strip().strip("'")
-                ret[device_serial] = os.path.join("/dev", devname.strip())
-
-    return ret
-
-
-def ResetDeviceUsb(dev_file_path):
-    """Invokes ioctl that resets the USB device on the given file path.
-
-    Args:
-        dev_file_path: string, abs path to the device file
-
-    Returns:
-        True if successful, False otherwise.
-    """
-    try:
-        with open(dev_file_path, "wb") as usb_fd:
-            fcntl.ioctl(usb_fd, USBDEVFS_RESET, 0)
-    except IOError as e:
-        logging.exception(e)
-        return False
-
-    return True
-
-
-def ResetUsbDeviceOfSerial(serial):
-    """Resets a USB device file corresponding to the given serial.
-
-    Args:
-        serial: string, serial number of the device whose USB device file
-                will reset.
-
-    Returns:
-        True if successful, False otherwise.
-    """
-    device_file_path = GetDevicesUSBFilePath()
-    if serial in device_file_path:
-        logging.error(
-            "Device %s not responding. Resetting device file %s.", serial,
-            device_file_path[serial])
-        return ResetDeviceUsb(device_file_path[serial])
-    return False
-
-
-def ResetUsbDeviceOfSerial_Callback(*args):
-    """Wrapper of the ResetUsbDeviceOfSerial(), for handling the *args.
-
-    Args:
-        args: tuple of arguments, expected to have the serial number of
-              the devices as the first element.
-
-    Returns:
-        True if successful, False otherwise.
-    """
-    try:
-        return ResetUsbDeviceOfSerial(args[0])
-    except IndexError as e:
-        logging.exception(e)
-        return False
\ No newline at end of file
diff --git a/harnesses/host_controller/vti_interface/__init__.py b/harnesses/host_controller/vti_interface/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/harnesses/host_controller/vti_interface/__init__.py
+++ /dev/null
diff --git a/harnesses/host_controller/vti_interface/vti_endpoint_client.py b/harnesses/host_controller/vti_interface/vti_endpoint_client.py
deleted file mode 100644
index 17fdc9d..0000000
--- a/harnesses/host_controller/vti_interface/vti_endpoint_client.py
+++ /dev/null
@@ -1,452 +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.
-#
-
-import json
-import logging
-import requests
-import threading
-import time
-
-from host_controller.utils.parser import pb2_utils
-
-# Job status dict
-JOB_STATUS_DICT = {
-    # scheduled but not leased yet
-    "ready": 0,
-    # scheduled and in running
-    "leased": 1,
-    # completed job
-    "complete": 2,
-    # unexpected error during running
-    "infra-err": 3,
-    # never leased within schedule period
-    "expired": 4,
-    # device boot error after flashing the given img sets
-    "bootup-err": 5
-}
-
-SCHEDULE_INFO_PB2_ATTR_FILTERS = {
-    "pab_account_id": "device_pab_account_id",
-    "name": "build_target",
-}
-
-# timeout seconds for requests
-REQUESTS_TIMEOUT_SECONDS = 60
-
-
-class VtiEndpointClient(object):
-    """VTI (Vendor Test Infrastructure) endpoint client.
-
-    Attributes:
-        _headers: A dictionary, containing HTTP request header information.
-        _url: string, the base URL of an endpoint API.
-        _job: dict, currently leased job info.
-    """
-
-    def __init__(self, url):
-        if url == "localhost":
-            url = "http://localhost:8080/_ah/api/"
-        else:
-            if not url.startswith(("https://")) and not url.startswith("http://"):
-                url = "https://" + url
-            if url.endswith("appspot.com"):
-                url += "/_ah/api/"
-        self._headers = {"content-type": "application/json",
-                   "Accept-Charset": "UTF-8"}
-        self._url = url
-        self._job = {}
-        self._heartbeat_thread = None
-
-    def UploadBuildInfo(self, builds):
-        """Uploads the given build information to VTI.
-
-        Args:
-            builds: a list of dictionaries, containing info about all new
-                    builds found.
-
-        Returns:
-            True if successful, False otherwise.
-        """
-        url = self._url + "build/v1/set"
-        fail = False
-        for build in builds:
-            try:
-                response = requests.post(url, data=json.dumps(build),
-                                         headers=self._headers,
-                                         timeout=REQUESTS_TIMEOUT_SECONDS)
-                if response.status_code != requests.codes.ok:
-                    logging.error("UploadBuildInfo error: %s", response)
-                    fail = True
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-                fail = True
-        if fail:
-            return False
-        return True
-
-    def UploadDeviceInfo(self, hostname, devices):
-        """Uploads the given device information to VTI.
-
-        Args:
-            hostname: string, the hostname of a target host.
-            devices: a list of dicts, containing info about all detected
-                     devices that are attached to the host.
-
-        Returns:
-            True if successful, False otherwise.
-        """
-        url = self._url + "host/v1/set"
-        payload = {}
-        payload["hostname"] = hostname
-        payload["devices"] = []
-        for device in devices:
-            new_device = {
-                "serial": device["serial"],
-                "product": device["product"],
-                "status": device["status"]}
-            payload["devices"].append(new_device)
-
-        try:
-            response = requests.post(url, data=json.dumps(payload),
-                                     headers=self._headers,
-                                     timeout=REQUESTS_TIMEOUT_SECONDS)
-        except (requests.exceptions.ConnectionError,
-                requests.exceptions.Timeout) as e:
-            logging.exception(e)
-            return False
-        if response.status_code != requests.codes.ok:
-            logging.error("UploadDeviceInfo error: %s", response)
-            return False
-        return True
-
-    def UploadScheduleInfo(self, pbs, clear_schedule):
-        """Uploads the given schedule information to VTI.
-
-        Args:
-            pbs: a list of dicts, containing info about all task schedules.
-            clear_schedule: bool, True to clear all schedule data exist on the
-                            scheduler
-
-        Returns:
-            True if successful, False otherwise.
-        """
-        if pbs is None or len(pbs) == 0:
-            return False
-
-        url = self._url + "schedule/v1/clear"
-        succ = True
-        if clear_schedule:
-            try:
-                response = requests.post(
-                    url, data=json.dumps({"manifest_branch": "na"}),
-                    headers=self._headers, timeout=REQUESTS_TIMEOUT_SECONDS)
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-                return False
-            if response.status_code != requests.codes.ok:
-                logging.error("UploadScheduleInfo error: %s", response)
-                succ = False
-
-        if not succ:
-            return False
-
-        url = self._url + "schedule/v1/set"
-        for pb in pbs:
-            schedule = {}
-            succ = succ and pb2_utils.FillDictAndPost(
-                pb, schedule, url, self._headers,
-                SCHEDULE_INFO_PB2_ATTR_FILTERS, "UploadScheduleInfo")
-
-        return succ
-
-    def UploadLabInfo(self, pbs, clear_labinfo):
-        """Uploads the given lab information to VTI.
-
-        Args:
-            pbs: a list of dicts, containing info about all known labs.
-            clear_labinfo: bool, True to clear all lab data exist on the
-                           scheduler
-
-        Returns:
-            True if successful, False otherwise.
-        """
-        if pbs is None or len(pbs) == 0:
-            return
-
-        url = self._url + "lab/v1/clear"
-        succ = True
-        if clear_labinfo:
-            try:
-                response = requests.post(url, data=json.dumps({"name": "na"}),
-                                         headers=self._headers,
-                                         timeout=REQUESTS_TIMEOUT_SECONDS)
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-                return False
-            if response.status_code != requests.codes.ok:
-                logging.error("UploadLabInfo error: %s", response)
-                succ = False
-
-        if not succ:
-            return False
-
-        url = self._url + "lab/v1/set"
-        for pb in pbs:
-            lab = {}
-            lab["name"] = pb.name
-            lab["owner"] = pb.owner
-            lab["admin"] = []
-            lab["admin"].extend(pb.admin)
-            lab["host"] = []
-            for host in pb.host:
-                new_host = {}
-                new_host["hostname"] = host.hostname
-                new_host["ip"] = host.ip
-                new_host["script"] = host.script
-                if host.host_equipment:
-                    new_host["host_equipment"] = []
-                    new_host["host_equipment"].extend(host.host_equipment)
-                new_host["device"] = []
-                if host.device:
-                    for device in host.device:
-                        new_device = {}
-                        new_device["serial"] = device.serial
-                        new_device["product"] = device.product
-                        if device.device_equipment:
-                            new_device["device_equipment"] = []
-                            new_device["device_equipment"].extend(
-                                device.device_equipment)
-                        new_host["device"].append(new_device)
-                lab["host"].append(new_host)
-            try:
-                response = requests.post(url, data=json.dumps(lab),
-                                         headers=self._headers,
-                                         timeout=REQUESTS_TIMEOUT_SECONDS)
-                if response.status_code != requests.codes.ok:
-                    logging.error("UploadLabInfo error: %s", response)
-                    succ = False
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-                succ = False
-        return succ
-
-    def LeaseJob(self, hostname, execute=True):
-        """Leases a job for the given host, 'hostname'.
-
-        Args:
-            hostname: string, the hostname of a target host.
-            execute: boolean, True to lease and execute StartHeartbeat, which is
-                     the case that the leased job will be executed on this
-                     process's context.
-
-        Returns:
-            True if successful, False otherwise.
-        """
-        if not hostname:
-            return None, {}
-
-        url = self._url + "job/v1/lease"
-        try:
-            response = requests.post(url, data=json.dumps({"hostname": hostname}),
-                                     headers=self._headers,
-                                     timeout=REQUESTS_TIMEOUT_SECONDS)
-        except requests.exceptions.Timeout as e:
-            logging.exception(e)
-            return None, {}
-
-        if response.status_code != requests.codes.ok:
-            logging.error("LeaseJob error: %s", response.status_code)
-            return None, {}
-
-        response_json = json.loads(response.text)
-        if ("return_code" in response_json
-                and response_json["return_code"] != "SUCCESS"):
-            logging.debug("LeaseJob error: %s", response_json)
-            return None, {}
-
-        if "jobs" not in response_json:
-            logging.error(
-                "LeaseJob jobs not found in response json %s", response.text)
-            return None, {}
-
-        jobs = response_json["jobs"]
-        if jobs and len(jobs) > 0:
-            for job in jobs:
-                if execute == True:
-                    self._job = job
-                    self.StartHeartbeat("leased", 60)
-                return job["test_name"].split("/")[0], job
-        return None, {}
-
-    def ExecuteJob(self, job):
-        """Executes leased job passed from parent process.
-
-        Args:
-            job: dict, information the on leased job.
-
-        Returns:
-            a string which is path to a script file for onecmd().
-            a dict contains info on the leased job, will be passed to onecmd().
-        """
-        logging.info("Job info : {}".format(json.dumps(job)))
-        if job is not None:
-            self._job = job
-            self.StartHeartbeat("leased", 60)
-            return job["test_name"].split("/")[0], job
-
-        return None, {}
-
-    def UpdateLeasedJobStatus(self, status, update_interval):
-        """Updates the status of the leased job.
-
-        Args:
-            status: string, status value.
-            update_interval: int, time between heartbeats in second.
-        """
-        if self._job is None:
-            return
-
-        url = self._url + "job/v1/heartbeat"
-        self._job["status"] = JOB_STATUS_DICT[status]
-
-        thread = threading.currentThread()
-        while getattr(thread, 'keep_running', True):
-            try:
-                response = requests.post(url, data=json.dumps(self._job),
-                                         headers=self._headers,
-                                         timeout=REQUESTS_TIMEOUT_SECONDS)
-                if response.status_code != requests.codes.ok:
-                    logging.error("UpdateLeasedJobStatus error: %s", response)
-            except requests.exceptions.Timeout as e:
-                logging.exception(e)
-            time.sleep(update_interval)
-
-    def StartHeartbeat(self, status="leased", update_interval=60):
-        """Starts the hearbeat_thread.
-
-        Args:
-            status: string, status value.
-            update_interval: int, time between heartbeats in second.
-        """
-        if (self._heartbeat_thread is None
-                or hasattr(self._heartbeat_thread, 'keep_running')):
-            self._heartbeat_thread = threading.Thread(
-                target=self.UpdateLeasedJobStatus,
-                args=(
-                    status,
-                    update_interval,
-                ))
-            self._heartbeat_thread.daemon = True
-            self._heartbeat_thread.start()
-
-    def StopHeartbeat(self, status="complete", infra_log_url=""):
-        """Stops the hearbeat_thread and sets current job's status.
-
-        Args:
-            status: string, status value.
-            infra_log_url: string, URL to the uploaded infra log.
-        """
-        self._heartbeat_thread.keep_running = False
-
-        if self._job is None:
-            return
-
-        url = self._url + "job/v1/heartbeat"
-        self.SetJobStatusFromLeasedTo(status)
-        self._job["infra_log_url"] = infra_log_url
-
-        try:
-            response = requests.post(url, data=json.dumps(self._job),
-                                     headers=self._headers,
-                                     timeout=REQUESTS_TIMEOUT_SECONDS)
-            if response.status_code != requests.codes.ok:
-                logging.error("StopHeartbeat error: %s", response)
-        except requests.exceptions.Timeout as e:
-            logging.exception(e)
-
-        self._job = None
-
-    def SetJobStatusFromLeasedTo(self, status):
-        """Sets current job's status only when the job's status is 'leased'.
-
-        Args:
-            status: string, status value.
-        """
-        if (self._job is not None and
-            self._job["status"] == JOB_STATUS_DICT["leased"]):
-            self._job["status"] = JOB_STATUS_DICT[status]
-
-    def UploadHostVersion(self, hostname, vtslab_version):
-        """Uploads vtslab version.
-
-        Args:
-            hostname: string, the name of the host.
-            vtslab_version: string, current version of vtslab package.
-        """
-        url = self._url + "lab/v1/set_version"
-        host = {}
-        host["hostname"] = hostname
-        host["vtslab_version"] = vtslab_version
-
-        try:
-            response = requests.post(url, data=json.dumps(host),
-                                     headers=self._headers,
-                                     timeout=REQUESTS_TIMEOUT_SECONDS)
-        except (requests.exceptions.ConnectionError,
-                requests.exceptions.Timeout) as e:
-            logging.exception(e)
-            return
-        if response.status_code != requests.codes.ok:
-            logging.error("UploadHostVersion error: %s", response)
-
-    def CheckBootUpStatus(self):
-        """Checks whether the device_img + gsi from the job fails to boot up.
-
-        Returns:
-            True if the devices flashed with the given imgs from the leased job
-            succeed to boot up. False otherwise.
-        """
-        if self._job:
-            return (self._job["status"] != JOB_STATUS_DICT["bootup-err"])
-        return False
-
-    def GetJobTestType(self):
-        """Returns the test type of the leased job.
-
-        Returns:
-            int, test_type attr in the job message. 0 when there is no job
-            leased to this vti_endpoint_client.
-        """
-        if self._job and "test_type" in self._job:
-            try:
-                return int(self._job["test_type"])
-            except ValueError as e:
-                logging.exception(e)
-        return 0
-
-    def GetJobDeviceProductName(self):
-        """Returns the product name of the DUTs of the leased job.
-
-        Returns:
-            string, product name. An empty string if there is no job leased or
-            "device" attr of the job obj is not well formatted.
-        """
-        if self._job and "device" in self._job:
-            try:
-                return self._job["device"].split("/")[1]
-            except IndexError as e:
-                logging.exception(e)
-        return ""
diff --git a/host_setup/fabfile.py b/host_setup/fabfile.py
deleted file mode 100644
index d37bb58..0000000
--- a/host_setup/fabfile.py
+++ /dev/null
@@ -1,386 +0,0 @@
-#
-# Copyright 2018 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import imp
-import os
-import sys
-import time
-
-from fabric.api import env
-from fabric.api import local
-from fabric.api import run
-from fabric.api import settings
-from fabric.api import sudo
-from fabric.contrib.files import contains
-from fabric.contrib.files import exists
-from fabric.context_managers import cd
-
-_PIP_REQUIREMENTS_PATHS = [
-    "test/vts/script/pip_requirements.txt",
-    "test/framework/harnesses/host_controller/script/pip_requirements.txt"
-]
-
-# Path to the file that contains the abs path to the deployed vtslab pakcage.
-_VTSLAB_PACKAGE_PATH_FILENAME = ".vtslab_package_path"
-
-# Zone filter list for GCE instances.
-_DEFAULT_GCE_ZONE_LIST = [
-    "us-east1-b",
-    "asia-northeast1-a",
-]
-
-
-def SetPassword(password):
-    """Sets password for hosts to access through ssh and to run sudo commands
-
-    usage: $ fab SetPassword:<password for hosts>
-
-    Args:
-        password: string, password for hosts.
-    """
-    env.password = password
-
-
-def GetHosts(hosts_file_path, gce_instance_name=None, account=None):
-    """Configures env.hosts to a given list of hosts.
-
-    usage: $ fab GetHosts:<path to a source file contains hosts info>
-
-    Args:
-        hosts_file_path: string, path to a python file passed from command file
-                         input.
-        gce_instance_name: string, GCE instance name.
-        account: string, account name used for the ssh connection.
-    """
-    if hosts_file_path.endswith(".py"):
-        hosts_module = imp.load_source('hosts_module', hosts_file_path)
-        env.hosts = hosts_module.EmitHostList()
-    else:
-        if not gce_instance_name or not account:
-            print(
-                "Please specify gce_instance_name and account using -H option. "
-                "Example: -H <Google_Cloud_project>,<GCE_instance>,<account>")
-            sys.exit(0)
-        env.key_filename = "~/.ssh/google_compute_engine"
-        gce_list_out = local(
-            "gcloud compute instances list --project=%s --filter=\"zone:(%s)\""
-            % (hosts_file_path, " ".join(_DEFAULT_GCE_ZONE_LIST)),
-            capture=True)
-        for line in gce_list_out.split("\n")[1:]:
-            if line.startswith(gce_instance_name):
-                env.hosts.append("%s@%s" % (account, line.strip().split()[-2]))
-
-
-def SetupIptables(ip_address_file_path):
-    """Configures iptables setting for all hosts listed.
-
-    usage: $ fab SetupIptables:<path to a source file contains ip addresses of
-             certified machines>
-
-    Args:
-        ip_address_file_path: string, path to a python file passed from command
-                              file input.
-    """
-    ip_addresses_module = imp.load_source('ip_addresses_module',
-                                          ip_address_file_path)
-    ip_address_list = ip_addresses_module.EmitIPAddressList()
-
-    sudo("apt-get install -y iptables-persistent")
-    sudo("iptables -P INPUT ACCEPT")
-    sudo("iptables -P FORWARD ACCEPT")
-    sudo("iptables -F")
-
-    for ip_address in ip_address_list:
-        sudo(
-            "iptables -A INPUT -p tcp -s %s --dport 22 -j ACCEPT" % ip_address)
-
-    sudo("iptables -P INPUT DROP")
-    sudo("iptables -P FORWARD DROP")
-    sudo("iptables -A INPUT -p icmp -j ACCEPT")
-    sudo("netfilter-persistent save")
-    sudo("netfilter-persistent reload")
-
-
-def SetupSudoers():
-    """Append sudo rules for vtslab user.
-
-    usage: $ fab SetupSudoers
-    """
-    if not contains("/etc/sudoers", "vtslab", use_sudo=True):
-        sudo("echo '' | sudo tee -a /etc/sudoers")
-        sudo("echo '# Let vtslab account have all authorization' | "
-             "sudo tee -a /etc/sudoers")
-        sudo("echo 'vtslab  ALL=(ALL:ALL) ALL' | sudo tee -a /etc/sudoers")
-
-
-def SetupUSBPermission():
-    """Sets up the USB permission for adb and fastboot.
-
-    usage: $ fab SetupUSBPermission
-    """
-    sudo("curl --create-dirs -L -o /etc/udev/rules.d/51-android.rules -O -L "
-         "https://raw.githubusercontent.com/snowdream/51-android/master/"
-         "51-android.rules")
-    sudo("chmod a+r /etc/udev/rules.d/51-android.rules")
-    sudo("service udev restart")
-
-
-def SetupADBVendorKeysEnvVar():
-    """Appends scripts for ADB_VENDOR_KEYS path setup.
-
-    In setup step, this function looks into .bashrc file for this script, and
-    if there is not then appends the below scripts to .bashrc.
-    Later when shell env created (through ssh or screen instance creation time),
-    .bashrc file will look for _VTSLAB_PACKAGE_PATH_FILENAME and use the
-    contents of the file to set ADB_VENDOR_KEYS.
-
-    usage: $ fab SetupADBVendorKeysEnvVar
-    """
-    if not contains("~/.bashrc", _VTSLAB_PACKAGE_PATH_FILENAME):
-        run("echo '' >> ~/.bashrc", )
-        run("echo '# Set $ADB_VENDOR_KEYS as paths to adb private key files "
-            "within the vtslab-package' >> ~/.bashrc")
-        run("echo 'if [ -f ~/%s ]; then' >> ~/.bashrc" %
-            _VTSLAB_PACKAGE_PATH_FILENAME)
-        run("echo '  export ADB_VENDOR_KEYS=$(find $(cat ~/%s)/android-vtslab/"
-            "testcases/DATA/ak -name \".*.ak\" | tr \"\\n\" \":\")' "
-            ">> ~/.bashrc" % _VTSLAB_PACKAGE_PATH_FILENAME)
-        run("echo 'fi' >> ~/.bashrc")
-
-
-def _CheckADBVendorKeysEnvVar(vtslab_package_file_name=""):
-    """Checks if there is a change in ADB_VENDOR_KEYS env variable.
-
-    if there is, then the adbd needs to be restarted in the screen context
-    before running the HC.
-
-    Args:
-        vtslab_package_file_name: string, the HC package file name that is about
-                                  to be deployed.
-
-    Returns:
-        True if the list of the adb vendor key files have changed,
-        False otherwise.
-    """
-    former_key_set = set()
-    current_key_set = set()
-    set_keyfile_set = lambda set, path_list: map(set.add, map(os.path.basename,
-                                                              path_list))
-    vtslab_package_path_filepath = "~/%s" % _VTSLAB_PACKAGE_PATH_FILENAME
-
-    if exists(vtslab_package_path_filepath):
-        former_HC_package_path = run("cat %s" % vtslab_package_path_filepath)
-        former_HC_package_adbkey_path = os.path.join(
-            former_HC_package_path, "android-vtslab/testcases/DATA/ak")
-        if exists(former_HC_package_adbkey_path):
-            adb_vendor_keys_list = run("find %s -name \".*.ak\"" %
-                                       former_HC_package_adbkey_path).split()
-            set_keyfile_set(former_key_set, adb_vendor_keys_list)
-
-    if exists("~/run/%s.dir/android-vtslab/testcases/DATA/ak" %
-              vtslab_package_file_name):
-        adb_vendor_keys_list = run(
-            "find ~/run/%s.dir/android-vtslab/testcases/DATA/ak -name \".*.ak\""
-            % vtslab_package_file_name).split()
-        set_keyfile_set(current_key_set, adb_vendor_keys_list)
-
-    return former_key_set != current_key_set
-
-
-def SetupPackages(ip_address_file_path=None):
-    """Sets up the execution environment for vts `run` command.
-
-    Need to temporarily open the ports for apt-get and pip commands.
-
-    usage: $ fab SetupPackages
-
-    Args:
-        ip_address_file_path: string, path to a python file passed from command
-                              file input. Will be passed to SetupIptables().
-    """
-    sudo("iptables -P INPUT ACCEPT")
-
-    # todo : replace "kr.ubuntu." to "ubuntu" in /etc/apt/sources.list
-    sudo("apt-get upgrade -y")
-    sudo("apt-get update -y")
-    sudo("apt-get install -y git-core gnupg flex bison gperf build-essential "
-         "zip curl zlib1g-dev gcc-multilib g++-multilib x11proto-core-dev "
-         "libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc "
-         "unzip liblz4-tool udev screen")
-
-    sudo("apt-get install -y android-tools-adb")
-    sudo("usermod -aG plugdev $LOGNAME")
-
-    SetupUSBPermission()
-
-    sudo("apt-get update")
-    sudo("apt-get install -y python2.7")
-    sudo("apt-get install -y python-pip")
-    run("pip install --upgrade pip")
-    sudo("apt-get install -y python-virtualenv")
-
-    sudo("apt-get install -y python-dev python-protobuf protobuf-compiler "
-         "python-setuptools")
-
-    for req_path in _PIP_REQUIREMENTS_PATHS:
-        full_path = os.path.join(os.environ["ANDROID_BUILD_TOP"], req_path)
-        pip_requirement_list = []
-        try:
-            requirements_fd = open(full_path, "r")
-            lines = requirements_fd.readlines()
-            for line in lines:
-                req = line.rstrip()
-                if req != "" and not req.startswith("#"):
-                    pip_requirement_list.append(req)
-        except IOError as e:
-            print("%s: %s" % (e.strerror, full_path))
-            return
-        sudo("pip install %s" % " ".join(pip_requirement_list))
-
-    sudo("pip install --upgrade protobuf")
-
-    lsb_result = run("lsb_release -c -s")
-    sudo("echo \"deb http://packages.cloud.google.com/apt cloud-sdk-%s "
-         "main\" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list" %
-         lsb_result)
-    sudo("curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | "
-         "sudo apt-key add -")
-    sudo("apt-get update && sudo apt-get install -y google-cloud-sdk")
-    sudo("apt-get install -y google-cloud-sdk-app-engine-java "
-         "google-cloud-sdk-app-engine-python kubectl")
-
-    sudo("apt-get install -y m4 bison")
-
-    if ip_address_file_path is not None:
-        SetupIptables(ip_address_file_path)
-
-    SetupADBVendorKeysEnvVar()
-
-
-def DeployVtslab(vtslab_package_gcs_url=None):
-    """Deploys vtslab package.
-
-    Fetches and deploy vtslab by going through the processes described below
-    1. Send the "exit --wait_for_jobs=True" command to all detached screen.
-       And let the screen to terminate itself.
-    2. Create a new screen instance that downloads and runs the new HC,
-       give password and device command to the HC without actually attaching it
-
-    usage: $ fab DeployVtslab -p <password> -H hosts.py -f <gs://vtslab-release/...>
-
-    Args:
-        vtslab_package_gcs_url: string, URL to a certain vtslab package file.
-    """
-    if not vtslab_package_gcs_url:
-        print("Please specify vtslab package file URL using -f option.")
-        return
-    elif not vtslab_package_gcs_url.startswith("gs://vtslab-release/"):
-        print("Please spcify a valid URL for the vtslab package.")
-        return
-    else:
-        vti = "vtslab-schedule-" + vtslab_package_gcs_url[len(
-            "gs://vtslab-release/"):].split("/")[0] + ".appspot.com"
-    with settings(warn_only=True):
-        screen_list_result = run("screen -list")
-    lines = screen_list_result.split("\n")
-    for line in lines:
-        if "(Detached)" in line:
-            screen_name = line.split("\t")[1]
-            print(screen_name)
-            with settings(warn_only=True):
-                run("screen -S %s -X stuff \"exit --wait_for_jobs=True\"" %
-                    screen_name)
-                run("screen -S %s -X stuff \"^M\"" % screen_name)
-                run("screen -S %s -X stuff \"exit\"" % screen_name)
-                run("screen -S %s -X stuff \"^M\"" % screen_name)
-
-    vtslab_package_file_name = os.path.basename(vtslab_package_gcs_url)
-    run("mkdir -p ~/run/%s.dir/" % vtslab_package_file_name)
-    with cd("~/run/%s.dir" % vtslab_package_file_name):
-        run("gsutil cp %s ./" % vtslab_package_gcs_url)
-        run("unzip -o %s" % vtslab_package_file_name)
-        adb_vendor_keys_changed = _CheckADBVendorKeysEnvVar(
-            vtslab_package_file_name)
-        run("pwd > ~/%s" % _VTSLAB_PACKAGE_PATH_FILENAME)
-
-    with cd("~/run/%s.dir/android-vtslab/tools" % vtslab_package_file_name):
-        new_screen_name = run("cat ../testcases/version.txt")
-
-    with cd("~/run/%s.dir/android-vtslab/tools" % vtslab_package_file_name):
-        run("./make_screen %s ; sleep 1" % new_screen_name)
-
-    if adb_vendor_keys_changed:
-        reset_adbd = ""
-        while reset_adbd.lower() not in ["y", "n"]:
-            if reset_adbd:
-                print("Please type 'y' or 'n'")
-            reset_adbd = raw_input(
-                "Reset adb server daemon on host %s (y/n)? " % env.host)
-        if reset_adbd.lower() == "y":
-            run("screen -S %s -X stuff \"adb kill-server^M\"" %
-                new_screen_name)
-            run("screen -S %s -X stuff \"adb start-server^M\"" %
-                new_screen_name)
-    run("screen -S %s -X stuff \"./run --vti=%s\"" % (new_screen_name, vti))
-    run("screen -S %s -X stuff \"^M\"" % new_screen_name)
-    time.sleep(5)
-    run("screen -S %s -X stuff \"password\"" % new_screen_name)
-    run("screen -S %s -X stuff \"^M\"" % new_screen_name)
-    run("screen -S %s -X stuff \"%s\"" % (new_screen_name, env.password))
-    run("screen -S %s -X stuff \"^M\"" % new_screen_name)
-    run("screen -S %s -X stuff \"device --lease=True\"" % new_screen_name)
-    run("screen -S %s -X stuff \"^M\"" % new_screen_name)
-
-    with cd("~/run/%s.dir" % vtslab_package_file_name):
-        run("rm %s" % vtslab_package_file_name)
-
-
-def DeployGCE(vtslab_package_gcs_url=None):
-    """Deploys a vtslab package to GCE nodes.
-
-    Fetches and deploy vtslab on monitor-hc by doing;
-    1. Download android-vtslab-<>.zip from GCS using the given URL and upzip it.
-    2. Send the Ctrl-c key input to all detached screen, then cursor-up
-       key input and enter key input, making the screen to execute
-       the last run command.
-
-    usage: $ fab DeployVtslab -p <password> -H <Google Cloud Platform project name> -f <gs://vtslab-release/...>
-
-    Args:
-        vtslab_package_gcs_url: string, URL to a certain vtslab package file.
-    """
-    if not vtslab_package_gcs_url:
-        print("Please specify vtslab package file URL using -f option.")
-        return
-    elif not vtslab_package_gcs_url.startswith("gs://"):
-        print("Please spcify a valid URL for the vtslab package.")
-        return
-
-    vtslab_package_file_name = os.path.basename(vtslab_package_gcs_url)
-    with cd("~/run"):
-        run("gsutil cp %s ./" % vtslab_package_gcs_url)
-        run("unzip -o %s" % vtslab_package_file_name)
-        run("rm %s" % vtslab_package_file_name)
-
-    with settings(warn_only=True):
-        screen_list_result = run("screen -list")
-    lines = screen_list_result.split("\n")
-    for line in lines:
-        if "(Detached)" in line:
-            screen_name = line.split("\t")[1]
-            run("screen -S %s -X stuff \"^C\"" % screen_name)
-            run("screen -S %s -X stuff \"\033[A\"" % screen_name)
-            run("screen -S %s -X stuff \"^M\"" % screen_name)
diff --git a/host_setup/host_setup.sh b/host_setup/host_setup.sh
deleted file mode 100755
index fa52755..0000000
--- a/host_setup/host_setup.sh
+++ /dev/null
@@ -1,96 +0,0 @@
-#/bin/bash
-#
-# Copyright 2018 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-SCRIPT_NAME=$(basename $0)
-usage()
-{
-  echo "Usage: $SCRIPT_NAME <task_name> [options]"
-  echo ""
-  echo "Options:"
-  echo "  -p PASSWORD         password for hosts."
-  echo "  -H PATH             path to a .py file contains hosts information"
-  echo "  -i PATH             path to a .py file contains ip address information of certified machines"
-  echo "  -f GCS_URL          URL to the vtslab package file to be deployed."
-  exit 1
-}
-
-FABRIC_EXISTS=$(pip show fabric)
-if [ -z "$FABRIC_EXISTS" ]; then
-  INSTALL_FABRIC=true
-else
-  FABRIC_VERSION=$(fab -V | grep Fabric)
-  if [ "${FABRIC_VERSION:7:1}" -ne 1 ]; then
-    INSTALL_FABRIC=true
-  fi
-fi
-if [ "$INSTALL_FABRIC" == true ]; then
-  sudo pip install fabric==1.14.0 --force
-fi
-
-TASK=$1
-if [[ ${TASK:0:1} == "-" ]]; then
-  usage
-fi
-
-shift
-PASSWORD=""
-HOSTS_PATH="hosts.py"
-IPADDRESSES_PATH=""
-VTSLAB_PACKAGE_GCS_URL=""
-
-while getopts ":p:H:i:f:" opt; do
-  case $opt in
-    p)
-      PASSWORD=$OPTARG
-      ;;
-    H)
-      HOSTS_PATH=$OPTARG
-      ;;
-    i)
-      IPADDRESSES_PATH=$OPTARG
-      ;;
-    f)
-      VTSLAB_PACKAGE_GCS_URL=$OPTARG
-      ;;
-    \?)
-      echo "Invalid option: -$OPTARG"
-      usage
-      ;;
-    :)
-      echo "Option -$OPTARG requires an argument."
-      usage
-      ;;
-  esac
-done
-
-if [ "$TASK" == "SetupIptables" ]; then
-  fab SetPassword:$PASSWORD GetHosts:$HOSTS_PATH $TASK:$IPADDRESSES_PATH
-elif [ "$TASK" == "SetupPackages" ]; then
-  if [ -z "$IPADDRESSES_PATH" ]; then
-    fab SetPassword:$PASSWORD GetHosts:$HOSTS_PATH $TASK
-  else
-    fab SetPassword:$PASSWORD GetHosts:$HOSTS_PATH $TASK:$IPADDRESSES_PATH
-  fi
-elif [ "$TASK" == "DeployVtslab" ] || [ "$TASK" == "DeployGCE" ]; then
-  if [ -z "$VTSLAB_PACKAGE_GCS_URL" ]; then
-    echo "Please specify vtslab package file URL using -f option."
-    exit
-  fi
-  fab SetPassword:$PASSWORD GetHosts:$HOSTS_PATH $TASK:$VTSLAB_PACKAGE_GCS_URL
-else
-  fab SetPassword:$PASSWORD GetHosts:$HOSTS_PATH $TASK
-fi
diff --git a/script/run-unittest.sh b/script/run-unittest.sh
deleted file mode 100755
index fb4fca0..0000000
--- a/script/run-unittest.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-TEST_FRAMEWORK_DIR=`dirname $0`
-TEST_FRAMEWORK_DIR=`dirname $TEST_FRAMEWORK_DIR`
-
-if [ -z "$ANDROID_BUILD_TOP" ]; then
-    echo "Missing ANDROID_BUILD_TOP env variable. Run 'lunch' first."
-    exit 1
-fi
-
-touch $ANDROID_BUILD_TOP/test/vti/__init__.py
-
-avoid_list=(
-  # known failures
-  "./harnesses/host_controller/console_test.py"
-  "./harnesses/host_controller/invocation_thread_test.py"
-  # not unit tests
-  "./harnesses/host_controller/command_processor/command_test.py"
-  )
-
-#######################################
-# Checks if a given file is included in the list of files to avoid
-# Globals:
-# Arguments:
-#   $1: list of files to avoid
-#   $2: the given file
-# Returns:
-#   SUCCESS, if the given file exists in the list
-#   FAILURE, otherwise
-#######################################
-function contains_file() {
-  local -n arr=$1
-  for avoid in "${arr[@]}"; do
-    if [ "$2" = "$avoid" ]; then
-      return  # contains
-    fi
-  done
-  false  # not contains
-}
-
-# Runs all unit tests under test/framework.
-for t in $(find $TEST_FRAMEWORK_DIR -type f -name "*_test.py");
-do
-    if contains_file avoid_list $t; then
-        continue
-    fi
-    echo "UNIT TEST", $t
-    echo PYTHONPATH=$ANDROID_BUILD_TOP/test/framework/harnesses:$ANDROID_BUILD_TOP/test python $t;
-    PYTHONPATH=$ANDROID_BUILD_TOP/test/framework/harnesses:$ANDROID_BUILD_TOP/test python $t;
-done
diff --git a/tools/host_controller/Android.bp b/tools/host_controller/Android.bp
deleted file mode 100644
index 174ac4a..0000000
--- a/tools/host_controller/Android.bp
+++ /dev/null
@@ -1,18 +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.
-
-sh_binary_host {
-    name: "run",
-    src: "run",
-}
diff --git a/tools/host_controller/make_screen b/tools/host_controller/make_screen
deleted file mode 100755
index 10aed5d..0000000
--- a/tools/host_controller/make_screen
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-# 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.
-
-# Sets env var PATH and makes a detached screen instance
-pushd ../bin
-export PATH=`pwd`:$PATH
-popd
-screen -mdS $1
diff --git a/tools/host_controller/run b/tools/host_controller/run
deleted file mode 100755
index 43b3707..0000000
--- a/tools/host_controller/run
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-# 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.
-
-# launcher script for vts-hc (host controller)
-# can be used from an Android build environment, or a standalone vts zip
-
-# get OS
-HOST=`uname`
-if [ "$HOST" == "Linux" ]; then
-    OS="linux-x86"
-elif [ "$HOST" == "Darwin" ]; then
-    OS="darwin-x86"
-else
-    echo "Unrecognized OS"
-    exit
-fi
-
-# check if in Android build env
-if [ ! -z "${ANDROID_BUILD_TOP}" ]; then
-    if [ ! -z "${ANDROID_HOST_OUT}" ]; then
-        VTS_ROOT=${ANDROID_HOST_OUT}/vtslab
-    else
-        VTS_ROOT=${ANDROID_BUILD_TOP}/${OUT_DIR:-out}/host/${OS}/vtslab
-    fi
-    if [ ! -d ${VTS_ROOT} ]; then
-        echo "Could not find $VTS_ROOT in Android build environment. Try 'make vts'"
-        exit
-    fi;
-fi;
-
-if [ -z ${VTS_ROOT} ]; then
-    # assume we're in an extracted vts install
-    VTS_ROOT="$(dirname $(readlink -e $0))/../.."
-fi;
-
-find ${VTS_ROOT} -name "*.pyc" -exec rm -f {} \;
-cd ${VTS_ROOT}/android-vtslab/testcases/; python -m host_controller.main "$@"