Merge "ltp tests emit skip if filtered out"
diff --git a/agents/hal/AgentRequestHandler.cpp b/agents/hal/AgentRequestHandler.cpp
index 457e18f..d4d8bb7 100644
--- a/agents/hal/AgentRequestHandler.cpp
+++ b/agents/hal/AgentRequestHandler.cpp
@@ -138,7 +138,7 @@
       Close();
 
       string driver_binary_path;
-      char* cmd;
+      char* cmd = NULL;
       if (driver_type == VTS_DRIVER_TYPE_HAL_CONVENTIONAL ||
           driver_type == VTS_DRIVER_TYPE_HAL_LEGACY ||
           driver_type == VTS_DRIVER_TYPE_HAL_HIDL) {
diff --git a/agents/hal/AgentRequestHandler.h b/agents/hal/AgentRequestHandler.h
index 8e7a36a..229f1a1 100644
--- a/agents/hal/AgentRequestHandler.h
+++ b/agents/hal/AgentRequestHandler.h
@@ -38,14 +38,15 @@
   AgentRequestHandler(const char* spec_dir_path, const char* hal_path32,
                       const char* hal_path64, const char* shell_path32,
                       const char* shell_path64)
-      : service_name_(),
+      : VtsDriverCommUtil(),
+        service_name_(),
         driver_client_(NULL),
         driver_hal_spec_dir_path_(spec_dir_path),
         driver_hal_binary32_(hal_path32),
         driver_hal_binary64_(hal_path64),
         driver_shell_binary32_(shell_path32),
-        driver_shell_binary64_(shell_path64),
-        VtsDriverCommUtil() {}
+        driver_shell_binary64_(shell_path64) {}
+
 
   // handles a new session.
   bool ProcessOneCommand();
diff --git a/agents/hal/Android.mk b/agents/hal/Android.mk
index 4ba33a0..ea137ff 100644
--- a/agents/hal/Android.mk
+++ b/agents/hal/Android.mk
@@ -23,6 +23,8 @@
 LOCAL_MODULE_STEM_32 := vts_hal_agent32
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_CFLAGS += -Wall -Werror
+
 LOCAL_SRC_FILES := \
   VtsAgentMain.cpp \
   TcpServerForRunner.cpp \
diff --git a/agents/hal/SocketClientToDriver.cpp b/agents/hal/SocketClientToDriver.cpp
index 188db3e..90d85f0 100644
--- a/agents/hal/SocketClientToDriver.cpp
+++ b/agents/hal/SocketClientToDriver.cpp
@@ -189,10 +189,10 @@
   VtsDriverControlCommandMessage command_message;
   command_message.set_command_type(CALL_FUNCTION);
   command_message.set_status_type(type);
-  if (!VtsSocketSendMessage(command_message)) return NULL;
+  if (!VtsSocketSendMessage(command_message)) return 0;
 
   VtsDriverControlResponseMessage response_message;
-  if (!VtsSocketRecvMessage(&response_message)) return NULL;
+  if (!VtsSocketRecvMessage(&response_message)) return 0;
   return response_message.return_value();
 }
 
diff --git a/agents/hal/SocketServerForDriver.h b/agents/hal/SocketServerForDriver.h
index 027357c..4b3db3a 100644
--- a/agents/hal/SocketServerForDriver.h
+++ b/agents/hal/SocketServerForDriver.h
@@ -32,8 +32,8 @@
 class SocketServerForDriver : public VtsDriverCommUtil {
  public:
   SocketServerForDriver(int sock, int runner_port)
-      : runner_port_(runner_port),
-        VtsDriverCommUtil(sock) {}
+      : VtsDriverCommUtil(sock),
+        runner_port_(runner_port) {}
 
   // Starts to process requests.
   void Start();
diff --git a/agents/hal/VtsAgentMain.cpp b/agents/hal/VtsAgentMain.cpp
index 488bcf3..2df0ffe 100644
--- a/agents/hal/VtsAgentMain.cpp
+++ b/agents/hal/VtsAgentMain.cpp
@@ -37,16 +37,16 @@
   printf("|| VTS AGENT ||\n");
 
   if (argc == 1) {
-    hal_path32 = DEFAULT_HAL_DRIVER_FILE_PATH32;
-    hal_path64 = DEFAULT_HAL_DRIVER_FILE_PATH64;
-    shell_path32 = DEFAULT_SHELL_DRIVER_FILE_PATH32;
-    shell_path64 = DEFAULT_SHELL_DRIVER_FILE_PATH64;
+    hal_path32 = (char*) DEFAULT_HAL_DRIVER_FILE_PATH32;
+    hal_path64 = (char*) DEFAULT_HAL_DRIVER_FILE_PATH64;
+    shell_path32 = (char*) DEFAULT_SHELL_DRIVER_FILE_PATH32;
+    shell_path64 = (char*) DEFAULT_SHELL_DRIVER_FILE_PATH64;
   } else if (argc == 2) {
-    hal_path32 = DEFAULT_HAL_DRIVER_FILE_PATH32;
-    hal_path64 = DEFAULT_HAL_DRIVER_FILE_PATH64;
+    hal_path32 = (char*) DEFAULT_HAL_DRIVER_FILE_PATH32;
+    hal_path64 = (char*) DEFAULT_HAL_DRIVER_FILE_PATH64;
     spec_dir_path = argv[1];
-    shell_path32 = DEFAULT_SHELL_DRIVER_FILE_PATH32;
-    shell_path64 = DEFAULT_SHELL_DRIVER_FILE_PATH64;
+    shell_path32 = (char*) DEFAULT_SHELL_DRIVER_FILE_PATH32;
+    shell_path64 = (char*) DEFAULT_SHELL_DRIVER_FILE_PATH64;
   } else if (argc == 3) {
     hal_path32 = argv[1];
     hal_path64 = argv[2];
diff --git a/doc/testcase_develop_manual/codelab_host_driven_test.md b/doc/testcase_develop_manual/codelab_host_driven_test.md
index a6875ed..f8ea23f 100644
--- a/doc/testcase_develop_manual/codelab_host_driven_test.md
+++ b/doc/testcase_develop_manual/codelab_host_driven_test.md
@@ -174,6 +174,12 @@
 The exact schedule, and the used branches and devices are all customizable.
 Please contact an EngProd representative to your team, or vts-dev@google.com.
 
+Results from the test lab are automatically visible on the dashboard, but local
+runs may also be visible for debugging purposes if tests are run on a machine
+with access to the database service key file. To view local runs on the dashboard
+for debugging purposes, add the following to the end of the URL from the table
+summary page: '&unfiltered='.
+
 ## 5. Notifications
 
 For notifications when test cases fail, go to the VTS dashboard and click the
diff --git a/drivers/libprofiling/Android.mk b/drivers/libprofiling/Android.mk
index bc8dedc..a6486bf 100644
--- a/drivers/libprofiling/Android.mk
+++ b/drivers/libprofiling/Android.mk
@@ -32,6 +32,8 @@
 LOCAL_SHARED_LIBRARIES := \
   libbase \
   libcutils \
+  libhidl \
+  libhwbinder \
   libvts_multidevice_proto \
   libprotobuf-cpp-full \
 
diff --git a/drivers/libprofiling/VtsProfilingInterface.cpp b/drivers/libprofiling/VtsProfilingInterface.cpp
index bd2ad76..5520f6d 100644
--- a/drivers/libprofiling/VtsProfilingInterface.cpp
+++ b/drivers/libprofiling/VtsProfilingInterface.cpp
@@ -15,6 +15,7 @@
  */
 #include "VtsProfilingInterface.h"
 
+#include <cutils/properties.h>
 #include <fstream>
 #include <string>
 
@@ -58,8 +59,19 @@
 
 void VtsProfilingInterface::Init() {
   if (initialized_) return;
-  // Attach timestamp for the trace file.
-  string file_path = trace_file_path_ + "_" + to_string(NanoTime());
+
+  // Attach device info and timestamp for the trace file.
+  char build_number[PROPERTY_VALUE_MAX];
+  char device_id[PROPERTY_VALUE_MAX];
+  char product_name[PROPERTY_VALUE_MAX];
+  property_get("ro.build.version.incremental", build_number, "unknown_build");
+  property_get("ro.serialno", device_id, "unknown_device");
+  property_get("ro.build.product", product_name, "unknown_product");
+
+  string file_path = trace_file_path_ + "_" + string(product_name) + "_"
+      + string(device_id) + "_" + string(build_number) + "_"
+      + to_string(NanoTime()) + ".vts.trace";
+
   LOG(INFO) << "Creating new profiler instance with file path: " << file_path;
   trace_output_ = std::ofstream(file_path, std::fstream::out);
   if (!trace_output_) {
@@ -69,8 +81,9 @@
   initialized_ = true;
 }
 
-bool VtsProfilingInterface::AddTraceEvent(const char* package,
-    const char* version, const char* interface,
+bool VtsProfilingInterface::AddTraceEvent(
+    android::hardware::HidlInstrumentor::InstrumentationEvent event,
+    const char* package, const char* version, const char* interface,
     const FunctionSpecificationMessage& message) {
   if (!initialized_) {
     LOG(ERROR) << "Profiler not initialized. ";
@@ -84,9 +97,10 @@
 
   mutex_.lock();
   // Record the event data with the following format:
-  // timestamp,package_name,package_version,interface_name,message
-  trace_output_ << NanoTime() << "," << package << "," << version << ","
-                << interface << "," << msg_str << "\n";
+  // timestamp,event,package_name,package_version,interface_name,message
+  trace_output_ << NanoTime() << "," << event << "," << package << ","
+                << version << "," << interface << "," << message.name() << "\n";
+  trace_output_ << msg_str << "\n";
   trace_output_.flush();
   mutex_.unlock();
 
diff --git a/drivers/libprofiling/VtsProfilingInterface.h b/drivers/libprofiling/VtsProfilingInterface.h
index 5636a26..a0c5950 100644
--- a/drivers/libprofiling/VtsProfilingInterface.h
+++ b/drivers/libprofiling/VtsProfilingInterface.h
@@ -19,6 +19,7 @@
 
 #include <android-base/macros.h>
 #include <fstream>
+#include <hidl/HidlSupport.h>
 #include <utils/Condition.h>
 
 #include "test/vts/proto/ComponentSpecificationMessage.pb.h"
@@ -49,8 +50,9 @@
   static VtsProfilingInterface& getInstance(const string& trace_file_path);
 
   // returns true if the given message is added to the tracing queue.
-  bool AddTraceEvent(const char* package, const char* version,
-      const char* interface, const FunctionSpecificationMessage& message);
+  bool AddTraceEvent(android::hardware::HidlInstrumentor::InstrumentationEvent event,
+      const char* package, const char* version, const char* interface,
+      const FunctionSpecificationMessage& message);
 
  private:
   string trace_file_path_;  // Path of the trace file.
diff --git a/proto/ComponentSpecificationMessage.proto b/proto/ComponentSpecificationMessage.proto
index d6bb167..67a59a4 100644
--- a/proto/ComponentSpecificationMessage.proto
+++ b/proto/ComponentSpecificationMessage.proto
@@ -100,6 +100,7 @@
   TYPE_HIDL_CALLBACK = 10;
   TYPE_SUBMODULE = 11;
   TYPE_UNION = 12;
+  TYPE_HIDL_INTERFACE = 13;
 }
 
 
diff --git a/proto/ComponentSpecificationMessage_pb2.py b/proto/ComponentSpecificationMessage_pb2.py
index 183ff9a..f0da807 100644
--- a/proto/ComponentSpecificationMessage_pb2.py
+++ b/proto/ComponentSpecificationMessage_pb2.py
@@ -14,7 +14,7 @@
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='ComponentSpecificationMessage.proto',
   package='android.vts',
-  serialized_pb='\n#ComponentSpecificationMessage.proto\x12\x0b\x61ndroid.vts\"e\n\x1c\x43\x61llFlowSpecificationMessage\x12\x14\n\x05\x65ntry\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04\x65xit\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x0c\n\x04next\x18\x0b \x03(\x0c\x12\x0c\n\x04prev\x18\x0c \x03(\x0c\"C\n NativeCodeCoverageRawDataMessage\x12\x11\n\tfile_path\x18\x01 \x01(\x0c\x12\x0c\n\x04gcda\x18\x0b \x01(\x0c\"\xa3\x05\n\x1c\x46unctionSpecificationMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\x16\n\x0esubmodule_name\x18\x02 \x01(\x0c\x12>\n\x0breturn_type\x18\x0b \x01(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x43\n\x10return_type_hidl\x18\x0c \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12N\n\x1areturn_type_submodule_spec\x18\r \x01(\x0b\x32*.android.vts.ComponentSpecificationMessage\x12\x36\n\x03\x61rg\x18\x15 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12;\n\x08\x63\x61llflow\x18\x1f \x03(\x0b\x32).android.vts.CallFlowSpecificationMessage\x12\x13\n\x0bis_callback\x18) \x01(\x08\x12J\n\x10\x66unction_pointer\x18* \x01(\x0b\x32\x30.android.vts.FunctionPointerSpecificationMessage\x12\x16\n\x0eprofiling_data\x18\x65 \x03(\x02\x12 \n\x17processed_coverage_data\x18\xc9\x01 \x03(\r\x12I\n\x11raw_coverage_data\x18\xca\x01 \x03(\x0b\x32-.android.vts.NativeCodeCoverageRawDataMessage\x12\x14\n\x0bparent_path\x18\xad\x02 \x01(\x0c\x12\x17\n\x0esyscall_number\x18\x91\x03 \x01(\r\"\xf5\x02\n\x16ScalarDataValueMessage\x12\x0e\n\x06\x62ool_t\x18\x01 \x01(\x05\x12\x0e\n\x06int8_t\x18\x0b \x01(\x05\x12\x0f\n\x07uint8_t\x18\x0c \x01(\r\x12\x0c\n\x04\x63har\x18\r \x01(\x05\x12\r\n\x05uchar\x18\x0e \x01(\r\x12\x0f\n\x07int16_t\x18\x15 \x01(\x05\x12\x10\n\x08uint16_t\x18\x16 \x01(\r\x12\x0f\n\x07int32_t\x18\x1f \x01(\x05\x12\x10\n\x08uint32_t\x18  \x01(\r\x12\x0f\n\x07int64_t\x18) \x01(\x03\x12\x10\n\x08uint64_t\x18* \x01(\x04\x12\x0f\n\x07\x66loat_t\x18\x65 \x01(\x02\x12\x10\n\x08\x64ouble_t\x18\x66 \x01(\x01\x12\x10\n\x07pointer\x18\xc9\x01 \x01(\r\x12\x0f\n\x06opaque\x18\xca\x01 \x01(\r\x12\x15\n\x0cvoid_pointer\x18\xd3\x01 \x01(\r\x12\x15\n\x0c\x63har_pointer\x18\xd4\x01 \x01(\r\x12\x16\n\ruchar_pointer\x18\xd5\x01 \x01(\r\x12\x18\n\x0fpointer_pointer\x18\xfb\x01 \x01(\r\"\xd1\x01\n#FunctionPointerSpecificationMessage\x12\x15\n\rfunction_name\x18\x01 \x01(\x0c\x12\x0f\n\x07\x61\x64\x64ress\x18\x0b \x01(\r\x12\n\n\x02id\x18\x15 \x01(\x0c\x12\x36\n\x03\x61rg\x18\x65 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12>\n\x0breturn_type\x18o \x01(\x0b\x32).android.vts.VariableSpecificationMessage\"9\n\x16StringDataValueMessage\x12\x0f\n\x07message\x18\x01 \x01(\x0c\x12\x0e\n\x06length\x18\x0b \x01(\r\"z\n\x14\x45numDataValueMessage\x12\x12\n\nenumerator\x18\x01 \x03(\x0c\x12\x39\n\x0cscalar_value\x18\x02 \x03(\x0b\x32#.android.vts.ScalarDataValueMessage\x12\x13\n\x0bscalar_type\x18\x03 \x01(\x0c\"\x8b\x07\n\x1cVariableSpecificationMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\'\n\x04type\x18\x02 \x01(\x0e\x32\x19.android.vts.VariableType\x12\x39\n\x0cscalar_value\x18\x65 \x01(\x0b\x32#.android.vts.ScalarDataValueMessage\x12\x13\n\x0bscalar_type\x18\x66 \x01(\x0c\x12\x39\n\x0cstring_value\x18o \x01(\x0b\x32#.android.vts.StringDataValueMessage\x12\x35\n\nenum_value\x18y \x01(\x0b\x32!.android.vts.EnumDataValueMessage\x12@\n\x0cvector_value\x18\x83\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x14\n\x0bvector_size\x18\x84\x01 \x01(\x05\x12@\n\x0cstruct_value\x18\x8d\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x14\n\x0bstruct_type\x18\x8e\x01 \x01(\x0c\x12>\n\nsub_struct\x18\x8f\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12?\n\x0bunion_value\x18\x97\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x13\n\nunion_type\x18\x98\x01 \x01(\x0c\x12=\n\tsub_union\x18\x99\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x18\n\x0fpredefined_type\x18\xc9\x01 \x01(\x0c\x12K\n\x10\x66unction_pointer\x18\xdd\x01 \x03(\x0b\x32\x30.android.vts.FunctionPointerSpecificationMessage\x12\x1b\n\x12hidl_callback_type\x18\xe7\x01 \x01(\x0c\x12\x17\n\x08is_input\x18\xad\x02 \x01(\x08:\x04true\x12\x19\n\tis_output\x18\xae\x02 \x01(\x08:\x05\x66\x61lse\x12\x18\n\x08is_const\x18\xaf\x02 \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0bis_callback\x18\xb0\x02 \x01(\x08:\x05\x66\x61lse\"\xfb\x01\n\x1aStructSpecificationMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\x19\n\nis_pointer\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x37\n\x03\x61pi\x18\xe9\x07 \x03(\x0b\x32).android.vts.FunctionSpecificationMessage\x12<\n\nsub_struct\x18\xd1\x0f \x03(\x0b\x32\'.android.vts.StructSpecificationMessage\x12=\n\tattribute\x18\xb9\x17 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\"\xd5\x01\n\x1dInterfaceSpecificationMessage\x12\x37\n\x03\x61pi\x18\xd1\x0f \x03(\x0b\x32).android.vts.FunctionSpecificationMessage\x12=\n\tattribute\x18\xb9\x17 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12<\n\nsub_struct\x18\xa1\x1f \x03(\x0b\x32\'.android.vts.StructSpecificationMessage\"\xca\x03\n\x1d\x43omponentSpecificationMessage\x12\x34\n\x0f\x63omponent_class\x18\x01 \x01(\x0e\x32\x1b.android.vts.ComponentClass\x12\x32\n\x0e\x63omponent_type\x18\x02 \x01(\x0e\x32\x1a.android.vts.ComponentType\x12!\n\x16\x63omponent_type_version\x18\x03 \x01(\x02:\x01\x31\x12\x16\n\x0e\x63omponent_name\x18\x04 \x01(\x0c\x12,\n\x0btarget_arch\x18\x05 \x01(\x0e\x32\x17.android.vts.TargetArch\x12\x0f\n\x07package\x18\x0b \x01(\x0c\x12\x0e\n\x06import\x18\x0c \x03(\x0c\x12%\n\x1coriginal_data_structure_name\x18\xe9\x07 \x01(\x0c\x12\x0f\n\x06header\x18\xea\x07 \x03(\x0c\x12>\n\tinterface\x18\xd1\x0f \x01(\x0b\x32*.android.vts.InterfaceSpecificationMessage\x12=\n\tattribute\x18\xb5\x10 \x03(\x0b\x32).android.vts.VariableSpecificationMessage*\xc9\x01\n\x0e\x43omponentClass\x12\x11\n\rUNKNOWN_CLASS\x10\x00\x12\x14\n\x10HAL_CONVENTIONAL\x10\x01\x12\x1e\n\x1aHAL_CONVENTIONAL_SUBMODULE\x10\x02\x12\x0e\n\nHAL_LEGACY\x10\x03\x12\x0c\n\x08HAL_HIDL\x10\x04\x12!\n\x1dHAL_HIDL_WRAPPED_CONVENTIONAL\x10\x05\x12\x0e\n\nLIB_SHARED\x10\x0b\x12\n\n\x06KERNEL\x10\x15\x12\x11\n\rKERNEL_MODULE\x10\x16*\xe3\x01\n\rComponentType\x12\x10\n\x0cUNKNOWN_TYPE\x10\x00\x12\t\n\x05\x41UDIO\x10\x01\x12\n\n\x06\x43\x41MERA\x10\x02\x12\x07\n\x03GPS\x10\x03\x12\t\n\x05LIGHT\x10\x04\x12\x08\n\x04WIFI\x10\x05\x12\n\n\x06MOBILE\x10\x06\x12\r\n\tBLUETOOTH\x10\x07\x12\x07\n\x03NFC\x10\x08\x12\t\n\x05POWER\x10\t\x12\x0c\n\x08MEMTRACK\x10\n\x12\x07\n\x03\x42\x46P\x10\x0b\x12\x10\n\x0b\x42IONIC_LIBM\x10\xe9\x07\x12\x10\n\x0b\x42IONIC_LIBC\x10\xea\x07\x12\x13\n\x0eVNDK_LIBCUTILS\x10\xcd\x08\x12\x0c\n\x07SYSCALL\x10\xd1\x0f*\x87\x02\n\x0cVariableType\x12\x19\n\x15UNKNOWN_VARIABLE_TYPE\x10\x00\x12\x13\n\x0fTYPE_PREDEFINED\x10\x01\x12\x0f\n\x0bTYPE_SCALAR\x10\x02\x12\x0f\n\x0bTYPE_STRING\x10\x03\x12\r\n\tTYPE_ENUM\x10\x04\x12\x0e\n\nTYPE_ARRAY\x10\x05\x12\x0f\n\x0bTYPE_VECTOR\x10\x06\x12\x0f\n\x0bTYPE_STRUCT\x10\x07\x12\x19\n\x15TYPE_FUNCTION_POINTER\x10\x08\x12\r\n\tTYPE_VOID\x10\t\x12\x16\n\x12TYPE_HIDL_CALLBACK\x10\n\x12\x12\n\x0eTYPE_SUBMODULE\x10\x0b\x12\x0e\n\nTYPE_UNION\x10\x0c*Q\n\nTargetArch\x12\x17\n\x13UNKNOWN_TARGET_ARCH\x10\x00\x12\x13\n\x0fTARGET_ARCH_ARM\x10\x01\x12\x15\n\x11TARGET_ARCH_ARM64\x10\x02')
+  serialized_pb='\n#ComponentSpecificationMessage.proto\x12\x0b\x61ndroid.vts\"e\n\x1c\x43\x61llFlowSpecificationMessage\x12\x14\n\x05\x65ntry\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04\x65xit\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x0c\n\x04next\x18\x0b \x03(\x0c\x12\x0c\n\x04prev\x18\x0c \x03(\x0c\"C\n NativeCodeCoverageRawDataMessage\x12\x11\n\tfile_path\x18\x01 \x01(\x0c\x12\x0c\n\x04gcda\x18\x0b \x01(\x0c\"\xa3\x05\n\x1c\x46unctionSpecificationMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\x16\n\x0esubmodule_name\x18\x02 \x01(\x0c\x12>\n\x0breturn_type\x18\x0b \x01(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x43\n\x10return_type_hidl\x18\x0c \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12N\n\x1areturn_type_submodule_spec\x18\r \x01(\x0b\x32*.android.vts.ComponentSpecificationMessage\x12\x36\n\x03\x61rg\x18\x15 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12;\n\x08\x63\x61llflow\x18\x1f \x03(\x0b\x32).android.vts.CallFlowSpecificationMessage\x12\x13\n\x0bis_callback\x18) \x01(\x08\x12J\n\x10\x66unction_pointer\x18* \x01(\x0b\x32\x30.android.vts.FunctionPointerSpecificationMessage\x12\x16\n\x0eprofiling_data\x18\x65 \x03(\x02\x12 \n\x17processed_coverage_data\x18\xc9\x01 \x03(\r\x12I\n\x11raw_coverage_data\x18\xca\x01 \x03(\x0b\x32-.android.vts.NativeCodeCoverageRawDataMessage\x12\x14\n\x0bparent_path\x18\xad\x02 \x01(\x0c\x12\x17\n\x0esyscall_number\x18\x91\x03 \x01(\r\"\xf5\x02\n\x16ScalarDataValueMessage\x12\x0e\n\x06\x62ool_t\x18\x01 \x01(\x05\x12\x0e\n\x06int8_t\x18\x0b \x01(\x05\x12\x0f\n\x07uint8_t\x18\x0c \x01(\r\x12\x0c\n\x04\x63har\x18\r \x01(\x05\x12\r\n\x05uchar\x18\x0e \x01(\r\x12\x0f\n\x07int16_t\x18\x15 \x01(\x05\x12\x10\n\x08uint16_t\x18\x16 \x01(\r\x12\x0f\n\x07int32_t\x18\x1f \x01(\x05\x12\x10\n\x08uint32_t\x18  \x01(\r\x12\x0f\n\x07int64_t\x18) \x01(\x03\x12\x10\n\x08uint64_t\x18* \x01(\x04\x12\x0f\n\x07\x66loat_t\x18\x65 \x01(\x02\x12\x10\n\x08\x64ouble_t\x18\x66 \x01(\x01\x12\x10\n\x07pointer\x18\xc9\x01 \x01(\r\x12\x0f\n\x06opaque\x18\xca\x01 \x01(\r\x12\x15\n\x0cvoid_pointer\x18\xd3\x01 \x01(\r\x12\x15\n\x0c\x63har_pointer\x18\xd4\x01 \x01(\r\x12\x16\n\ruchar_pointer\x18\xd5\x01 \x01(\r\x12\x18\n\x0fpointer_pointer\x18\xfb\x01 \x01(\r\"\xd1\x01\n#FunctionPointerSpecificationMessage\x12\x15\n\rfunction_name\x18\x01 \x01(\x0c\x12\x0f\n\x07\x61\x64\x64ress\x18\x0b \x01(\r\x12\n\n\x02id\x18\x15 \x01(\x0c\x12\x36\n\x03\x61rg\x18\x65 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12>\n\x0breturn_type\x18o \x01(\x0b\x32).android.vts.VariableSpecificationMessage\"9\n\x16StringDataValueMessage\x12\x0f\n\x07message\x18\x01 \x01(\x0c\x12\x0e\n\x06length\x18\x0b \x01(\r\"z\n\x14\x45numDataValueMessage\x12\x12\n\nenumerator\x18\x01 \x03(\x0c\x12\x39\n\x0cscalar_value\x18\x02 \x03(\x0b\x32#.android.vts.ScalarDataValueMessage\x12\x13\n\x0bscalar_type\x18\x03 \x01(\x0c\"\x8b\x07\n\x1cVariableSpecificationMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\'\n\x04type\x18\x02 \x01(\x0e\x32\x19.android.vts.VariableType\x12\x39\n\x0cscalar_value\x18\x65 \x01(\x0b\x32#.android.vts.ScalarDataValueMessage\x12\x13\n\x0bscalar_type\x18\x66 \x01(\x0c\x12\x39\n\x0cstring_value\x18o \x01(\x0b\x32#.android.vts.StringDataValueMessage\x12\x35\n\nenum_value\x18y \x01(\x0b\x32!.android.vts.EnumDataValueMessage\x12@\n\x0cvector_value\x18\x83\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x14\n\x0bvector_size\x18\x84\x01 \x01(\x05\x12@\n\x0cstruct_value\x18\x8d\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x14\n\x0bstruct_type\x18\x8e\x01 \x01(\x0c\x12>\n\nsub_struct\x18\x8f\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12?\n\x0bunion_value\x18\x97\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x13\n\nunion_type\x18\x98\x01 \x01(\x0c\x12=\n\tsub_union\x18\x99\x01 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12\x18\n\x0fpredefined_type\x18\xc9\x01 \x01(\x0c\x12K\n\x10\x66unction_pointer\x18\xdd\x01 \x03(\x0b\x32\x30.android.vts.FunctionPointerSpecificationMessage\x12\x1b\n\x12hidl_callback_type\x18\xe7\x01 \x01(\x0c\x12\x17\n\x08is_input\x18\xad\x02 \x01(\x08:\x04true\x12\x19\n\tis_output\x18\xae\x02 \x01(\x08:\x05\x66\x61lse\x12\x18\n\x08is_const\x18\xaf\x02 \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0bis_callback\x18\xb0\x02 \x01(\x08:\x05\x66\x61lse\"\xfb\x01\n\x1aStructSpecificationMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\x19\n\nis_pointer\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x37\n\x03\x61pi\x18\xe9\x07 \x03(\x0b\x32).android.vts.FunctionSpecificationMessage\x12<\n\nsub_struct\x18\xd1\x0f \x03(\x0b\x32\'.android.vts.StructSpecificationMessage\x12=\n\tattribute\x18\xb9\x17 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\"\xd5\x01\n\x1dInterfaceSpecificationMessage\x12\x37\n\x03\x61pi\x18\xd1\x0f \x03(\x0b\x32).android.vts.FunctionSpecificationMessage\x12=\n\tattribute\x18\xb9\x17 \x03(\x0b\x32).android.vts.VariableSpecificationMessage\x12<\n\nsub_struct\x18\xa1\x1f \x03(\x0b\x32\'.android.vts.StructSpecificationMessage\"\xca\x03\n\x1d\x43omponentSpecificationMessage\x12\x34\n\x0f\x63omponent_class\x18\x01 \x01(\x0e\x32\x1b.android.vts.ComponentClass\x12\x32\n\x0e\x63omponent_type\x18\x02 \x01(\x0e\x32\x1a.android.vts.ComponentType\x12!\n\x16\x63omponent_type_version\x18\x03 \x01(\x02:\x01\x31\x12\x16\n\x0e\x63omponent_name\x18\x04 \x01(\x0c\x12,\n\x0btarget_arch\x18\x05 \x01(\x0e\x32\x17.android.vts.TargetArch\x12\x0f\n\x07package\x18\x0b \x01(\x0c\x12\x0e\n\x06import\x18\x0c \x03(\x0c\x12%\n\x1coriginal_data_structure_name\x18\xe9\x07 \x01(\x0c\x12\x0f\n\x06header\x18\xea\x07 \x03(\x0c\x12>\n\tinterface\x18\xd1\x0f \x01(\x0b\x32*.android.vts.InterfaceSpecificationMessage\x12=\n\tattribute\x18\xb5\x10 \x03(\x0b\x32).android.vts.VariableSpecificationMessage*\xc9\x01\n\x0e\x43omponentClass\x12\x11\n\rUNKNOWN_CLASS\x10\x00\x12\x14\n\x10HAL_CONVENTIONAL\x10\x01\x12\x1e\n\x1aHAL_CONVENTIONAL_SUBMODULE\x10\x02\x12\x0e\n\nHAL_LEGACY\x10\x03\x12\x0c\n\x08HAL_HIDL\x10\x04\x12!\n\x1dHAL_HIDL_WRAPPED_CONVENTIONAL\x10\x05\x12\x0e\n\nLIB_SHARED\x10\x0b\x12\n\n\x06KERNEL\x10\x15\x12\x11\n\rKERNEL_MODULE\x10\x16*\xf1\x01\n\rComponentType\x12\x10\n\x0cUNKNOWN_TYPE\x10\x00\x12\t\n\x05\x41UDIO\x10\x01\x12\n\n\x06\x43\x41MERA\x10\x02\x12\x07\n\x03GPS\x10\x03\x12\t\n\x05LIGHT\x10\x04\x12\x08\n\x04WIFI\x10\x05\x12\n\n\x06MOBILE\x10\x06\x12\r\n\tBLUETOOTH\x10\x07\x12\x07\n\x03NFC\x10\x08\x12\t\n\x05POWER\x10\t\x12\x0c\n\x08MEMTRACK\x10\n\x12\x07\n\x03\x42\x46P\x10\x0b\x12\x0c\n\x08VIBRATOR\x10\x0c\x12\x10\n\x0b\x42IONIC_LIBM\x10\xe9\x07\x12\x10\n\x0b\x42IONIC_LIBC\x10\xea\x07\x12\x13\n\x0eVNDK_LIBCUTILS\x10\xcd\x08\x12\x0c\n\x07SYSCALL\x10\xd1\x0f*\xa0\x02\n\x0cVariableType\x12\x19\n\x15UNKNOWN_VARIABLE_TYPE\x10\x00\x12\x13\n\x0fTYPE_PREDEFINED\x10\x01\x12\x0f\n\x0bTYPE_SCALAR\x10\x02\x12\x0f\n\x0bTYPE_STRING\x10\x03\x12\r\n\tTYPE_ENUM\x10\x04\x12\x0e\n\nTYPE_ARRAY\x10\x05\x12\x0f\n\x0bTYPE_VECTOR\x10\x06\x12\x0f\n\x0bTYPE_STRUCT\x10\x07\x12\x19\n\x15TYPE_FUNCTION_POINTER\x10\x08\x12\r\n\tTYPE_VOID\x10\t\x12\x16\n\x12TYPE_HIDL_CALLBACK\x10\n\x12\x12\n\x0eTYPE_SUBMODULE\x10\x0b\x12\x0e\n\nTYPE_UNION\x10\x0c\x12\x17\n\x13TYPE_HIDL_INTERFACE\x10\r*Q\n\nTargetArch\x12\x17\n\x13UNKNOWN_TARGET_ARCH\x10\x00\x12\x13\n\x0fTARGET_ARCH_ARM\x10\x01\x12\x15\n\x11TARGET_ARCH_ARM64\x10\x02')
 
 _COMPONENTCLASS = _descriptor.EnumDescriptor(
   name='ComponentClass',
@@ -121,26 +121,30 @@
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='BIONIC_LIBM', index=12, number=1001,
+      name='VIBRATOR', index=12, number=12,
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='BIONIC_LIBC', index=13, number=1002,
+      name='BIONIC_LIBM', index=13, number=1001,
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='VNDK_LIBCUTILS', index=14, number=1101,
+      name='BIONIC_LIBC', index=14, number=1002,
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='SYSCALL', index=15, number=2001,
+      name='VNDK_LIBCUTILS', index=15, number=1101,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SYSCALL', index=16, number=2001,
       options=None,
       type=None),
   ],
   containing_type=None,
   options=None,
   serialized_start=3719,
-  serialized_end=3946,
+  serialized_end=3960,
 )
 
 ComponentType = enum_type_wrapper.EnumTypeWrapper(_COMPONENTTYPE)
@@ -202,11 +206,15 @@
       name='TYPE_UNION', index=12, number=12,
       options=None,
       type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_HIDL_INTERFACE', index=13, number=13,
+      options=None,
+      type=None),
   ],
   containing_type=None,
   options=None,
-  serialized_start=3949,
-  serialized_end=4212,
+  serialized_start=3963,
+  serialized_end=4251,
 )
 
 VariableType = enum_type_wrapper.EnumTypeWrapper(_VARIABLETYPE)
@@ -231,8 +239,8 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=4214,
-  serialized_end=4295,
+  serialized_start=4253,
+  serialized_end=4334,
 )
 
 TargetArch = enum_type_wrapper.EnumTypeWrapper(_TARGETARCH)
@@ -257,6 +265,7 @@
 POWER = 9
 MEMTRACK = 10
 BFP = 11
+VIBRATOR = 12
 BIONIC_LIBM = 1001
 BIONIC_LIBC = 1002
 VNDK_LIBCUTILS = 1101
@@ -274,6 +283,7 @@
 TYPE_HIDL_CALLBACK = 10
 TYPE_SUBMODULE = 11
 TYPE_UNION = 12
+TYPE_HIDL_INTERFACE = 13
 UNKNOWN_TARGET_ARCH = 0
 TARGET_ARCH_ARM = 1
 TARGET_ARCH_ARM64 = 2
diff --git a/proto/VtsReportMessage_pb2.py b/proto/VtsReportMessage_pb2.py
index d9a88fb..ed8f635 100644
--- a/proto/VtsReportMessage_pb2.py
+++ b/proto/VtsReportMessage_pb2.py
@@ -14,7 +14,7 @@
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='VtsReportMessage.proto',
   package='android.vts',
-  serialized_pb='\n\x16VtsReportMessage.proto\x12\x0b\x61ndroid.vts\"\xb9\x01\n\x18\x41ndroidDeviceInfoMessage\x12\x14\n\x0cproduct_type\x18\x01 \x01(\x0c\x12\x17\n\x0fproduct_variant\x18\x02 \x01(\x0c\x12\x14\n\x0c\x62uild_flavor\x18\x0b \x01(\x0c\x12\x10\n\x08\x62uild_id\x18\x0c \x01(\x0c\x12\x0e\n\x06\x62ranch\x18\x15 \x01(\x0c\x12\x13\n\x0b\x62uild_alias\x18\x16 \x01(\x0c\x12\x11\n\tapi_level\x18\x1f \x01(\x0c\x12\x0e\n\x06serial\x18\x65 \x01(\x0c\"g\n\x10\x41ndroidBuildInfo\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0c\n\x04name\x18\x0b \x01(\x0c\x12\x12\n\nbuild_type\x18\x0c \x01(\x0c\x12\x0e\n\x06\x62ranch\x18\r \x01(\x0c\x12\x15\n\rbuild_summary\x18\x15 \x01(\x0c\"\xbd\x01\n\x15TestCaseReportMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\x30\n\x0btest_result\x18\x0b \x01(\x0e\x32\x1b.android.vts.TestCaseResult\x12\x17\n\x0fstart_timestamp\x18\x15 \x01(\x03\x12\x15\n\rend_timestamp\x18\x16 \x01(\x03\x12\x34\n\x08\x63overage\x18\x1f \x03(\x0b\x32\".android.vts.CoverageReportMessage\"\xcd\x01\n\x16ProfilingReportMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12+\n\x04type\x18\x02 \x01(\x0e\x32\x1d.android.vts.VtsProfilingType\x12\x17\n\x0fstart_timestamp\x18\x0b \x01(\x03\x12\x15\n\rend_timestamp\x18\x0c \x01(\x03\x12\r\n\x05label\x18\x15 \x03(\x0c\x12\r\n\x05value\x18\x16 \x03(\x03\x12\x14\n\x0cx_axis_label\x18\x1f \x01(\x0c\x12\x14\n\x0cy_axis_label\x18  \x01(\x0c\"\xe5\x01\n\x15\x43overageReportMessage\x12\x11\n\tfile_path\x18\x0b \x01(\x0c\x12\x14\n\x0cproject_name\x18\x0c \x01(\x0c\x12\x10\n\x08revision\x18\r \x01(\x0c\x12\x1c\n\x14line_coverage_vector\x18\x17 \x03(\x05\x12\x18\n\x10total_line_count\x18\x65 \x01(\x05\x12\x1a\n\x12\x63overed_line_count\x18\x66 \x01(\x05\x12\x14\n\x08\x64ir_path\x18\x01 \x01(\x0c\x42\x02\x18\x01\x12\x15\n\tfile_name\x18\x02 \x01(\x0c\x42\x02\x18\x01\x12\x10\n\x04html\x18\x03 \x01(\x0c\x42\x02\x18\x01\"\x8a\x03\n\x11TestReportMessage\x12\x12\n\ntest_suite\x18\x01 \x01(\x0c\x12\x0c\n\x04test\x18\x02 \x01(\x0c\x12+\n\ttest_type\x18\x03 \x01(\x0e\x32\x18.android.vts.VtsTestType\x12:\n\x0b\x64\x65vice_info\x18\x04 \x03(\x0b\x32%.android.vts.AndroidDeviceInfoMessage\x12\x31\n\nbuild_info\x18\x05 \x01(\x0b\x32\x1d.android.vts.AndroidBuildInfo\x12\x18\n\x10subscriber_email\x18\x06 \x03(\x0c\x12\x35\n\ttest_case\x18\x0b \x03(\x0b\x32\".android.vts.TestCaseReportMessage\x12\x36\n\tprofiling\x18\x15 \x03(\x0b\x32#.android.vts.ProfilingReportMessage\x12\x17\n\x0fstart_timestamp\x18\x65 \x01(\x03\x12\x15\n\rend_timestamp\x18\x66 \x01(\x03*\xb3\x01\n\x0eTestCaseResult\x12\x12\n\x0eUNKNOWN_RESULT\x10\x00\x12\x19\n\x15TEST_CASE_RESULT_PASS\x10\x01\x12\x19\n\x15TEST_CASE_RESULT_FAIL\x10\x02\x12\x19\n\x15TEST_CASE_RESULT_SKIP\x10\x03\x12\x1e\n\x1aTEST_CASE_RESULT_EXCEPTION\x10\x04\x12\x1c\n\x18TEST_CASE_RESULT_TIMEOUT\x10\x05*\x9c\x01\n\x0bVtsTestType\x12\x18\n\x14UNKNOWN_VTS_TESTTYPE\x10\x00\x12\x1e\n\x1aVTS_HOST_DRIVEN_STRUCTURAL\x10\x01\x12\x1b\n\x17VTS_HOST_DRIVEN_FUZZING\x10\x02\x12\x19\n\x15VTS_TARGET_SIDE_GTEST\x10\x03\x12\x1b\n\x17VTS_TARGET_SIDE_FUZZING\x10\x04*{\n\x10VtsProfilingType\x12\x1e\n\x1aUNKNOWN_VTS_PROFILING_TYPE\x10\x00\x12 \n\x1cVTS_PROFILING_TYPE_TIMESTAMP\x10\x01\x12%\n!VTS_PROFILING_TYPE_LABELED_VECTOR\x10\x02\x42\x30\n\x1c\x63om.google.android.vts.protoB\x10VtsReportMessage')
+  serialized_pb='\n\x16VtsReportMessage.proto\x12\x0b\x61ndroid.vts\"\xb9\x01\n\x18\x41ndroidDeviceInfoMessage\x12\x14\n\x0cproduct_type\x18\x01 \x01(\x0c\x12\x17\n\x0fproduct_variant\x18\x02 \x01(\x0c\x12\x14\n\x0c\x62uild_flavor\x18\x0b \x01(\x0c\x12\x10\n\x08\x62uild_id\x18\x0c \x01(\x0c\x12\x0e\n\x06\x62ranch\x18\x15 \x01(\x0c\x12\x13\n\x0b\x62uild_alias\x18\x16 \x01(\x0c\x12\x11\n\tapi_level\x18\x1f \x01(\x0c\x12\x0e\n\x06serial\x18\x65 \x01(\x0c\"g\n\x10\x41ndroidBuildInfo\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0c\n\x04name\x18\x0b \x01(\x0c\x12\x12\n\nbuild_type\x18\x0c \x01(\x0c\x12\x0e\n\x06\x62ranch\x18\r \x01(\x0c\x12\x15\n\rbuild_summary\x18\x15 \x01(\x0c\"\xbd\x01\n\x15TestCaseReportMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\x30\n\x0btest_result\x18\x0b \x01(\x0e\x32\x1b.android.vts.TestCaseResult\x12\x17\n\x0fstart_timestamp\x18\x15 \x01(\x03\x12\x15\n\rend_timestamp\x18\x16 \x01(\x03\x12\x34\n\x08\x63overage\x18\x1f \x03(\x0b\x32\".android.vts.CoverageReportMessage\"\xcd\x01\n\x16ProfilingReportMessage\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12+\n\x04type\x18\x02 \x01(\x0e\x32\x1d.android.vts.VtsProfilingType\x12\x17\n\x0fstart_timestamp\x18\x0b \x01(\x03\x12\x15\n\rend_timestamp\x18\x0c \x01(\x03\x12\r\n\x05label\x18\x15 \x03(\x0c\x12\r\n\x05value\x18\x16 \x03(\x03\x12\x14\n\x0cx_axis_label\x18\x1f \x01(\x0c\x12\x14\n\x0cy_axis_label\x18  \x01(\x0c\"\xe5\x01\n\x15\x43overageReportMessage\x12\x11\n\tfile_path\x18\x0b \x01(\x0c\x12\x14\n\x0cproject_name\x18\x0c \x01(\x0c\x12\x10\n\x08revision\x18\r \x01(\x0c\x12\x1c\n\x14line_coverage_vector\x18\x17 \x03(\x05\x12\x18\n\x10total_line_count\x18\x65 \x01(\x05\x12\x1a\n\x12\x63overed_line_count\x18\x66 \x01(\x05\x12\x14\n\x08\x64ir_path\x18\x01 \x01(\x0c\x42\x02\x18\x01\x12\x15\n\tfile_name\x18\x02 \x01(\x0c\x42\x02\x18\x01\x12\x10\n\x04html\x18\x03 \x01(\x0c\x42\x02\x18\x01\"\x8a\x03\n\x11TestReportMessage\x12\x12\n\ntest_suite\x18\x01 \x01(\x0c\x12\x0c\n\x04test\x18\x02 \x01(\x0c\x12+\n\ttest_type\x18\x03 \x01(\x0e\x32\x18.android.vts.VtsTestType\x12:\n\x0b\x64\x65vice_info\x18\x04 \x03(\x0b\x32%.android.vts.AndroidDeviceInfoMessage\x12\x31\n\nbuild_info\x18\x05 \x01(\x0b\x32\x1d.android.vts.AndroidBuildInfo\x12\x18\n\x10subscriber_email\x18\x06 \x03(\x0c\x12\x35\n\ttest_case\x18\x0b \x03(\x0b\x32\".android.vts.TestCaseReportMessage\x12\x36\n\tprofiling\x18\x15 \x03(\x0b\x32#.android.vts.ProfilingReportMessage\x12\x17\n\x0fstart_timestamp\x18\x65 \x01(\x03\x12\x15\n\rend_timestamp\x18\x66 \x01(\x03*\xb3\x01\n\x0eTestCaseResult\x12\x12\n\x0eUNKNOWN_RESULT\x10\x00\x12\x19\n\x15TEST_CASE_RESULT_PASS\x10\x01\x12\x19\n\x15TEST_CASE_RESULT_FAIL\x10\x02\x12\x19\n\x15TEST_CASE_RESULT_SKIP\x10\x03\x12\x1e\n\x1aTEST_CASE_RESULT_EXCEPTION\x10\x04\x12\x1c\n\x18TEST_CASE_RESULT_TIMEOUT\x10\x05*\x9c\x01\n\x0bVtsTestType\x12\x18\n\x14UNKNOWN_VTS_TESTTYPE\x10\x00\x12\x1e\n\x1aVTS_HOST_DRIVEN_STRUCTURAL\x10\x01\x12\x1b\n\x17VTS_HOST_DRIVEN_FUZZING\x10\x02\x12\x19\n\x15VTS_TARGET_SIDE_GTEST\x10\x03\x12\x1b\n\x17VTS_TARGET_SIDE_FUZZING\x10\x04*{\n\x10VtsProfilingType\x12\x1e\n\x1aUNKNOWN_VTS_PROFILING_TYPE\x10\x00\x12 \n\x1cVTS_PROFILING_TYPE_TIMESTAMP\x10\x01\x12%\n!VTS_PROFILING_TYPE_LABELED_VECTOR\x10\x02\x42)\n\x15\x63om.android.vts.protoB\x10VtsReportMessage')
 
 _TESTCASERESULT = _descriptor.EnumDescriptor(
   name='TestCaseResult',
@@ -624,7 +624,7 @@
 
 
 DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), '\n\034com.google.android.vts.protoB\020VtsReportMessage')
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), '\n\025com.android.vts.protoB\020VtsReportMessage')
 _COVERAGEREPORTMESSAGE.fields_by_name['dir_path'].has_options = True
 _COVERAGEREPORTMESSAGE.fields_by_name['dir_path']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), '\030\001')
 _COVERAGEREPORTMESSAGE.fields_by_name['file_name'].has_options = True
diff --git a/proto/VtsWebStatusMessage_pb2.py b/proto/VtsWebStatusMessage_pb2.py
index 73fa122..7a76b24 100644
--- a/proto/VtsWebStatusMessage_pb2.py
+++ b/proto/VtsWebStatusMessage_pb2.py
@@ -14,7 +14,7 @@
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='VtsWebStatusMessage.proto',
   package='android.vts',
-  serialized_pb='\n\x19VtsWebStatusMessage.proto\x12\x0b\x61ndroid.vts\"\x92\x01\n\x11TestStatusMessage\x12\x12\n\ntest_suite\x18\x01 \x01(\x0c\x12\x0c\n\x04test\x18\x02 \x01(\x0c\x12\x18\n\x10status_timestamp\x18\x03 \x01(\x03\x12\'\n\x06status\x18\x04 \x01(\x0e\x32\x17.android.vts.TestStatus\x12\x18\n\x10\x66\x61iled_testcases\x18\x05 \x03(\x0c*:\n\nTestStatus\x12\x10\n\x0cTEST_UNKNOWN\x10\x00\x12\x0b\n\x07TEST_OK\x10\x01\x12\r\n\tTEST_FAIL\x10\x02\x42\x33\n\x1c\x63om.google.android.vts.protoB\x13VtsWebStatusMessage')
+  serialized_pb='\n\x19VtsWebStatusMessage.proto\x12\x0b\x61ndroid.vts\"\x92\x01\n\x11TestStatusMessage\x12\x12\n\ntest_suite\x18\x01 \x01(\x0c\x12\x0c\n\x04test\x18\x02 \x01(\x0c\x12\x18\n\x10status_timestamp\x18\x03 \x01(\x03\x12\'\n\x06status\x18\x04 \x01(\x0e\x32\x17.android.vts.TestStatus\x12\x18\n\x10\x66\x61iled_testcases\x18\x05 \x03(\x0c*:\n\nTestStatus\x12\x10\n\x0cTEST_UNKNOWN\x10\x00\x12\x0b\n\x07TEST_OK\x10\x01\x12\r\n\tTEST_FAIL\x10\x02\x42,\n\x15\x63om.android.vts.protoB\x13VtsWebStatusMessage')
 
 _TESTSTATUS = _descriptor.EnumDescriptor(
   name='TestStatus',
@@ -114,5 +114,5 @@
 
 
 DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), '\n\034com.google.android.vts.protoB\023VtsWebStatusMessage')
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), '\n\025com.android.vts.protoB\023VtsWebStatusMessage')
 # @@protoc_insertion_point(module_scope)
diff --git a/run-angler.sh b/run-angler.sh
index 965f26f..87941d1 100755
--- a/run-angler.sh
+++ b/run-angler.sh
@@ -22,6 +22,6 @@
 # PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.host.camera.conventional.2_1.SampleCameraV2Test
 # PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.host.camera.conventional.3_4.SampleCameraV3Test
 # PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.hal.nfc.hidl.host.NfcHidlBasicTest
-# PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.hal.vibrator.hidl.VibratorHidlTest
+# PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.hal.vibrator.hidl.host.VibratorHidlTest
 # PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.host.shell.SampleShellTest
 # PYTHONPATH=$PYTHONPATH:.. python -m vts.testcases.fuzz_test.lib_bionic.LibBionicLibmFuzzTest
diff --git a/runners/host/base_test.py b/runners/host/base_test.py
index 4c865d1..32f5221 100644
--- a/runners/host/base_test.py
+++ b/runners/host/base_test.py
@@ -86,10 +86,7 @@
                     setattr(self, filter, filter_expanded)
 
         # Set abi bitness (optional)
-        self.abi_bitness = None
-        if keys.ConfigKeys.IKEY_ABI_BITNESS in self.user_params:
-            self.abi_bitness = self.user_params[
-                keys.ConfigKeys.IKEY_ABI_BITNESS]
+        self.abi_bitness = self.getUserParam(keys.ConfigKeys.IKEY_ABI_BITNESS)
 
     def __enter__(self):
         return self
@@ -133,6 +130,48 @@
             else:
                 setattr(self, name, self.user_params[name])
 
+    def getUserParam(self, param_name, error_if_not_found=False, default_value=None):
+        """Get the value of a single user parameter.
+
+        This method returns the value of specified user parameter.
+        Note: this method will not automatically set attribute using the parameter name and value.
+
+        Args:
+            param_name: string or list of string, denoting user parameter names. If provided
+                        a single string, self.user_params["<param_name>"] will be accessed.
+                        If provided multiple strings,
+                        self.user_params["<param_name1>"]["<param_name2>"]["<param_name3>"]...
+                        will be accessed.
+            error_if_not_found: bool, whether to raise error if parameter not exists. Default:
+                                False
+            default_value: object, default value to return if not found. If error_if_not_found is
+                           True, this parameter has no effect. Default: None
+
+        Returns:
+            object, value of the specified parameter name chain if exists;
+            <default_value> if not exists.
+        """
+        if not param_name:
+            if error_if_not_found:
+                raise errors.BaseTestError("empty param_name provided")
+            logging.error("empty param_name")
+            return default_value
+
+        if not isinstance(param_name, list):
+            param_name = [param_name]
+
+        curr_obj = self.user_params
+        for param in param_name:
+            if param not in curr_obj:
+                if error_if_not_found:
+                    raise errors.BaseTestError(
+                        ("Missing user param '%s' "
+                         "in test configuration.") % name)
+                return default_value
+            curr_obj = curr_obj[param]
+
+        return curr_obj
+
     def _setUpClass(self):
         """Proxy function to guarantee the base implementation of setUpClass
         is called.
diff --git a/runners/host/base_test_with_webdb.py b/runners/host/base_test_with_webdb.py
index 1e64dea..afa3377 100644
--- a/runners/host/base_test_with_webdb.py
+++ b/runners/host/base_test_with_webdb.py
@@ -41,9 +41,12 @@
 from vts.utils.python.coverage import gcda_parser
 from vts.utils.python.coverage import gcno_parser
 from vts.utils.python.build.api import artifact_fetcher
+from vts.utils.python.profiling import profiling_utils
 
 _ANDROID_DEVICE = "AndroidDevice"
-
+_MAX = "max"
+_MIN = "min"
+_AVG = "avg"
 
 class BaseTestWithWebDbClass(base_test.BaseTestClass):
     """Base class with Web DB interface for test classes to inherit from.
@@ -73,6 +76,8 @@
     STATUS_TABLE = "vts_status_table"
     BIGTABLE_BASE_URL = "bigtable_base_url"
     BRANCH = "master"
+    ENABLE_PROFILING = "enable_profiling"
+    VTS_PROFILING_TRACING_PATH = "profiling_trace_path"
 
     def __init__(self, configs):
         super(BaseTestWithWebDbClass, self).__init__(configs)
@@ -82,10 +87,11 @@
         is called.
         """
         self.getUserParams(opt_param_names=[
-            self.USE_GAE_DB, self.BIGTABLE_BASE_URL,
-            self.MODULES, self.GIT_PROJECT_NAME, self.GIT_PROJECT_PATH,
+            self.USE_GAE_DB, self.BIGTABLE_BASE_URL, self.MODULES,
+            self.GIT_PROJECT_NAME, self.GIT_PROJECT_PATH,
             self.SERVICE_JSON_PATH, keys.ConfigKeys.IKEY_DATA_FILE_PATH,
-            keys.ConfigKeys.KEY_TESTBED_NAME
+            keys.ConfigKeys.KEY_TESTBED_NAME, self.ENABLE_PROFILING,
+            self.VTS_PROFILING_TRACING_PATH
         ])
 
         if getattr(self, self.USE_GAE_DB, False):
@@ -94,14 +100,13 @@
             test_module_name = self.__class__.__name__
             if hasattr(self, keys.ConfigKeys.KEY_TESTBED_NAME):
                 user_specified_test_name = getattr(
-                        self, keys.ConfigKeys.KEY_TESTBED_NAME, None)
+                    self, keys.ConfigKeys.KEY_TESTBED_NAME, None)
                 if user_specified_test_name:
                     test_module_name = str(user_specified_test_name)
                 else:
-                    logging.warn(
-                        "%s field = %s",
-                        keys.ConfigKeys.KEY_TESTBED_NAME,
-                        user_specified_test_name)
+                    logging.warn("%s field = %s",
+                                 keys.ConfigKeys.KEY_TESTBED_NAME,
+                                 user_specified_test_name)
             else:
                 logging.warn("%s not defined in the given test config",
                              keys.ConfigKeys.KEY_TESTBED_NAME)
@@ -116,11 +121,13 @@
         return super(BaseTestWithWebDbClass, self)._setUpClass()
 
     def _tearDownClass(self):
+        """Calls sub-class's tearDownClass first and then uploads to web DB."""
+        result = super(BaseTestWithWebDbClass, self)._tearDownClass()
         if (getattr(self, self.USE_GAE_DB, False) and
-            getattr(self, self.BIGTABLE_BASE_URL, "")):
+                getattr(self, self.BIGTABLE_BASE_URL, "")):
             # Handle case when runner fails, tests aren't executed
             if (self.results.executed and
-                self.results.executed[-1].test_name == "setup_class"):
+                    self.results.executed[-1].test_name == "setup_class"):
                 # Test failed during setup, all tests were not executed
                 start_index = 0
             else:
@@ -151,9 +158,9 @@
                     build_id = str(build[keys.ConfigKeys.IKEY_BUILD_ID])
                     self._report_msg.build_info.id = build_id
 
-            bt_client.PutRow(str(self._report_msg.start_timestamp),
-                             "data", self._report_msg.SerializeToString())
-
+            bt_client.PutRow(
+                str(self._report_msg.start_timestamp), "data",
+                self._report_msg.SerializeToString())
 
             logging.info("_tearDownClass hook: report msg proto %s",
                          self._report_msg)
@@ -173,7 +180,7 @@
         else:
             logging.info("_tearDownClass hook: missing USE_GAE_DB and/or "
                          "BIGTABLE_BASE_URL. Web uploading disabled.")
-        return super(BaseTestWithWebDbClass, self)._tearDownClass()
+        return result
 
     def SetDeviceInfo(self, msg):
         """Sets device info to the given protobuf message, msg."""
@@ -405,7 +412,7 @@
             product = getattr(device_spec,
                               keys.ConfigKeys.IKEY_PRODUCT_VARIANT, None)
             device_build_id = getattr(device_spec,
-                              keys.ConfigKeys.IKEY_BUILD_ID, None)
+                                      keys.ConfigKeys.IKEY_BUILD_ID, None)
 
         if not build_flavor or not product or not device_build_id:
             logging.error("Could not read device information.")
@@ -441,43 +448,43 @@
             build_client = artifact_fetcher.AndroidBuildClient(
                 service_json_path)
         except Exception:
-            logging.error("Invalid service JSON file %s",
-                service_json_path)
+            logging.error("Invalid service JSON file %s", service_json_path)
             return False
 
         # Fetch repo dictionary
         try:
-            repos = build_client.GetRepoDictionary(self.BRANCH,
-                build_flavor, device_build_id)
+            repos = build_client.GetRepoDictionary(self.BRANCH, build_flavor,
+                                                   device_build_id)
         except:
             logging.error("Could not read build info for branch %s, " +
-                "target %s, id: %s" % (self.BRANCH, build_flavor,
-                    device_build_id))
+                          "target %s, id: %s" % (self.BRANCH, build_flavor,
+                                                 device_build_id))
             return False
 
         # Get revision (commit ID) from manifest
         if project_name not in repos:
             logging.error("Could not find project %s in repo dictionary",
-                project_name)
+                          project_name)
             return False
         revision = str(repos[project_name])
 
         # Fetch coverage zip
         try:
-            cov_zip = io.BytesIO(build_client.GetCoverage("master",
-                build_flavor, device_build_id, product))
+            cov_zip = io.BytesIO(
+                build_client.GetCoverage("master", build_flavor,
+                                         device_build_id, product))
             cov_zip = zipfile.ZipFile(cov_zip)
         except:
             logging.error("Could not read coverage zip for branch %s, " +
-                "target %s, id: %s, product: %s" %
-                (self.BRANCH, build_flavor, device_build_id, product))
+                          "target %s, id: %s, product: %s" %
+                          (self.BRANCH, build_flavor, device_build_id, product
+                           ))
             return False
 
         # Load and parse the gcno archive
         modules = getattr(self, self.MODULES)
         gcnodirs = set([m + '.gcnodir' for m in modules])
 
-
         for name in [name for name in cov_zip.namelist() if name in gcnodirs]:
             archive = archive_parser.Archive(cov_zip.open(name).read())
             try:
@@ -505,11 +512,13 @@
                                      src_file_path)
                         continue
                     if src_file_name.endswith(file_name):
-                        logging.info("Coverage source file: %s" % src_file_path)
+                        logging.info("Coverage source file: %s" %
+                                     src_file_path)
                         break
 
                 if not src_file_path:
-                    logging.error("No source file found for %s." % gcno_file_path)
+                    logging.error("No source file found for %s." %
+                                  gcno_file_path)
                     continue
 
                 gcda_name = file_name + ".gcda"
@@ -523,7 +532,8 @@
                     coverage.total_line_count, coverage.covered_line_count = (
                         coverage_report.GetCoverageStats(coverage_vec))
                     coverage.line_coverage_vector.extend(coverage_vec)
-                    src_file_path = os.path.relpath(src_file_path, project_path)
+                    src_file_path = os.path.relpath(src_file_path,
+                                                    project_path)
                     coverage.file_path = src_file_path
                     coverage.revision = str(revision)
                     coverage.project_name = str(project_name)
@@ -531,3 +541,24 @@
                     logging.error("No gcda file found %s." % gcda_name)
                     continue
         return True
+
+    def ProcessAndUploadTraceData(self, dut, profiling_trace_path):
+        """Pulls the generated profiling data to the host, parses the data to
+        get the max/min/avg latency of each API call and uploads these latency
+        metrics to webdb.
+
+        Args:
+            dut: the registered device.
+            porfiling_trace_path: path to store the profiling data on host.
+        """
+        trace_files = profiling_utils.GetTraceFiles(dut, profiling_trace_path)
+        for file in trace_files:
+            logging.info("parsing trace file: %s.", file)
+            data = profiling_utils.ParseTraceData(file)
+            for tag in [_MAX, _MIN, _AVG]:
+                self.AddProfilingDataLabeledVector(
+                    data.name + "_" + tag,
+                    data.labels,
+                    data.values[tag],
+                    x_axis_label="API name",
+                    y_axis_label="API processing latency (nano secs)")
diff --git a/runners/host/const.py b/runners/host/const.py
index a8a8fa7..cd290d3 100644
--- a/runners/host/const.py
+++ b/runners/host/const.py
@@ -14,10 +14,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from vts.utils.python.common import cmd_utils
 
-STDOUT = 0
-STDERR = 1
-EXIT_CODE = 2
+STDOUT = cmd_utils.STDOUT
+STDERR = cmd_utils.STDERR
+EXIT_CODE = cmd_utils.EXIT_CODE
 
 LIST_ITEM_DELIMITER = ','
 
diff --git a/setup.sh b/setup.sh
index 34bccc3..e58a0f9 100755
--- a/setup.sh
+++ b/setup.sh
@@ -50,6 +50,8 @@
   echo "install vts driver for hidl"
   adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib/libvts_driver_hidl_nfc@1.0.so /data/local/tmp/32/
   adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib64/libvts_driver_hidl_nfc@1.0.so /data/local/tmp/64/
+  adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib/libvts_driver_hidl_vibrator@1.0.so /data/local/tmp/32/
+  adb push ${ANDROID_BUILD_TOP}/out/target/product/${DEVICE}/system/lib64/libvts_driver_hidl_vibrator@1.0.so /data/local/tmp/64/
 
   echo "install hal packages"
   adb shell mkdir -p /data/local/tmp/32/hw
@@ -83,6 +85,9 @@
   adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/nfc/1.0/vts/Nfc.vts /data/local/tmp/spec/Nfc.vts
   adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts /data/local/tmp/spec/NfcClientCallback.vts
   adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/nfc/1.0/vts/types.vts /data/local/tmp/spec/types.vts
+  # uncomment to test vibrator HAL
+  # adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vibrator/1.0/vts/Vibrator.vts /data/local/tmp/spec/
+  # adb push ${ANDROID_BUILD_TOP}/hardware/interfaces/vibrator/1.0/vts/types.vts /data/local/tmp/spec/
   adb push ${ANDROID_BUILD_TOP}/test/vts/specification/lib_bionic/libmV1.vts /data/local/tmp/spec/libmV1.vts
   adb push ${ANDROID_BUILD_TOP}/test/vts/specification/lib_bionic/libcV1.vts /data/local/tmp/spec/libcV1.vts
   adb push ${ANDROID_BUILD_TOP}/test/vts/specification/lib_bionic/libcutilsV1.vts /data/local/tmp/spec/libcutilsV1.vts
diff --git a/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp b/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp
index 68109eb..78db922 100644
--- a/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp
+++ b/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp
@@ -324,7 +324,7 @@
   return true;
 }
 
-bool FuzzerBase::GetService() {
+bool FuzzerBase::GetService(bool /*get_stub*/) {
   cerr << __func__ << " not impl" << endl;
   return false;
 }
diff --git a/sysfuzzer/common/include/fuzz_tester/FuzzerBase.h b/sysfuzzer/common/include/fuzz_tester/FuzzerBase.h
index 3bd0f94..e370322 100644
--- a/sysfuzzer/common/include/fuzz_tester/FuzzerBase.h
+++ b/sysfuzzer/common/include/fuzz_tester/FuzzerBase.h
@@ -40,7 +40,7 @@
 
   // Gets the HIDL service.
   // Returns true iff successful.
-  virtual bool GetService();
+  virtual bool GetService(bool get_stub);
 
   // Open Conventional Hal
   int OpenConventionalHal(const char* module_name = NULL);
diff --git a/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp b/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
index 43646b3..d92c6b1 100644
--- a/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
+++ b/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
@@ -22,6 +22,8 @@
 #include <queue>
 #include <string>
 
+#include <cutils/properties.h>
+
 #include "fuzz_tester/FuzzerBase.h"
 #include "fuzz_tester/FuzzerWrapper.h"
 #include "specification_parser/InterfaceSpecificationParser.h"
@@ -141,7 +143,16 @@
   cout << __func__ << ":" << __LINE__ << " "
        << "got fuzzer" << endl;
   if (iface_spec_msg.component_class() == HAL_HIDL) {
-    if (!fuzzer->GetService()) {
+    char get_sub_property[PROPERTY_VALUE_MAX];
+    bool get_stub = false;  /* default is binderized */
+    if (property_get("vts.hidl.get_stub", get_sub_property, "") > 0) {
+      if (!strcmp(get_sub_property, "true") ||
+          !strcmp(get_sub_property, "True") ||
+          !strcmp(get_sub_property, "1")) {
+        get_stub = true;
+      }
+    }
+    if (!fuzzer->GetService(get_stub)) {
       cerr << __FUNCTION__ << ": couldn't get service" << endl;
       return NULL;
     }
diff --git a/sysfuzzer/libdatatype/include/vts_datatype.h b/sysfuzzer/libdatatype/include/vts_datatype.h
index 15e02b6..4b0d55c 100644
--- a/sysfuzzer/libdatatype/include/vts_datatype.h
+++ b/sysfuzzer/libdatatype/include/vts_datatype.h
@@ -29,6 +29,7 @@
 extern void RandomNumberGeneratorReset();
 extern uint32_t RandomUint32();
 extern int32_t RandomInt32();
+extern uint64_t RandomUint64();
 extern int64_t RandomInt64();
 extern float RandomFloat();
 extern double RandomDouble();
diff --git a/sysfuzzer/libdatatype/vts_datatype.cpp b/sysfuzzer/libdatatype/vts_datatype.cpp
index d67aefd..ee93a21 100644
--- a/sysfuzzer/libdatatype/vts_datatype.cpp
+++ b/sysfuzzer/libdatatype/vts_datatype.cpp
@@ -28,6 +28,11 @@
 
 int32_t RandomInt32() { return rand(); }
 
+uint64_t RandomUint64() {
+  uint64_t num = (unsigned int)rand();
+  return (num << 32) | (unsigned int)rand();
+}
+
 int64_t RandomInt64() {
   int64_t num = rand();
   return (num << 32) | rand();
diff --git a/sysfuzzer/vtscompiler/Android.mk b/sysfuzzer/vtscompiler/Android.mk
new file mode 100644
index 0000000..41a41d0
--- /dev/null
+++ b/sysfuzzer/vtscompiler/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/sysfuzzer/vtscompiler/VtsCompilerUtils.cpp b/sysfuzzer/vtscompiler/VtsCompilerUtils.cpp
index f0ac68a..eea3f66 100644
--- a/sysfuzzer/vtscompiler/VtsCompilerUtils.cpp
+++ b/sysfuzzer/vtscompiler/VtsCompilerUtils.cpp
@@ -30,6 +30,7 @@
 #include <google/protobuf/text_format.h>
 
 #include "specification_parser/InterfaceSpecificationParser.h"
+#include "utils/StringUtil.h"
 
 #include "test/vts/proto/ComponentSpecificationMessage.pb.h"
 
@@ -132,6 +133,8 @@
     return arg.predefined_type();
   } else if (arg.type() == TYPE_SCALAR) {
     return GetCppVariableType(arg.scalar_type());
+  } else if (arg.type() == TYPE_STRING) {
+    return "::android::hardware::hidl_string";
   } else if (arg.type() == TYPE_ENUM) {
     cout << __func__ << ":" << __LINE__ << " "
          << arg.has_enum_value() << " " << arg.has_predefined_type() << endl;
@@ -316,7 +319,9 @@
         if (!message || message->component_class() != HAL_HIDL) {
           return "(" + arg.predefined_type() +  ") RandomUint32()";
         } else {
-          return "Random" + arg.predefined_type() + "()";
+          std::string predefined_type_name = arg.predefined_type();
+          ReplaceSubString(predefined_type_name, "::", "__");
+          return "Random" + predefined_type_name + "()";
           // TODO: generate a function which can dynamically choose the value.
           /* for (const auto& attribute : message->attribute()) {
             if (attribute.type() == TYPE_ENUM &&
@@ -336,6 +341,9 @@
       }
       break;
     }
+    case TYPE_STRING: {
+      return "android::hardware::hidl_string(RandomCharPointer())";
+    }
     case TYPE_STRUCT: {
       if (arg.struct_value_size() == 0 && arg.has_predefined_type()) {
         return message->component_name() + "::" + arg.predefined_type() +  "()";
@@ -372,24 +380,27 @@
   return 0;
 }
 
+#define DEFAULT_FACTOR 10000
 
 string GetVersionString(float version, bool for_macro) {
   std::ostringstream out;
   if (for_macro) {
     out << "V";
   }
-  out << int(version);
+  long version_long = version * DEFAULT_FACTOR;
+  out << (version_long / DEFAULT_FACTOR);
   if (!for_macro) {
     out << ".";
   } else {
     out << "_";
   }
-  version -= int(version);
+  version_long -= (version_long / DEFAULT_FACTOR) * DEFAULT_FACTOR;
   bool first = true;
-  while (version > 0.0 || first) {
-    version *= 10;
-    out << int(version);
-    version -= int(version);
+  long factor = DEFAULT_FACTOR / 10;
+  while (first || (version_long > 0 && factor > 1)) {
+    out << (version_long / factor);
+    version_long -= (version_long / factor) * factor;
+    factor /= 10;
     first = false;
   }
   return out.str();
diff --git a/sysfuzzer/vtscompiler/code_gen/driver/DriverCodeGenBase.cpp b/sysfuzzer/vtscompiler/code_gen/driver/DriverCodeGenBase.cpp
index e3dca9d..d336ccd 100644
--- a/sysfuzzer/vtscompiler/code_gen/driver/DriverCodeGenBase.cpp
+++ b/sysfuzzer/vtscompiler/code_gen/driver/DriverCodeGenBase.cpp
@@ -136,13 +136,16 @@
       int arg_count = 0;
       for (const auto& arg : api.arg()) {
         if (arg_count > 0) out << "," << "\n";
-        if (arg.type() == TYPE_ENUM || arg.type() == TYPE_STRUCT) {
+        if (arg.type() == TYPE_ENUM) {
           if (arg.is_const()) {
             out << "    const " << arg.predefined_type() << "&";
           } else {
             out << "    " << arg.predefined_type();
           }
           out << " arg" << arg_count;
+        } else if (arg.type() == TYPE_STRUCT) {
+          out << "    const " << arg.predefined_type() << "&";
+          out << " arg" << arg_count;
         } else if (arg.type() == TYPE_VECTOR) {
           out << "    const ";
           if (arg.vector_value(0).type() == TYPE_SCALAR) {
@@ -292,13 +295,16 @@
       int arg_count = 0;
       for (const auto& arg : api.arg()) {
         if (arg_count > 0) out << "," << "\n";
-        if (arg.type() == TYPE_ENUM || arg.type() == TYPE_STRUCT) {
+        if (arg.type() == TYPE_ENUM) {
           if (arg.is_const()) {
             out << "    const " << arg.predefined_type() << "&";
           } else {
             out << "    " << arg.predefined_type();
           }
           out << " arg" << arg_count;
+        } else if (arg.type() == TYPE_STRUCT) {
+          out << "    const " << arg.predefined_type() << "&";
+          out << " arg" << arg_count;
         } else if (arg.type() == TYPE_VECTOR) {
           out << "    const ";
           if (arg.vector_value(0).type() == TYPE_SCALAR) {
@@ -438,7 +444,7 @@
 
     if (message.component_class() == HAL_HIDL
         && message.component_name() != "types") {
-      out << "bool GetService();" << "\n"
+      out << "bool GetService(bool get_stub);" << "\n"
           << "\n";
       out.unindent();
       out << " private:" << "\n";
@@ -465,7 +471,9 @@
             << "Random" << attribute_name << "();"
             << "\n";
       } else if (attribute.type() == TYPE_STRUCT) {
-        out << "void " << "MessageTo" << attribute.name()
+        std::string attribute_name = attribute.name();
+        ReplaceSubString(attribute_name, "::", "__");
+        out << "void " << "MessageTo" << attribute_name
             << "(const VariableSpecificationMessage& var_msg, "
             << attribute.name() << "* arg);"
             << "\n";
diff --git a/sysfuzzer/vtscompiler/code_gen/driver/HalHidlCodeGen.cpp b/sysfuzzer/vtscompiler/code_gen/driver/HalHidlCodeGen.cpp
index 4b19f28..a729c6d 100644
--- a/sysfuzzer/vtscompiler/code_gen/driver/HalHidlCodeGen.cpp
+++ b/sysfuzzer/vtscompiler/code_gen/driver/HalHidlCodeGen.cpp
@@ -105,13 +105,14 @@
           */
           if (arg.scalar_type() == "char_pointer") {
             out << "char* ";
-          } else if (arg.scalar_type() == "bool_t" ||
-                     arg.scalar_type() == "int32_t" ||
+          } else if (arg.scalar_type() == "int32_t" ||
                      arg.scalar_type() == "uint32_t" ||
                      arg.scalar_type() == "size_t" ||
                      arg.scalar_type() == "int64_t" ||
                      arg.scalar_type() == "uint64_t") {
             out << arg.scalar_type() << " ";
+          } else if (arg.scalar_type() == "bool_t") {
+            out << "bool ";
           } else if (arg.scalar_type() == "void_pointer") {
             out << "void*";
           } else {
@@ -226,14 +227,28 @@
           out << ", ";
         }
         if (return_type_hidl.type() == TYPE_SCALAR) {
-          out << return_type_hidl.scalar_type();
+          if (return_type_hidl.scalar_type() == "bool_t") {
+            out << "bool";
+          } else {
+            out << return_type_hidl.scalar_type();
+          }
         } else if (return_type_hidl.type() == TYPE_ENUM ||
-                   return_type_hidl.type() == TYPE_VECTOR ||
-                   return_type_hidl.type() == TYPE_STRUCT) {
+                   return_type_hidl.type() == TYPE_VECTOR) {
           out << GetCppVariableType(return_type_hidl, &message);
+        } else if (return_type_hidl.type() == TYPE_STRING) {
+          out << "::android::hardware::hidl_string ";
+        } else if (return_type_hidl.type() == TYPE_STRUCT) {
+          if (return_type_hidl.has_predefined_type()) {
+            out << return_type_hidl.predefined_type() << " ";
+          } else {
+            cerr << __func__ << ":" << __LINE__ << " ERROR no predefined type "
+                 << "\n";
+            exit(-1);
+          }
         } else {
           cerr << __func__ << ":" << __LINE__ << " ERROR unsupported type "
-               << return_type_hidl.type() << "\n";
+               << return_type_hidl.type() << " for " << api.name() << "\n";
+          exit(-1);
         }
         out << " arg" << arg_index;
         arg_index++;
@@ -252,14 +267,21 @@
           out << ", ";
         }
         if (return_type_hidl.type() == TYPE_SCALAR) {
-          out << return_type_hidl.scalar_type();
+          if (return_type_hidl.scalar_type() == "bool_t") {
+            out << "bool";
+          } else {
+            out << return_type_hidl.scalar_type();
+          }
         } else if (return_type_hidl.type() == TYPE_ENUM ||
                    return_type_hidl.type() == TYPE_VECTOR ||
                    return_type_hidl.type() == TYPE_STRUCT) {
           out << GetCppVariableType(return_type_hidl, &message);
+        } else if (return_type_hidl.type() == TYPE_STRING) {
+          out << "::android::hardware::hidl_string";
         } else {
           cerr << __func__ << ":" << __LINE__ << " ERROR unsupported type "
-               << return_type_hidl.type() << "\n";
+               << return_type_hidl.type() << " for " << api.name() << "\n";
+          exit(-1);
         }
       }
       out << ")> "
@@ -298,7 +320,8 @@
                                   sub_struct.is_pointer() ? "->" : ".");
     }
 
-    out << "bool " << fuzzer_extended_class_name << "::GetService() {" << "\n";
+    out << "bool " << fuzzer_extended_class_name
+        << "::GetService(bool get_stub) {" << "\n";
     out.indent();
 
     out << "static bool initialized = false;" << "\n";
@@ -314,7 +337,7 @@
     out << "hw_binder_proxy_ = " << message.component_name()
         << "::getService(\""
         << service_name
-        << "\", false /*get stub*/);" << "\n";
+        << "\", get_stub);" << "\n";
     out << "cout << \"[agent:hal] hw_binder_proxy_ = \" << "
         << "hw_binder_proxy_.get() << endl;" << "\n";
     out << "initialized = true;" << "\n";
@@ -468,8 +491,8 @@
                   arg.scalar_type() == "void_pointer" ||
                   arg.scalar_type() == "function_pointer") {
                 out << "reinterpret_cast<"
-                       << GetCppVariableType(arg, &message)
-                       << ">";
+                    << GetCppVariableType(arg, &message)
+                    << ">";
               }
               out << "(" << msg << ".scalar_value()";
 
@@ -496,7 +519,13 @@
               }
               out << ") : ";
             } else if (arg.type() == TYPE_ENUM) {
-              // TODO: impl
+              // TODO(yim): support this case
+              cerr << __func__ << ":" << __LINE__ << " unknown type "
+                   << arg.type() << "\n";
+            } else if (arg.type() == TYPE_STRING) {
+              // TODO(yim): support this case
+              cerr << __func__ << ":" << __LINE__ << " unknown type "
+                   << arg.type() << "\n";
             } else {
               cerr << __func__ << ":" << __LINE__ << " unknown type "
                    << arg.type() << "\n";
@@ -504,8 +533,8 @@
             }
 
             out << "( (" << msg << ".type() == TYPE_PREDEFINED || " << msg
-                   << ".type() == TYPE_STRUCT || " << msg
-                   << ".type() == TYPE_SCALAR)? ";
+                << ".type() == TYPE_STRUCT || " << msg
+                << ".type() == TYPE_SCALAR)? ";
             out << GetCppInstanceType(arg, msg, &message);
             out << " : " << GetCppInstanceType(arg, string(), &message) << " )";
             // TODO: use the given message and call a lib function which converts
@@ -530,9 +559,9 @@
           out << ";" << "\n";
           if (arg.type() == TYPE_STRUCT) {
             if (message.component_class() == HAL_HIDL) {
-              std::string attribute_name = arg.name();
+              std::string attribute_name = arg.predefined_type();
               ReplaceSubString(attribute_name, "::", "__");
-              out << "    MessageTo" << attribute_name
+              out << "MessageTo" << attribute_name
                   << "(func_msg->arg(" << arg_count
                   << "), &arg" << arg_count << ");\n";
             }
@@ -552,13 +581,13 @@
           api.return_type_hidl_size() > 1 ||
           api.return_type_hidl(0).type() == TYPE_VOID) {
         // TODO(yim): support multiple return values (when size > 1)
-        out << "    *result = NULL;" << "\n";
-        out << "    " << kInstanceVariableName << "->" << api.name() << "(";
+        out << "*result = NULL;" << "\n";
+        out << kInstanceVariableName << "->" << api.name() << "(";
       } else if (api.return_type_hidl_size() == 1 &&
                  api.return_type_hidl(0).type() != TYPE_SCALAR &&
                  api.return_type_hidl(0).type() != TYPE_ENUM) {
-        out << "    *result = NULL;" << "\n";
-        out << "    " << kInstanceVariableName << "->" << api.name() << "(";
+        out << "*result = NULL;" << "\n";
+        out << kInstanceVariableName << "->" << api.name() << "(";
       } else if (api.return_type_hidl(0).type() == TYPE_SCALAR) {
         out << "*result = reinterpret_cast<void*>("
             << "(" << api.return_type_hidl(0).scalar_type() << ")"
@@ -596,27 +625,23 @@
       if (api.return_type_hidl_size() == 0 ||
           api.return_type_hidl(0).type() == TYPE_VOID) {
         out << ");" << "\n";
-      } else if (api.return_type_hidl(0).type() == TYPE_SCALAR ||
-                 api.return_type_hidl(0).type() == TYPE_ENUM) {
-        out << "));"
-               << "\n";
-      } else {
-        if (api.return_type_hidl_size() > 0) {
+      } else if (api.return_type_hidl_size() == 1) {
+        if (api.return_type_hidl(0).type() == TYPE_SCALAR ||
+            api.return_type_hidl(0).type() == TYPE_ENUM) {
+          out << "));"
+              << "\n";
+        } else {
           if (arg_count != 0) out << ", ";
           out << fuzzer_extended_class_name << api.name() << "_cb_func";
-        }
-        if (api.return_type_hidl_size() > 1) {  // return type is void
-          // TODO(yim): support multiple return values
-          out << ");" << "\n";
-        } else if (
-            api.return_type_hidl_size() == 1 &&
-            api.return_type_hidl(0).type() != TYPE_SCALAR &&
-            api.return_type_hidl(0).type() != TYPE_ENUM) {
           // TODO(yim): support non-scalar return type.
           out << ");" << "\n";
-        } else {
-          out << ").toString8().string())));" << "\n";
         }
+      } else {
+        if (arg_count != 0) out << ", ";
+        out << fuzzer_extended_class_name << api.name() << "_cb_func";
+        // return type is void
+        // TODO(yim): support multiple return values
+        out << ");" << "\n";
       }
 
       GenerateCodeToStopMeasurement(out);
@@ -657,20 +682,25 @@
 
         // Message to value converter
         out << attribute.name() << " " << "EnumValue" << attribute_name
-            << "(const EnumDataValueMessage& arg, int index) {" << "\n";
+            << "(const EnumDataValueMessage& arg) {" << "\n";
         out << "  return (" << attribute.name()
-            << ") arg.scalar_value(index)."
+            << ") arg.scalar_value(0)."
             << attribute.enum_value().scalar_type() << "();" << "\n";
         out << "}" << "\n";
 
         // Random value generator
         out << attribute.name() << " " << "Random" << attribute_name << "() {"
             << "\n";
-        out << "int choice = rand() / "
+        out << attribute.enum_value().scalar_type() << " choice = "
+            << "(" << attribute.enum_value().scalar_type() << ") "
+            << "rand() / "
             << attribute.enum_value().enumerator().size() << ";" << "\n";
-        out << "if (choice < 0) choice *= -1;" << "\n";
+        if (attribute.enum_value().scalar_type().find("u") != 0) {
+          out << "if (choice < 0) choice *= -1;" << "\n";
+        }
         for (int index = 0; index < attribute.enum_value().enumerator().size(); index++) {
           out << "if (choice == ";
+          out << "(" << attribute.enum_value().scalar_type() << ") ";
           if (attribute.enum_value().scalar_type() == "int32_t") {
             out << attribute.enum_value().scalar_value(index).int32_t();
           } else if (attribute.enum_value().scalar_type() == "uint32_t") {
@@ -696,6 +726,7 @@
             << "(const VariableSpecificationMessage& var_msg, "
             << attribute.name() << "* arg) {"
             << "\n";
+        out.indent();
         int struct_index = 0;
         for (const auto& struct_value : attribute.struct_value()) {
           if (struct_value.type() == TYPE_SCALAR) {
@@ -796,10 +827,24 @@
           } else if (struct_value.type() == TYPE_ENUM) {
             std::string enum_attribute_name = struct_value.predefined_type();
             ReplaceSubString(enum_attribute_name, "::", "__");
-            out << "    arg->" << struct_value.name() << " = "
+            out << "arg->" << struct_value.name() << " = "
                 << "EnumValue" << enum_attribute_name << "("
                 << "var_msg.struct_value(" << struct_index
                 << ").enum_value());" << "\n";
+          } else if (struct_value.type() == TYPE_STRUCT) {
+            if (struct_value.has_predefined_type()) {
+              std::string struct_attribute_name = struct_value.predefined_type();
+              ReplaceSubString(struct_attribute_name, "::", "__");
+              out << "/*" << struct_value.predefined_type() << "*/";
+              //"arg->" << struct_value.name() << " = "
+              //    << "" << enum_attribute_name << "("
+              //    << "var_msg.struct_value(" << struct_index
+              //    << ").enum_value());" << "\n";
+            } else {
+              cerr << __func__ << ":" << __LINE__ << " ERROR predefined_type "
+                   << "not defined." << "\n";
+              exit(-1);
+            }
           } else {
             cerr << __func__ << ":" << __LINE__ << " ERROR unsupported type "
                  << struct_value.type() << "\n";
@@ -899,7 +944,7 @@
           out << ") : ";
         }
 
-        out << "( (" << msg << ".type() == TYPE_PREDEFINED || " << msg
+        out << "((" << msg << ".type() == TYPE_PREDEFINED || " << msg
             << ".type() == TYPE_STRUCT || " << msg
             << ".type() == TYPE_SCALAR)? ";
         out << GetCppInstanceType(arg, msg);
@@ -914,10 +959,11 @@
     // actual function call
     GenerateCodeToStartMeasurement(out);
 
-    out << "    cout << \"Call an API.\" << endl;" << "\n";
-    out << "    cout << \"local_device = \" << " << kInstanceVariableName
+    out.indent();
+    out << "cout << \"Call an API.\" << endl;" << "\n";
+    out << "cout << \"local_device = \" << " << kInstanceVariableName
         << ".get();" << "\n";
-    out << "    *result = const_cast<void*>(reinterpret_cast<const void*>(new string("
+    out << "*result = const_cast<void*>(reinterpret_cast<const void*>(new string("
         << kInstanceVariableName << "->" << parent_path << message.name()
         << "->" << api.name() << "(";
     if (arg_count > 0) out << "\n";
@@ -939,21 +985,22 @@
     }
     out << ").toString8().string())));" << "\n";
     GenerateCodeToStopMeasurement(out);
-    out << "    cout << \"called\" << endl;" << "\n";
+    out << "cout << \"called\" << endl;" << "\n";
 
     // Copy the output (call by pointer or reference cases).
     arg_count = 0;
     for (auto const& arg : api.arg()) {
       if (arg.is_output()) {
         // TODO check the return value
-        out << "    " << GetConversionToProtobufFunctionName(arg) << "(arg"
+        out << GetConversionToProtobufFunctionName(arg) << "(arg"
             << arg_count << ", "
             << "func_msg->mutable_arg(" << arg_count << "));" << "\n";
       }
       arg_count++;
     }
 
-    out << "    return true;" << "\n";
+    out << "return true;" << "\n";
+    out.unindent();
     out << "  }" << "\n";
   }
   // TODO: if there were pointers, free them.
diff --git a/sysfuzzer/vtscompiler/code_gen/profiler/HalHidlProfilerCodeGen.cpp b/sysfuzzer/vtscompiler/code_gen/profiler/HalHidlProfilerCodeGen.cpp
index bea96d9..165d709 100644
--- a/sysfuzzer/vtscompiler/code_gen/profiler/HalHidlProfilerCodeGen.cpp
+++ b/sysfuzzer/vtscompiler/code_gen/profiler/HalHidlProfilerCodeGen.cpp
@@ -150,6 +150,7 @@
 
   out << "case HidlInstrumentor::CLIENT_API_ENTRY:\n";
   out << "case HidlInstrumentor::SERVER_API_ENTRY:\n";
+  out << "case HidlInstrumentor::PASSTHROUGH_ENTRY:\n";
   out << "{\n";
   out.indent();
   ComponentSpecificationMessage message;
@@ -171,6 +172,7 @@
 
   out << "case HidlInstrumentor::CLIENT_API_EXIT:\n";
   out << "case HidlInstrumentor::SERVER_API_EXIT:\n";
+  out << "case HidlInstrumentor::PASSTHROUGH_EXIT:\n";
   out << "{\n";
   out.indent();
   for (int i = 0; i < method.return_type_hidl().size(); i++) {
@@ -181,7 +183,6 @@
     out << GetCppVariableType(arg, &message) << " *" << result_value
         << " = reinterpret_cast<" << GetCppVariableType(arg, &message)
         << "*> ((*args)[" << i << "]);\n";
-
     GenerateProfilerForTypedVariable(out, arg, result_name,
                                      "(*" + result_value + ")");
   }
@@ -197,7 +198,7 @@
   out << "}\n";
   out.unindent();
   out << "}\n";
-  out << "profiler.AddTraceEvent(package, version, interface, msg);\n";
+  out << "profiler.AddTraceEvent(event, package, version, interface, msg);\n";
   out.unindent();
   out << "}\n";
 }
diff --git a/sysfuzzer/vtscompiler/test/golden/DRIVER/Nfc.driver.cpp b/sysfuzzer/vtscompiler/test/golden/DRIVER/Nfc.driver.cpp
index c9f2aca..b883a71 100644
--- a/sysfuzzer/vtscompiler/test/golden/DRIVER/Nfc.driver.cpp
+++ b/sysfuzzer/vtscompiler/test/golden/DRIVER/Nfc.driver.cpp
@@ -1,5 +1,4 @@
 #include "hardware/interfaces/nfc/1.0/vts/Nfc.vts.h"
-#include "hardware/interfaces/nfc/1.0/vts/types.vts.h"
 #include <hidl/HidlSupport.h>
 #include <iostream>
 #include "vts_datatype.h"
@@ -8,6 +7,7 @@
 #include <android/hardware/nfc/1.0/INfc.h>
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
 #include "hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts.h"
+#include "hardware/interfaces/nfc/1.0/vts/types.vts.h"
 #include <android/hardware/nfc/1.0/types.h>
 using namespace android::hardware::nfc::V1_0;
 namespace android {
@@ -57,11 +57,11 @@
 std::function<void(int32_t)> FuzzerExtended_INfcpowerCycle_cb = FuzzerExtended_INfcpowerCycle_cb_func;
 
 
-bool FuzzerExtended_INfc::GetService() {
+bool FuzzerExtended_INfc::GetService(bool get_stub) {
     static bool initialized = false;
     if (!initialized) {
         cout << "[agent:hal] HIDL getService" << endl;
-        hw_binder_proxy_ = INfc::getService("nfc_nci", false /*get stub*/);
+        hw_binder_proxy_ = INfc::getService("nfc_nci", get_stub);
         cout << "[agent:hal] hw_binder_proxy_ = " << hw_binder_proxy_.get() << endl;
         initialized = true;
     }
diff --git a/sysfuzzer/vtscompiler/test/golden/DRIVER/NfcClientCallback.driver.cpp b/sysfuzzer/vtscompiler/test/golden/DRIVER/NfcClientCallback.driver.cpp
index 064650a..e2c5a95 100644
--- a/sysfuzzer/vtscompiler/test/golden/DRIVER/NfcClientCallback.driver.cpp
+++ b/sysfuzzer/vtscompiler/test/golden/DRIVER/NfcClientCallback.driver.cpp
@@ -1,11 +1,11 @@
 #include "hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts.h"
-#include "hardware/interfaces/nfc/1.0/vts/types.vts.h"
 #include <hidl/HidlSupport.h>
 #include <iostream>
 #include "vts_datatype.h"
 #include "vts_measurement.h"
 #include <hidl/HidlSupport.h>
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
+#include "hardware/interfaces/nfc/1.0/vts/types.vts.h"
 #include <android/hardware/nfc/1.0/types.h>
 using namespace android::hardware::nfc::V1_0;
 namespace android {
diff --git a/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/Nfc.vts.h b/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/Nfc.vts.h
index 633255e..60a8aaa 100644
--- a/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/Nfc.vts.h
+++ b/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/Nfc.vts.h
@@ -10,7 +10,6 @@
 #include <fuzz_tester/FuzzerBase.h>
 #include <fuzz_tester/FuzzerCallbackBase.h>
 #include <android/hardware/nfc/1.0/INfc.h>
-#include <android/hardware/nfc/1.0/types.h>
 #include <android/hardware/nfc/1.0/INfc.h>
 #include <hidl/HidlSupport.h>
 
@@ -27,7 +26,7 @@
               void** result, const string& callback_socket_name);
     bool GetAttribute(FunctionSpecificationMessage* func_msg,
               void** result);
-    bool GetService();
+    bool GetService(bool get_stub);
 
  private:
     sp<INfc> hw_binder_proxy_;
diff --git a/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts.h b/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts.h
index db5cebb..5ed2995 100644
--- a/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts.h
+++ b/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts.h
@@ -10,7 +10,6 @@
 #include <fuzz_tester/FuzzerBase.h>
 #include <fuzz_tester/FuzzerCallbackBase.h>
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
-#include <android/hardware/nfc/1.0/types.h>
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
 #include <hidl/HidlSupport.h>
 
diff --git a/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/types.vts.h b/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/types.vts.h
index b84e903..c7cb4e8 100644
--- a/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/types.vts.h
+++ b/sysfuzzer/vtscompiler/test/golden/DRIVER/hardware/interfaces/nfc/1.0/vts/types.vts.h
@@ -10,7 +10,6 @@
 #include <fuzz_tester/FuzzerBase.h>
 #include <fuzz_tester/FuzzerCallbackBase.h>
 #include <android/hardware/nfc/1.0/types.h>
-#include <android/hardware/nfc/1.0/types.h>
 #include <hidl/HidlSupport.h>
 
 
diff --git a/sysfuzzer/vtscompiler/test/golden/DRIVER/types.driver.cpp b/sysfuzzer/vtscompiler/test/golden/DRIVER/types.driver.cpp
index a19f3f6..3f55471 100644
--- a/sysfuzzer/vtscompiler/test/golden/DRIVER/types.driver.cpp
+++ b/sysfuzzer/vtscompiler/test/golden/DRIVER/types.driver.cpp
@@ -1,5 +1,4 @@
 #include "hardware/interfaces/nfc/1.0/vts/types.vts.h"
-#include "hardware/interfaces/nfc/1.0/vts/types.vts.h"
 #include <hidl/HidlSupport.h>
 #include <iostream>
 #include "vts_datatype.h"
@@ -12,32 +11,30 @@
 
 
 
-::android::hardware::nfc::V1_0::NfcEvent EnumValue__android__hardware__nfc__V1_0__NfcEvent(const EnumDataValueMessage& arg, int index) {
-  return (::android::hardware::nfc::V1_0::NfcEvent) arg.scalar_value(index).uint32_t();
+::android::hardware::nfc::V1_0::NfcEvent EnumValue__android__hardware__nfc__V1_0__NfcEvent(const EnumDataValueMessage& arg) {
+  return (::android::hardware::nfc::V1_0::NfcEvent) arg.scalar_value(0).uint32_t();
 }
 ::android::hardware::nfc::V1_0::NfcEvent Random__android__hardware__nfc__V1_0__NfcEvent() {
-int choice = rand() / 7;
-if (choice < 0) choice *= -1;
-if (choice == 0) return ::android::hardware::nfc::V1_0::NfcEvent::OPEN_CPLT;
-if (choice == 1) return ::android::hardware::nfc::V1_0::NfcEvent::CLOSE_CPLT;
-if (choice == 2) return ::android::hardware::nfc::V1_0::NfcEvent::POST_INIT_CPLT;
-if (choice == 3) return ::android::hardware::nfc::V1_0::NfcEvent::PRE_DISCOVER_CPLT;
-if (choice == 4) return ::android::hardware::nfc::V1_0::NfcEvent::REQUEST_CONTROL;
-if (choice == 5) return ::android::hardware::nfc::V1_0::NfcEvent::RELEASE_CONTROL;
-if (choice == 6) return ::android::hardware::nfc::V1_0::NfcEvent::ERROR;
+uint32_t choice = (uint32_t) rand() / 7;
+if (choice == (uint32_t) 0) return ::android::hardware::nfc::V1_0::NfcEvent::OPEN_CPLT;
+if (choice == (uint32_t) 1) return ::android::hardware::nfc::V1_0::NfcEvent::CLOSE_CPLT;
+if (choice == (uint32_t) 2) return ::android::hardware::nfc::V1_0::NfcEvent::POST_INIT_CPLT;
+if (choice == (uint32_t) 3) return ::android::hardware::nfc::V1_0::NfcEvent::PRE_DISCOVER_CPLT;
+if (choice == (uint32_t) 4) return ::android::hardware::nfc::V1_0::NfcEvent::REQUEST_CONTROL;
+if (choice == (uint32_t) 5) return ::android::hardware::nfc::V1_0::NfcEvent::RELEASE_CONTROL;
+if (choice == (uint32_t) 6) return ::android::hardware::nfc::V1_0::NfcEvent::ERROR;
     return ::android::hardware::nfc::V1_0::NfcEvent::OPEN_CPLT;
 }
-::android::hardware::nfc::V1_0::NfcStatus EnumValue__android__hardware__nfc__V1_0__NfcStatus(const EnumDataValueMessage& arg, int index) {
-  return (::android::hardware::nfc::V1_0::NfcStatus) arg.scalar_value(index).uint32_t();
+::android::hardware::nfc::V1_0::NfcStatus EnumValue__android__hardware__nfc__V1_0__NfcStatus(const EnumDataValueMessage& arg) {
+  return (::android::hardware::nfc::V1_0::NfcStatus) arg.scalar_value(0).uint32_t();
 }
 ::android::hardware::nfc::V1_0::NfcStatus Random__android__hardware__nfc__V1_0__NfcStatus() {
-int choice = rand() / 5;
-if (choice < 0) choice *= -1;
-if (choice == 0) return ::android::hardware::nfc::V1_0::NfcStatus::OK;
-if (choice == 1) return ::android::hardware::nfc::V1_0::NfcStatus::FAILED;
-if (choice == 2) return ::android::hardware::nfc::V1_0::NfcStatus::ERR_TRANSPORT;
-if (choice == 3) return ::android::hardware::nfc::V1_0::NfcStatus::ERR_CMD_TIMEOUT;
-if (choice == 4) return ::android::hardware::nfc::V1_0::NfcStatus::REFUSED;
+uint32_t choice = (uint32_t) rand() / 5;
+if (choice == (uint32_t) 0) return ::android::hardware::nfc::V1_0::NfcStatus::OK;
+if (choice == (uint32_t) 1) return ::android::hardware::nfc::V1_0::NfcStatus::FAILED;
+if (choice == (uint32_t) 2) return ::android::hardware::nfc::V1_0::NfcStatus::ERR_TRANSPORT;
+if (choice == (uint32_t) 3) return ::android::hardware::nfc::V1_0::NfcStatus::ERR_CMD_TIMEOUT;
+if (choice == (uint32_t) 4) return ::android::hardware::nfc::V1_0::NfcStatus::REFUSED;
     return ::android::hardware::nfc::V1_0::NfcStatus::OK;
 }
 }  // namespace vts
diff --git a/sysfuzzer/vtscompiler/test/golden/PROFILER/Nfc.profiler.cpp b/sysfuzzer/vtscompiler/test/golden/PROFILER/Nfc.profiler.cpp
index f967562..6f0f575 100644
--- a/sysfuzzer/vtscompiler/test/golden/PROFILER/Nfc.profiler.cpp
+++ b/sysfuzzer/vtscompiler/test/golden/PROFILER/Nfc.profiler.cpp
@@ -41,6 +41,7 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 auto *arg_0 = msg.add_arg();
                 INfcClientCallback *arg_val_0 = reinterpret_cast<INfcClientCallback*> ((*args)[0]);
@@ -49,6 +50,7 @@
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -62,7 +64,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "write") == 0) {
         FunctionSpecificationMessage msg;
@@ -70,6 +72,7 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 auto *arg_0 = msg.add_arg();
                 ::android::hardware::hidl_vec<uint8_t> *arg_val_0 = reinterpret_cast<::android::hardware::hidl_vec<uint8_t>*> ((*args)[0]);
@@ -82,6 +85,7 @@
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -95,7 +99,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "coreInitialized") == 0) {
         FunctionSpecificationMessage msg;
@@ -103,6 +107,7 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 auto *arg_0 = msg.add_arg();
                 ::android::hardware::hidl_vec<uint8_t> *arg_val_0 = reinterpret_cast<::android::hardware::hidl_vec<uint8_t>*> ((*args)[0]);
@@ -115,6 +120,7 @@
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -128,7 +134,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "prediscover") == 0) {
         FunctionSpecificationMessage msg;
@@ -136,11 +142,13 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 break;
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -154,7 +162,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "close") == 0) {
         FunctionSpecificationMessage msg;
@@ -162,11 +170,13 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 break;
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -180,7 +190,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "controlGranted") == 0) {
         FunctionSpecificationMessage msg;
@@ -188,11 +198,13 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 break;
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -206,7 +218,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "powerCycle") == 0) {
         FunctionSpecificationMessage msg;
@@ -214,11 +226,13 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 break;
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 auto *result_0 = msg.add_return_type_hidl();
                 int32_t *result_val_0 = reinterpret_cast<int32_t*> ((*args)[0]);
@@ -232,7 +246,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
 }
 
diff --git a/sysfuzzer/vtscompiler/test/golden/PROFILER/NfcClientCallback.profiler.cpp b/sysfuzzer/vtscompiler/test/golden/PROFILER/NfcClientCallback.profiler.cpp
index 6f4eaaf..fa321d6 100644
--- a/sysfuzzer/vtscompiler/test/golden/PROFILER/NfcClientCallback.profiler.cpp
+++ b/sysfuzzer/vtscompiler/test/golden/PROFILER/NfcClientCallback.profiler.cpp
@@ -41,6 +41,7 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 auto *arg_0 = msg.add_arg();
                 ::android::hardware::nfc::V1_0::NfcEvent *arg_val_0 = reinterpret_cast<::android::hardware::nfc::V1_0::NfcEvent*> ((*args)[0]);
@@ -54,6 +55,7 @@
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 break;
             }
@@ -63,7 +65,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
     if (strcmp(method, "sendData") == 0) {
         FunctionSpecificationMessage msg;
@@ -71,6 +73,7 @@
         switch (event) {
             case HidlInstrumentor::CLIENT_API_ENTRY:
             case HidlInstrumentor::SERVER_API_ENTRY:
+            case HidlInstrumentor::PASSTHROUGH_ENTRY:
             {
                 auto *arg_0 = msg.add_arg();
                 ::android::hardware::hidl_vec<uint8_t> *arg_val_0 = reinterpret_cast<::android::hardware::hidl_vec<uint8_t>*> ((*args)[0]);
@@ -83,6 +86,7 @@
             }
             case HidlInstrumentor::CLIENT_API_EXIT:
             case HidlInstrumentor::SERVER_API_EXIT:
+            case HidlInstrumentor::PASSTHROUGH_EXIT:
             {
                 break;
             }
@@ -92,7 +96,7 @@
                 break;
             }
         }
-        profiler.AddTraceEvent(package, version, interface, msg);
+        profiler.AddTraceEvent(event, package, version, interface, msg);
     }
 }
 
diff --git a/testcases/hal/common/fuzz/Android.hal_fuzzer.mk b/testcases/hal/common/fuzz/Android.hal_fuzzer.mk
index d48a237..8262c29 100644
--- a/testcases/hal/common/fuzz/Android.hal_fuzzer.mk
+++ b/testcases/hal/common/fuzz/Android.hal_fuzzer.mk
@@ -14,6 +14,8 @@
 # limitations under the License.
 #
 
+include $(CLEAR_VARS)
+
 # TODO(trong): enable for mips and x86.
 ifeq (,$(findstring mips, $(TARGET_ARCH)))
 ifeq (,$(findstring x86, $(TARGET_ARCH)))
@@ -33,6 +35,7 @@
 LOCAL_SHARED_LIBRARIES := \
     $(module_shared_libraries) \
     libutils \
+    libhidl \
     libhardware \
 
 LOCAL_ARM_MODE := arm
diff --git a/testcases/hal/nfc/hidl/host/Android.mk b/testcases/hal/nfc/hidl/host/Android.mk
index 6d45159..f9e3276 100644
--- a/testcases/hal/nfc/hidl/host/Android.mk
+++ b/testcases/hal/nfc/hidl/host/Android.mk
@@ -16,8 +16,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := NfcHidlBasicTest
-VTS_CONFIG_SRC_DIR := testcases/hal/nfc/hidl/host
-include test/vts/tools/build/Android.host_config.mk
+include $(call all-subdir-makefiles)
diff --git a/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py b/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py
index 4ce50c2..7af626e 100644
--- a/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py
+++ b/testcases/hal/nfc/hidl/host/NfcHidlBasicTest.py
@@ -24,15 +24,30 @@
 from vts.runners.host import test_runner
 from vts.utils.python.controllers import android_device
 
+PASSTHROUGH_MODE_KEY = "passthrough_mode"
+
 
 class NfcHidlBasicTest(base_test_with_webdb.BaseTestWithWebDbClass):
     """A simple testcase for the NFC HIDL HAL."""
 
-    _TREBLE_DEVICE_NAME_SUFFIX = "_treble"
-
     def setUpClass(self):
         """Creates a mirror and turns on the framework-layer NFC service."""
         self.dut = self.registerController(android_device)[0]
+
+        self.getUserParams(opt_param_names=[PASSTHROUGH_MODE_KEY])
+
+        self.dut.shell.InvokeTerminal("one")
+        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
+        self.dut.shell.one.Execute("service call nfc 4")  # Turn off
+        self.dut.shell.one.Execute("service call nfc 5")  # Turn on
+
+        if getattr(self, PASSTHROUGH_MODE_KEY, True):
+            self.dut.shell.one.Execute(
+                "setprop vts.hal.vts.hidl.get_stub true")
+        else:
+            self.dut.shell.one.Execute(
+                "setprop vts.hal.vts.hidl.get_stub false")
+
         self.dut.hal.InitHidlHal(target_type="nfc",
                                  target_basepaths=["/system/lib64"],
                                  target_version=1.0,
@@ -40,21 +55,12 @@
                                  target_component_name="INfc",
                                  bits=64)
 
-        self.dut.shell.InvokeTerminal("one")
-        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
-        self.dut.shell.one.Execute("service call nfc 4")  # Turn off
-        self.dut.shell.one.Execute("service call nfc 5")  # Turn on
-
     def tearDownClass(self):
         """Turns off the framework-layer NFC service."""
         self.dut.shell.one.Execute("service call nfc 4")
 
     def testBase(self):
         """A simple test case which just calls each registered function."""
-        asserts.skipIf(
-            not self.dut.model.endswith(self._TREBLE_DEVICE_NAME_SUFFIX),
-            "a non-Treble device.")
-
         # TODO: extend to make realistic testcases
         # For example, call after CORE_INIT_RSP is received.
         # result = self.dut.hal.nfc.coreInitialized([1])
diff --git a/testcases/hal/nfc/hidl/host/binderize/Android.mk b/testcases/hal/nfc/hidl/host/binderize/Android.mk
new file mode 100644
index 0000000..cd58d32
--- /dev/null
+++ b/testcases/hal/nfc/hidl/host/binderize/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := NfcHidlBinderizeBasicTest
+VTS_CONFIG_SRC_DIR := testcases/hal/nfc/hidl/host/binderize
+include test/vts/tools/build/Android.host_config.mk
diff --git a/testcases/hal/nfc/hidl/host/AndroidTest.xml b/testcases/hal/nfc/hidl/host/binderize/AndroidTest.xml
similarity index 87%
copy from testcases/hal/nfc/hidl/host/AndroidTest.xml
copy to testcases/hal/nfc/hidl/host/binderize/AndroidTest.xml
index 711e98a..f7d0d9b 100644
--- a/testcases/hal/nfc/hidl/host/AndroidTest.xml
+++ b/testcases/hal/nfc/hidl/host/binderize/AndroidTest.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for VTS HAL NFC test cases">
+<configuration description="Config for VTS HAL NFC (Binder Mode) test cases">
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
         <option name="push-group" value="HidlHalTest.push" />
         <option name="cleanup" value="true" />
@@ -24,5 +24,6 @@
     <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
     <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
         <option name="test-case-path" value="vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest" />
+        <option name="test-config-path" value="vts-config/testcases/hal/nfc/hidl/host/binderize/NfcHidlBinderizeBasicTest.config" />
     </test>
 </configuration>
diff --git a/testcases/hal/nfc/hidl/host/binderize/NfcHidlBinderizeBasicTest.config b/testcases/hal/nfc/hidl/host/binderize/NfcHidlBinderizeBasicTest.config
new file mode 100644
index 0000000..5a94c6f
--- /dev/null
+++ b/testcases/hal/nfc/hidl/host/binderize/NfcHidlBinderizeBasicTest.config
@@ -0,0 +1,3 @@
+{
+    "passthrough_mode": False
+}
diff --git a/testcases/hal/nfc/hidl/host/passthrough/Android.mk b/testcases/hal/nfc/hidl/host/passthrough/Android.mk
new file mode 100644
index 0000000..e274107
--- /dev/null
+++ b/testcases/hal/nfc/hidl/host/passthrough/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := NfcHidlPassthroughBasicTest
+VTS_CONFIG_SRC_DIR := testcases/hal/nfc/hidl/host/passthrough
+include test/vts/tools/build/Android.host_config.mk
diff --git a/testcases/hal/nfc/hidl/host/AndroidTest.xml b/testcases/hal/nfc/hidl/host/passthrough/AndroidTest.xml
similarity index 87%
rename from testcases/hal/nfc/hidl/host/AndroidTest.xml
rename to testcases/hal/nfc/hidl/host/passthrough/AndroidTest.xml
index 711e98a..f27a29d 100644
--- a/testcases/hal/nfc/hidl/host/AndroidTest.xml
+++ b/testcases/hal/nfc/hidl/host/passthrough/AndroidTest.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for VTS HAL NFC test cases">
+<configuration description="Config for VTS HAL NFC (Passthrough) test cases">
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
         <option name="push-group" value="HidlHalTest.push" />
         <option name="cleanup" value="true" />
@@ -24,5 +24,6 @@
     <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
     <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
         <option name="test-case-path" value="vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest" />
+        <option name="test-config-path" value="vts-config/testcases/hal/nfc/hidl/host/passthrough/NfcHidlPassthroughBasicTest.config" />
     </test>
 </configuration>
diff --git a/testcases/hal/nfc/hidl/host/passthrough/NfcHidlPassthroughBasicTest.config b/testcases/hal/nfc/hidl/host/passthrough/NfcHidlPassthroughBasicTest.config
new file mode 100644
index 0000000..eeb11f5
--- /dev/null
+++ b/testcases/hal/nfc/hidl/host/passthrough/NfcHidlPassthroughBasicTest.config
@@ -0,0 +1,3 @@
+{
+    "passthrough_mode": True
+}
diff --git a/testcases/hal/sensors/Android.mk b/testcases/hal/sensors/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/testcases/hal/sensors/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/testcases/hal/sensors/__init__.py b/testcases/hal/sensors/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testcases/hal/sensors/__init__.py
diff --git a/testcases/hal/sensors/fuzz/Android.mk b/testcases/hal/sensors/fuzz/Android.mk
new file mode 100644
index 0000000..379ff65
--- /dev/null
+++ b/testcases/hal/sensors/fuzz/Android.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+module_name := ISensorsFlush_fuzzer
+module_src_files := ISensorsFlush_fuzzer.cpp
+module_shared_libraries := android.hardware.sensors@1.0
+include test/vts/testcases/hal/common/fuzz/Android.hal_fuzzer.mk
+
+include $(CLEAR_VARS)
+module_name := ISensorsPoll_fuzzer
+module_src_files := ISensorsPoll_fuzzer.cpp
+module_shared_libraries := android.hardware.sensors@1.0
+include test/vts/testcases/hal/common/fuzz/Android.hal_fuzzer.mk
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ISensorsFuzzTest
+VTS_CONFIG_SRC_DIR := testcases/hal/sensors/fuzz
+include test/vts/tools/build/Android.host_config.mk
diff --git a/testcases/hal/nfc/hidl/host/AndroidTest.xml b/testcases/hal/sensors/fuzz/AndroidTest.xml
similarity index 60%
copy from testcases/hal/nfc/hidl/host/AndroidTest.xml
copy to testcases/hal/sensors/fuzz/AndroidTest.xml
index 711e98a..ce29b2e 100644
--- a/testcases/hal/nfc/hidl/host/AndroidTest.xml
+++ b/testcases/hal/sensors/fuzz/AndroidTest.xml
@@ -13,16 +13,17 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for VTS HAL NFC test cases">
+<configuration description="Config for VTS Sensors HIDL HAL's target-side fuzz test cases">
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
-        <option name="push-group" value="HidlHalTest.push" />
-        <option name="cleanup" value="true" />
-        <option name="push" value="spec/hardware/interfaces/nfc/1.0/vts/Nfc.vts->/data/local/tmp/spec/Nfc.vts" />
-        <option name="push" value="spec/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts->/data/local/tmp/spec/NfcClientCallback.vts" />
-        <option name="push" value="spec/hardware/interfaces/nfc/1.0/vts/types.vts->/data/local/tmp/spec/types.vts" />
+        <option name="push-group" value="LLVMFuzzerTest.push" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
     <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-        <option name="test-case-path" value="vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest" />
+        <option name="test-module-name" value="ISensorsFuzzTest" />
+        <option name="binary-test-sources" value="
+            hal_fuzz/ISensorsFlush_fuzzer,
+            hal_fuzz/ISensorsPoll_fuzzer
+            "/>
+        <option name="binary-test-type" value="llvmfuzzer" />
     </test>
 </configuration>
diff --git a/testcases/hal/sensors/fuzz/ISensorsFlush_fuzzer.cpp b/testcases/hal/sensors/fuzz/ISensorsFlush_fuzzer.cpp
new file mode 100644
index 0000000..fab94be
--- /dev/null
+++ b/testcases/hal/sensors/fuzz/ISensorsFlush_fuzzer.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <FuzzerInterface.h>
+#include <android/hardware/sensors/1.0/ISensors.h>
+
+using ::android::hardware::sensors::V1_0::ISensors;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  static ::android::sp<ISensors> sensors_hal = ISensors::getService("sensors", true);
+  if (sensors_hal == nullptr) {
+    return 0;
+  }
+  if (size < sizeof(int32_t)) {
+    return 0;
+  }
+  int32_t sensorHandle;
+  memcpy(&sensorHandle, data, sizeof(int32_t));
+
+  sensors_hal->flush(sensorHandle);
+  return 0;
+}
diff --git a/testcases/hal/sensors/fuzz/ISensorsPoll_fuzzer.cpp b/testcases/hal/sensors/fuzz/ISensorsPoll_fuzzer.cpp
new file mode 100644
index 0000000..da3f0d7
--- /dev/null
+++ b/testcases/hal/sensors/fuzz/ISensorsPoll_fuzzer.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include <FuzzerInterface.h>
+#include <android/hardware/sensors/1.0/ISensors.h>
+
+using ::android::hardware::sensors::V1_0::ISensors;
+
+auto _hidl_cb = [](auto x, auto y, auto z){};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  static ::android::sp<ISensors> sensors_hal = ISensors::getService("sensors", true);
+  if (sensors_hal == nullptr) {
+    return 0;
+  }
+  if (size < sizeof(int32_t)) {
+    return 0;
+  }
+  int32_t maxCount;
+  memcpy(&maxCount, data, sizeof(int32_t));
+
+  sensors_hal->poll(maxCount, _hidl_cb);
+  return 0;
+}
diff --git a/testcases/hal/vibrator/hidl/host/Android.mk b/testcases/hal/vibrator/hidl/host/Android.mk
index 5e628d2..d005450 100644
--- a/testcases/hal/vibrator/hidl/host/Android.mk
+++ b/testcases/hal/vibrator/hidl/host/Android.mk
@@ -20,4 +20,4 @@
 
 LOCAL_MODULE := VibratorHidlTest
 VTS_CONFIG_SRC_DIR := testcases/hal/vibrator/hidl/host
-include test/vts/tools/build/Android.host_config.mk
+include test/vts/tools/build/Android.host_config.mk
\ No newline at end of file
diff --git a/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py b/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py
index bbd8006..0007d89 100644
--- a/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py
+++ b/testcases/hal/vibrator/hidl/host/VibratorHidlTest.py
@@ -22,16 +22,26 @@
 from vts.runners.host import base_test_with_webdb
 from vts.runners.host import test_runner
 from vts.utils.python.controllers import android_device
+from vts.utils.python.profiling import profiling_utils
 
 
 class VibratorHidlTest(base_test_with_webdb.BaseTestWithWebDbClass):
     """A simple testcase for the VIBRATOR HIDL HAL."""
 
-    _TREBLE_DEVICE_NAME_SUFFIX = "_treble"
-
     def setUpClass(self):
         """Creates a mirror and turns on the framework-layer VIBRATOR service."""
         self.dut = self.registerController(android_device)[0]
+
+        self.dut.shell.InvokeTerminal("one")
+        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
+
+        # Test using the binderized mode
+        self.dut.shell.one.Execute(
+            "setprop vts.hal.vts.hidl.get_stub true")
+
+        if getattr(self, self.ENABLE_PROFILING, False):
+            profiling_utils.EnableVTSProfiling(self.dut.shell.one)
+
         self.dut.hal.InitHidlHal(
             target_type="vibrator",
             target_basepaths=["/system/lib64"],
@@ -40,15 +50,18 @@
             target_component_name="IVibrator",
             bits=64)
 
-        self.dut.shell.InvokeTerminal("one")
-        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
+    def tearDownClass(self):
+        """ If profiling is enabled for the test, collect the profiling data
+            and disable profiling after the test is done.
+        """
+        if getattr(self, self.ENABLE_PROFILING, False):
+            profiling_trace_path = getattr(
+                self, self.VTS_PROFILING_TRACING_PATH, "")
+            self.ProcessAndUploadTraceData(self.dut, profiling_trace_path)
+            profiling_utils.DisableVTSProfiling(self.dut.shell.one)
 
     def testVibratorBasic(self):
         """A simple test case which just calls each registered function."""
-        asserts.skipIf(
-                not self.dut.model.endswith(self._TREBLE_DEVICE_NAME_SUFFIX),
-                "a non-Treble device.")
-
         vibrator_types = self.dut.hal.vibrator.GetHidlTypeInterface("types")
         logging.info("vibrator_types: %s", vibrator_types)
         logging.info("OK: %s", vibrator_types.OK)
diff --git a/testcases/hal/vibrator/hidl/host_profiling/Android.mk b/testcases/hal/vibrator/hidl/host_profiling/Android.mk
new file mode 100644
index 0000000..ec73e06
--- /dev/null
+++ b/testcases/hal/vibrator/hidl/host_profiling/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VibratorHidlProfilingTest
+VTS_CONFIG_SRC_DIR := testcases/hal/vibrator/hidl/host_profiling
+include test/vts/tools/build/Android.host_config.mk
diff --git a/testcases/hal/nfc/hidl/host/AndroidTest.xml b/testcases/hal/vibrator/hidl/host_profiling/AndroidTest.xml
similarity index 62%
copy from testcases/hal/nfc/hidl/host/AndroidTest.xml
copy to testcases/hal/vibrator/hidl/host_profiling/AndroidTest.xml
index 711e98a..c214d1f 100644
--- a/testcases/hal/nfc/hidl/host/AndroidTest.xml
+++ b/testcases/hal/vibrator/hidl/host_profiling/AndroidTest.xml
@@ -13,16 +13,17 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for VTS HAL NFC test cases">
+<configuration description="Config for VTS HAL vibrator test cases">
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
         <option name="push-group" value="HidlHalTest.push" />
         <option name="cleanup" value="true" />
-        <option name="push" value="spec/hardware/interfaces/nfc/1.0/vts/Nfc.vts->/data/local/tmp/spec/Nfc.vts" />
-        <option name="push" value="spec/hardware/interfaces/nfc/1.0/vts/NfcClientCallback.vts->/data/local/tmp/spec/NfcClientCallback.vts" />
-        <option name="push" value="spec/hardware/interfaces/nfc/1.0/vts/types.vts->/data/local/tmp/spec/types.vts" />
+        <option name="push" value="spec/hardware/interfaces/vibrator/1.0/vts/Vibrator.vts->/data/local/tmp/spec/Vibrator.vts" />
+        <option name="push" value="spec/hardware/interfaces/vibrator/1.0/vts/types.vts->/data/local/tmp/spec/types.vts" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
     <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-        <option name="test-case-path" value="vts/testcases/hal/nfc/hidl/host/NfcHidlBasicTest" />
+        <option name="test-module-name" value="VibratorHidlProfilingTest" />
+        <option name="test-case-path" value="vts/testcases/hal/vibrator/hidl/host/VibratorHidlTest" />
+        <option name="test-config-path" value="vts-config/testcases/hal/vibrator/hidl/host_profiling/VibratorHidlProfilingTest.config" />
     </test>
 </configuration>
diff --git a/testcases/hal/vibrator/hidl/host_profiling/VibratorHidlProfilingTest.config b/testcases/hal/vibrator/hidl/host_profiling/VibratorHidlProfilingTest.config
new file mode 100644
index 0000000..912d8d5
--- /dev/null
+++ b/testcases/hal/vibrator/hidl/host_profiling/VibratorHidlProfilingTest.config
@@ -0,0 +1,3 @@
+{
+    "enable_profiling": true
+}
\ No newline at end of file
diff --git a/testcases/template/llvmfuzzer_test/llvmfuzzer_test.py b/testcases/template/llvmfuzzer_test/llvmfuzzer_test.py
index 2dafcf5..eb0e5b9 100644
--- a/testcases/template/llvmfuzzer_test/llvmfuzzer_test.py
+++ b/testcases/template/llvmfuzzer_test/llvmfuzzer_test.py
@@ -76,20 +76,19 @@
         self._dut.adb.push("%s %s" % (push_src, config.FUZZER_TEST_DIR))
         logging.info("Adb pushed: %s", testcase)
 
-    # TODO(trong): save crash-causing inputs to the fuzzer.
     def RunTestcase(self, testcase):
         """Runs the given testcase and asserts the result.
 
         Args:
-            testcase: string, path to executable fuzzer.
+            testcase: string, path to fuzzer executable.
         """
         self.PushFiles(testcase)
-        testcase = testcase.split("/")[-1]
+        fuzzer = testcase.split("/")[-1]
 
-        chmod_cmd = "chmod -R 755 %s" % os.path.join(config.FUZZER_TEST_DIR, testcase)
-        cd_cmd = "cd %s" % os.path.join(config.FUZZER_TEST_DIR)
-        test_cmd = "./%s" % testcase
+        chmod_cmd = "chmod -R 755 %s" % os.path.join(config.FUZZER_TEST_DIR, fuzzer)
+        cd_cmd = "cd %s" % config.FUZZER_TEST_DIR
         ld_path = "LD_LIBRARY_PATH=/data/local/tmp/32:/data/local/tmp/64:$LD_LIBRARY_PATH"
+        test_cmd = "./%s" % fuzzer
 
         cmd = [
             chmod_cmd,
@@ -98,10 +97,35 @@
         logging.info("Executing: %s", cmd)
 
         result = self._shell.Execute(cmd)
-        self.AssertTestResult(result)
+        self.AssertTestResult(fuzzer, result)
+
+    def LogCrashReport(self, fuzzer):
+        """Logs crash-causing fuzzer input.
+
+        Reads the crash report file and logs the contents in format:
+        "\x01\x23\x45\x67\x89\xab\xcd\xef"
+
+        Args:
+            fuzzer: string, name of fuzzer executable.
+        """
+        cmd = "xxd -p %s" % config.FUZZER_TEST_CRASH_REPORT
+
+        # output is string of a hexdump from crash report file.
+        # From the example above, output would be "0123456789abcdef".
+        output = self._shell.Execute(cmd)[const.STDOUT][0]
+        remove_chars = ["\r", "\t", "\n", " "]
+        for char in remove_chars:
+            output = output.replace(char, "")
+
+        crash_report = ""
+        # output is guaranteed to be even in length since its a hexdump.
+        for offset in xrange(0, len(output), 2):
+            crash_report += "\\x%s" % output[offset:offset + 2]
+
+        logging.info("FUZZER_TEST_CRASH_REPORT for %s: '%s'", fuzzer, crash_report)
 
     # TODO(trong): differentiate between crashes and sanitizer rule violations.
-    def AssertTestResult(self, result):
+    def AssertTestResult(self, fuzzer, result):
         """Asserts that testcase finished as expected.
 
         Checks that device is in responsive state. If not, waits for boot
@@ -109,23 +133,25 @@
         returned exit code 0.
 
         Args:
+            fuzzer: string, name of fuzzer executable.
             result: dict([str],[str],[int]), command results from shell.
         """
-        if self._dut.hasBooted():
-            exit_codes = result[const.EXIT_CODE]
-            logging.info("EXIT_CODE: %s", exit_codes)
-            asserts.assertFalse(
-                any(exit_codes), "Test case failed.")
-        else:
+        if not self._dut.hasBooted():
             self._dut.waitForBootCompletion()
-            asserts.fail("Test case left the device in unresponsive state.")
+            asserts.fail("%s left the device in unresponsive state." % fuzzer)
+
+        # Last exit code is the exit code of the fuzzer executable.
+        exit_code = result[const.EXIT_CODE][-1]
+        if exit_code == config.ExitCode.FUZZER_TEST_FAIL:
+            self.LogCrashReport(fuzzer)
+            asserts.fail("%s failed" % fuzzer)
 
     def generateFuzzerTests(self):
         """Runs fuzzer tests."""
         self.runGeneratedTests(
             test_func=self.RunTestcase,
             settings=self._testcases,
-            name_func=lambda x: x.replace('/','_'))
+            name_func=lambda x: x.split("/")[-1])
 
 
 if __name__ == "__main__":
diff --git a/testcases/template/llvmfuzzer_test/llvmfuzzer_test_config.py b/testcases/template/llvmfuzzer_test/llvmfuzzer_test_config.py
index d4757d3..1407f76 100644
--- a/testcases/template/llvmfuzzer_test/llvmfuzzer_test_config.py
+++ b/testcases/template/llvmfuzzer_test/llvmfuzzer_test_config.py
@@ -15,13 +15,21 @@
 # limitations under the License.
 #
 
+class ExitCode(object):
+    """Exit codes for test binaries."""
+    FUZZER_TEST_PASS = 0
+    FUZZER_TEST_FAIL = 77
 
 # Directory on the target where the tests are copied.
 FUZZER_TEST_DIR = "/data/local/tmp/llvmfuzzer_test"
 
+# File used to save crash-causing fuzzer input.
+FUZZER_TEST_CRASH_REPORT = FUZZER_TEST_DIR + "/crash_report"
+
 # Default parameters that will be passed to fuzzer executable.
 FUZZER_PARAMS = {
     "max_len": 64,
-    "max_total_time": 10
+    "max_total_time": 10,
+    "exact_artifact_path": FUZZER_TEST_CRASH_REPORT
 }
 
diff --git a/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk b/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk
index c833c70..a26074e 100644
--- a/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk
+++ b/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk
@@ -19,6 +19,7 @@
   libvts_driver_hidl_nfc@1.0 \
   libvts_profiler_hidl_nfc@1.0 \
   libvts_driver_hidl_vibrator@1.0 \
+  libvts_profiler_hidl_vibrator@1.0 \
 
 vts_test_lib_hidl_packages += \
   nfc_hidl_hal_test \
diff --git a/tools/vts-tradefed/res/config/vts-hal-hidl-profiling.xml b/tools/vts-tradefed/res/config/vts-hal-hidl-profiling.xml
new file mode 100644
index 0000000..96d651a
--- /dev/null
+++ b/tools/vts-tradefed/res/config/vts-hal-hidl-profiling.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Run VTS HIDL HAL Tests with profiling">
+    <include name="everything" />
+    <option name="plan" value="vts" />
+    <option name="compatibility:include-filter" value="VibratorHidlProfilingTest" />
+  <template-include name="reporters" default="basic-reporters" />
+</configuration>
\ No newline at end of file
diff --git a/tools/vts-tradefed/res/config/vts-hal-hidl.xml b/tools/vts-tradefed/res/config/vts-hal-hidl.xml
index c222f69..ba55cd0 100644
--- a/tools/vts-tradefed/res/config/vts-hal-hidl.xml
+++ b/tools/vts-tradefed/res/config/vts-hal-hidl.xml
@@ -21,6 +21,8 @@
     <option name="compatibility:include-filter" value="BinderPerformanceTest" />
     <option name="compatibility:include-filter" value="HwBinderBinderizePerformanceTest" />
     <option name="compatibility:include-filter" value="HwBinderPassthroughPerformanceTest" />
-    <option name="compatibility:include-filter" value="NfcHidlBasicTest" />
+    <option name="compatibility:include-filter" value="NfcHidlBinderizeBasicTest" />
+    <option name="compatibility:include-filter" value="NfcHidlPassthroughBasicTest" />
+
   <template-include name="reporters" default="basic-reporters" />
 </configuration>
diff --git a/tools/vts-tradefed/res/config/vts-serving-pinned.xml b/tools/vts-tradefed/res/config/vts-serving-pinned.xml
index 626afd7..d211266 100644
--- a/tools/vts-tradefed/res/config/vts-serving-pinned.xml
+++ b/tools/vts-tradefed/res/config/vts-serving-pinned.xml
@@ -18,7 +18,7 @@
     <option name="plan" value="vts" />
     <!-- For vts-kernel -->
     <option name="compatibility:include-filter" value="KernelLtpTest" />
-    <option name="compatibility:include-filter" value="LinuxKselftestTest" />
+    <option name="compatibility:include-filter" value="LinuxKselftestTestPresubmit" />
 
     <template-include name="reporters" default="basic-reporters" />
 </configuration>
diff --git a/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl.xml b/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl.xml
index 7be0e50..63f30df 100644
--- a/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl.xml
+++ b/tools/vts-tradefed/res/config/vts-serving-staging-hal-hidl.xml
@@ -21,8 +21,10 @@
     <option name="compatibility:include-filter" value="HwBinderThroughputBenchmark" />
     <option name="compatibility:include-filter" value="HwBinderBinderizePerformanceTest" />
     <option name="compatibility:include-filter" value="HwBinderPassthroughPerformanceTest" />
-    <option name="compatibility:include-filter" value="NfcHidlBasicTest" />
-    <option name="compatibility:include-filter" value="VibratorHidlTest" />
+    <option name="compatibility:include-filter" value="NfcHidlBinderizeBasicTest" />
+    <option name="compatibility:include-filter" value="NfcHidlPassthroughBasicTest" />
     <option name="compatibility:include-filter" value="VibratorHidlTargetTest" />
+    <option name="compatibility:include-filter" value="VibratorHidlTest" />
+    <option name="compatibility:include-filter" value="VibratorHidlProfilingTest" />
     <template-include name="reporters" default="basic-reporters" />
 </configuration>
diff --git a/tools/vts-tradefed/res/config/vts-serving-tot-postsubmit-treble.xml b/tools/vts-tradefed/res/config/vts-serving-tot-postsubmit-treble.xml
index 80acef7..58b2abc 100644
--- a/tools/vts-tradefed/res/config/vts-serving-tot-postsubmit-treble.xml
+++ b/tools/vts-tradefed/res/config/vts-serving-tot-postsubmit-treble.xml
@@ -20,7 +20,8 @@
     <!-- For vts-hal-hidl -->
     <option name="compatibility:include-filter" value="BinderPerformanceTest" />
     <option name="compatibility:include-filter" value="HwBinderBinderizePerformanceTest" />
-    <option name="compatibility:include-filter" value="NfcHidlBasicTest" />
+    <option name="compatibility:include-filter" value="NfcHidlBinderizeBasicTest" />
+    <option name="compatibility:include-filter" value="NfcHidlPassthroughBasicTest" />
 
     <template-include name="reporters" default="basic-reporters" />
 </configuration>
diff --git a/tools/vts-tradefed/res/push_groups/HidlHalTest.push b/tools/vts-tradefed/res/push_groups/HidlHalTest.push
index 30df503..c2716db 100644
--- a/tools/vts-tradefed/res/push_groups/HidlHalTest.push
+++ b/tools/vts-tradefed/res/push_groups/HidlHalTest.push
@@ -5,3 +5,6 @@
 
 DATA/lib/libvts_driver_hidl_vibrator@1.0.so->/data/local/tmp/32/libvts_driver_hidl_vibrator@1.0.so
 DATA/lib64/libvts_driver_hidl_vibrator@1.0.so->/data/local/tmp/64/libvts_driver_hidl_vibrator@1.0.so
+
+DATA/lib/libvts_profiler_hidl_vibrator@1.0.so->/data/local/tmp/32/hw/android.hardware.vibrator@1.0::IVibrator.profiler.so
+DATA/lib64/libvts_profiler_hidl_vibrator@1.0.so->/data/local/tmp/64/hw/android.hardware.vibrator@1.0::IVibrator.profiler.so
\ No newline at end of file
diff --git a/tools/vts-tradefed/res/push_groups/HostDrivenTest.push b/tools/vts-tradefed/res/push_groups/HostDrivenTest.push
index 56ce0ac..fcd88ae 100644
--- a/tools/vts-tradefed/res/push_groups/HostDrivenTest.push
+++ b/tools/vts-tradefed/res/push_groups/HostDrivenTest.push
@@ -31,4 +31,7 @@
 DATA/bin/vts_hal_agent32->/data/local/tmp/32/vts_hal_agent32
 DATA/bin/vts_hal_agent64->/data/local/tmp/64/vts_hal_agent64
 
+DATA/lib/libvts_profiling.so->/data/local/tmp/32/libvts_profiling.so
+DATA/lib64/libvts_profiling.so->/data/local/tmp/64/libvts_profiling.so
+
 DATA/app/VtsAgentApp/VtsAgentApp.apk->/data/local/tmp/VtsAgentApp.apk
diff --git a/utils/python/common/cmd_utils.py b/utils/python/common/cmd_utils.py
index 07bc9e0..1b64114 100644
--- a/utils/python/common/cmd_utils.py
+++ b/utils/python/common/cmd_utils.py
@@ -17,6 +17,11 @@
 import logging
 import subprocess
 
+STDOUT = 0
+STDERR = 1
+EXIT_CODE = 2
+
+
 def RunCommand(command):
     """Runs a unix command and stashes the result.
 
@@ -25,13 +30,45 @@
     Returns:
         code of the subprocess.
     """
-    proc = subprocess.Popen(command,
-                            stdout=subprocess.PIPE,
-                            stderr=subprocess.PIPE)
+    proc = subprocess.Popen(
+        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     (stdout, stderr) = proc.communicate()
     if proc.returncode != 0:
-        logging.error("Fail to execute command: %s  "
-                      "(stdout: %s\n  stderr: %s\n)" % (command,
-                                                        stdout,
+        logging.error('Fail to execute command: %s  '
+                      '(stdout: %s\n  stderr: %s\n)' % (command, stdout,
                                                         stderr))
-    return proc.returncode
\ No newline at end of file
+    return proc.returncode
+
+
+def ExecuteOneShellCommand(cmd):
+    """Execute one shell command and return (stdout, stderr, exit_code).
+
+    Args:
+        cmd: string, a shell command
+
+    Returns:
+        tuple(string, string, int), containing stdout, stderr, exit_code of the shell command
+    """
+    p = subprocess.Popen(
+        str(cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = p.communicate()
+    return (stdout, stderr, p.returncode)
+
+
+def ExecuteShellCommand(cmd):
+    """Execute one shell cmd or a list of shell commands.
+
+    Args:
+        cmd: string or a list of strings, shell command(s)
+
+    Returns:
+        dict{int->string}, containing stdout, stderr, exit_code of the shell command(s)
+    """
+    if not isinstance(cmd, list):
+        cmd = [cmd]
+
+    results = [ExecuteOneShellCommand(command) for command in cmd]
+    stdout, stderr, exit_code = zip(*results)
+    return {STDOUT: stdout,
+            STDERR: stderr,
+            EXIT_CODE: exit_code}
diff --git a/utils/python/profiling/__init__.py b/utils/python/profiling/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/utils/python/profiling/__init__.py
diff --git a/utils/python/profiling/profiling_utils.py b/utils/python/profiling/profiling_utils.py
new file mode 100644
index 0000000..600f2f7
--- /dev/null
+++ b/utils/python/profiling/profiling_utils.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+import os
+
+from vts.runners.host import asserts
+from vts.runners.host import const
+
+LOCAL_PROFILING_TRACE_PATH = "/tmp/vts-test-trace"
+TARGET_PROFILING_TRACE_PATH = "/data/local/tmp/"
+HAL_INSTRUMENTATION_LIB_PATH = "/data/local/tmp/64/hw/"
+
+
+def EnableVTSProfiling(
+        shell, hal_instrumentation_lib_path=HAL_INSTRUMENTATION_LIB_PATH):
+    """ Enable profiling by setting the system property.
+
+    Args:
+        shell: shell to control the testing device.
+        hal_instrumentation_lib_path: directory that stores profiling libraries.
+    """
+    # cleanup any existing traces.
+    shell.Execute("rm " + os.path.join(TARGET_PROFILING_TRACE_PATH,
+                                       "*.vts.trace"))
+    logging.info("enable VTS profiling.")
+
+    shell.Execute("setprop hal.instrumentation.lib.path " +
+                  hal_instrumentation_lib_path)
+    shell.Execute("setprop hal.instrumentation.enable true")
+
+
+def DisableVTSProfiling(shell):
+    """ Disable profiling by resetting the system property.
+
+    Args:
+        shell: shell to control the testing device.
+    """
+    shell.Execute("setprop hal.instrumentation.lib.path \"\"")
+    shell.Execute("setprop hal.instrumentation.enable false")
+
+
+class VTSProfilingData(object):
+    """Class to store the VTS profiling data.
+
+    Attributes:
+        name: A string to describe the profiling data. e.g. server_side_latency.
+        labels: A list of profiling data labels. e.g. a list of api names.
+        values: A dict that stores the profiling data for different metrics.
+    """
+
+    def __init__(self):
+        self.name = ""
+        self.labels = []
+        self.values = {"avg": [], "max": [], "min": []}
+
+
+EVENT_TYPE_DICT = {
+    0: "SERVER_API_ENTRY",
+    1: "SERVER_API_EXIT",
+    2: "CLIENT_API_ENTRY",
+    3: "CLIENT_API_EXIT",
+    4: "SYNC_CALLBACK_ENTRY",
+    5: "SYNC_CALLBACK_EXIT",
+    6: "PASSTHROUGH_ENTRY",
+    7: "PASSTHROUGH_EXIT",
+}
+
+
+def ParseTraceData(trace_file):
+    """Parses the data stored in trace_file, calculates the avg/max/min
+    latency for each API.
+
+    Args:
+        trace_file: file that stores the trace data.
+
+    Returns:
+        VTSProfilingData which contain the list of API names and the avg/max/min
+        latency for each API.
+    """
+    profiling_data = VTSProfilingData()
+    api_timestamps = {}
+    api_latencies = {}
+
+    myfile = open(trace_file, "r")
+    new_entry = True
+    for line in myfile.readlines():
+        if new_entry:
+            time_stamp, event, package, version, interface, api = line.strip(
+            ).split(",")
+            if not profiling_data.name:
+                logging.warning("no name set for the profiling data. ")
+                # TODO(zhuoyao): figure out a better way to set the data name.
+                profiling_data.name = EVENT_TYPE_DICT[int(event)]
+            if api_timestamps.get(api):
+                api_timestamps[api].append(time_stamp)
+            else:
+                api_timestamps[api] = [time_stamp]
+            new_entry = False
+        else:
+            # get the msg data.
+            if not line.strip():
+                new_entry = True
+    for api, time_stamps in api_timestamps.items():
+        latencies = []
+        # TODO(zhuoyao): figure out a way to get the latencies, e.g based on the
+        # event type of each entry.
+        for index in range(1, len(time_stamps), 2):
+            latencies.append(
+                long(time_stamps[index]) - long(time_stamps[index - 1]))
+        api_latencies[api] = latencies
+    for api, latencies in api_latencies.items():
+        profiling_data.labels.append(api)
+        profiling_data.values["max"].append(max(latencies))
+        profiling_data.values["min"].append(min(latencies))
+        profiling_data.values["avg"].append(sum(latencies) / len(latencies))
+
+    return profiling_data
+
+
+def GetTraceFiles(dut, host_profiling_trace_path):
+    """Pulls the trace file and save it under the profiling trace path.
+
+    Args:
+        dut: the testing device.
+        host_profiling_trace_path: directory that stores trace files on host.
+
+    Returns:
+        Name list of trace files that stored on host.
+    """
+    if not host_profiling_trace_path:
+        host_profiling_trace_path = LOCAL_PROFILING_TRACE_PATH
+    if not os.path.exists(host_profiling_trace_path):
+        os.makedirs(host_profiling_trace_path)
+    logging.info("Saving profiling traces under: %s",
+                 host_profiling_trace_path)
+
+    dut.shell.InvokeTerminal("profiling_shell")
+    results = dut.shell.profiling_shell.Execute("ls " + os.path.join(
+        TARGET_PROFILING_TRACE_PATH, "*.vts.trace"))
+    asserts.assertTrue(results, "failed to find trace file")
+    stdout_lines = results[const.STDOUT][0].split("\n")
+    logging.info("stdout: %s", stdout_lines)
+    trace_files = []
+    for line in stdout_lines:
+        if line:
+            file_name = os.path.join(host_profiling_trace_path,
+                                     os.path.basename(line.strip()))
+            dut.adb.pull("%s %s" % (line, file_name))
+            trace_files.append(file_name)
+    return trace_files
diff --git a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java
index 3526dcc..41f7af4 100644
--- a/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java
+++ b/web/dashboard/appengine/servlet/src/main/java/com/android/vts/servlet/ShowTableServlet.java
@@ -69,7 +69,7 @@
     private static final int MAX_BUILD_IDS_PER_PAGE = 10;
     private static final int TIME_INFO_ROW_COUNT = 2;
     private static final int DURATION_INFO_ROW_COUNT = 1;
-    private static final int SUMMARY_ROW_COUNT = 4;
+    private static final int SUMMARY_ROW_COUNT = 5;
     private static final long ONE_DAY = 86400000000L;  // units microseconds
     private static final String TABLE_PREFIX = "result_";
     private static final byte[] FAMILY = Bytes.toBytes("test");
@@ -81,6 +81,7 @@
         User currentUser = userService.getCurrentUser();
         String loginURI = userService.createLoginURL(request.getRequestURI());
         String logoutURI = userService.createLogoutURL(loginURI);
+        boolean unfiltered = request.getParameter("unfiltered") != null;
         boolean showPresubmit = request.getParameter("showPresubmit") != null;
         boolean showPostsubmit = request.getParameter("showPostsubmit") != null;
         Long startTime = null;  // time in microseconds
@@ -136,6 +137,12 @@
             showPostsubmit = true;
         }
 
+        // If unfiltered, set showPre- and Post-submit to true for accurate UI.
+        if (unfiltered) {
+            showPostsubmit = true;
+            showPresubmit = true;
+        }
+
         // Add result names to list
         List<String> resultNames = new ArrayList<>();
         for (TestCaseResult r : TestCaseResult.values()) {
@@ -201,14 +208,16 @@
 
                 try {
                     // filter non-integer build IDs
-                    Integer.parseInt(buildId);
-                    if (!showPostsubmit && firstDeviceBuildId.charAt(0) != 'P') {
-                        continue;
+                    if (!unfiltered) {
+                        Integer.parseInt(buildId);
+                        if (!showPostsubmit && firstDeviceBuildId.charAt(0) != 'P') {
+                            continue;
+                        }
+                        if (showPresubmit && firstDeviceBuildId.charAt(0) == 'P') {
+                            firstDeviceBuildId = firstDeviceBuildId.substring(1);
+                        }
+                        Integer.parseInt(firstDeviceBuildId);
                     }
-                    if (showPresubmit && firstDeviceBuildId.charAt(0) == 'P') {
-                        firstDeviceBuildId = firstDeviceBuildId.substring(1);
-                    }
-                    Integer.parseInt(firstDeviceBuildId);
                     tests.add(0, testReportMessage);
                 } catch (NumberFormatException e) {
                     /* skip a non-post-submit build */
@@ -317,7 +326,7 @@
         durationGrid[0][0] = "<b>Test Duration</b>";
 
         // first column for summary grid
-        String[] rowNamesSummaryGrid = {"Total", "Passed #", "Passed %", "Coverage %"};
+        String[] rowNamesSummaryGrid = {"Total", "Passing #", "Non-Passing #", "Passing %", "Coverage %"};
         for (int i = 0; i < rowNamesSummaryGrid.length; i++) {
             summaryGrid[i][0] = "<b>" + rowNamesSummaryGrid[i] + "</b>";
         }
@@ -348,11 +357,20 @@
             String buildId = report.getBuildInfo().getId().toStringUtf8();
 
             int passCount = 0;
+            int nonpassCount = 0;
+            TestCaseResult aggregateStatus = TestCaseResult.UNKNOWN_RESULT;
             long totalLineCount = 0, coveredLineCount = 0;
             for (TestCaseReportMessage testCaseReport : report.getTestCaseList()) {
                 if (testCaseReport.getTestResult() ==
                     TestCaseResult.TEST_CASE_RESULT_PASS) {
                     passCount++;
+                    if (aggregateStatus == TestCaseResult.UNKNOWN_RESULT) {
+                        aggregateStatus = TestCaseResult.TEST_CASE_RESULT_PASS;
+                    }
+                } else if (testCaseReport.getTestResult() !=
+                           TestCaseResult.TEST_CASE_RESULT_SKIP) {
+                    nonpassCount++;
+                    aggregateStatus = TestCaseResult.TEST_CASE_RESULT_FAIL;
                 }
                 for (CoverageReportMessage coverageReport :
                     testCaseReport.getCoverageList()) {
@@ -394,18 +412,20 @@
             } catch (ArithmeticException e) {
                 coverageInfo = " - ";
             }
-
-            headerRow[j + 1] = "<b>" + StringUtils.join(buildIdList, ",") + "</b><br>" +
-                               buildAlias.toLowerCase() + "<br>" + buildFlavor + "<br>" +
-                               productVariant + "<br>" + buildId;
+            String icon = "<div class='status-icon " + aggregateStatus.toString() + "'>&nbsp</div>";
+            String buildIds = StringUtils.join(buildIdList, ",");
+            headerRow[j + 1] = "<span class='valign-wrapper'><b>" + buildIds + "</b>" + icon +
+                               "</span>" + buildAlias.toLowerCase() + "<br>" + buildFlavor +
+                               "<br>" + productVariant + "<br>" + buildId;
             timeGrid[0][j + 1] = Long.toString(report.getStartTimestamp());
             timeGrid[1][j + 1] = Long.toString(report.getEndTimestamp());
             durationGrid[0][j + 1] = Long.toString(report.getEndTimestamp() -
                                                    report.getStartTimestamp());
             summaryGrid[0][j + 1] = Integer.toString(report.getTestCaseList().size());
             summaryGrid[1][j + 1] = Integer.toString(passCount);
-            summaryGrid[2][j + 1] = passInfo;
-            summaryGrid[3][j + 1] = coverageInfo;
+            summaryGrid[2][j + 1] = Integer.toString(nonpassCount);
+            summaryGrid[3][j + 1] = passInfo;
+            summaryGrid[4][j + 1] = coverageInfo;
         }
 
         String[] profilingPointNameArray = profilingPointNameSet.
@@ -446,6 +466,7 @@
         request.setAttribute("endTime", new Gson().toJson(endTime));
         request.setAttribute("hasNewer", new Gson().toJson(hasNewer));
         request.setAttribute("hasOlder", new Gson().toJson(hasOlder));
+        request.setAttribute("unfiltered", unfiltered);
         request.setAttribute("showPresubmit", showPresubmit);
         request.setAttribute("showPostsubmit", showPostsubmit);
 
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css b/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css
index ad9c488..806c308 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css
+++ b/web/dashboard/appengine/servlet/src/main/webapp/css/show_table.css
@@ -96,6 +96,13 @@
 .pie-chart-title {
     cursor: default;
 }
+div.status-icon {
+    width: 10px;
+    height: 10px;
+    border-radius: 10px;
+    display: inline-block;
+    margin-left: 5px;
+}
 .test-case-status {
     border-radius: 50px;
 }
diff --git a/web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp b/web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp
index b75e1c5..322895e 100644
--- a/web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp
+++ b/web/dashboard/appengine/servlet/src/main/webapp/show_table.jsp
@@ -93,6 +93,9 @@
           if ($('#postsubmit').prop('checked')) {
               link += '&showPostsubmit=';
           }
+          if (${unfiltered}) {
+              link += '&unfiltered=';
+          }
           window.open(link,'_self');
       }
 
@@ -108,6 +111,9 @@
           if ($('#postsubmit').prop('checked')) {
               link += '&showPostsubmit=';
           }
+          if (${unfiltered}) {
+              link += '&unfiltered=';
+          }
           window.open(link,'_self');
         }