Added sensor target VTS test

Initial submission of Sensor VTS test, including the following
test cases:

 * SensorListValid
 * NormalAccelerometerStreamingOperation
 * NormalGyroscopeStreamingOperation
 * AccelerometerSamplingPeriodHotSwitchOperation
 * AccelerometerBatchingOperation

One thing to note is that runtime has to be stopped to prevent
sensor service from stealing samples (which causes test failure).

Test: m vts -j32 &&
      adb shell stop &&
      vts-tradefed run commandAndExit vts \
          --skip-all-system-status-check \
          --primary-abi-only \
          --skip-preconditions \
          --module SensorsHidlTargetTest
      vts-tradefed run commandAndExit vts \
          --skip-all-system-status-check \
          --primary-abi-only \
          --skip-preconditions \
          --module SensorsHidlTest
      adb shell start

Test: # alternative, faster way to run target test only
      m sensors_hidl_hal_test -j32  &&
      TOUT=$T/out/target/product/${TARGET_PRODUCT}
      TEST=data/nativetest/sensors_hidl_hal_test/sensors_hidl_hal_test
      adb push ${TOUT}/${TEST} /${TEST} && \
      adb shell ${TEST}

Change-Id: I3e26aa550f4cdec2cebb847f47d63ed33a527210
diff --git a/sensors/1.0/vts/Android.mk b/sensors/1.0/vts/Android.mk
new file mode 100644
index 0000000..df8d66f
--- /dev/null
+++ b/sensors/1.0/vts/Android.mk
@@ -0,0 +1,83 @@
+#
+# 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)
+
+# build VTS driver for Sensors v1.0.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libvts_driver_hidl_sensors@1.0
+
+LOCAL_SRC_FILES := \
+  Sensors.vts \
+  types.vts \
+
+LOCAL_SHARED_LIBRARIES += \
+  android.hardware.sensors@1.0 \
+  libbase \
+  libutils \
+  libcutils \
+  liblog \
+  libhidlbase \
+  libhidltransport \
+  libhwbinder \
+  libprotobuf-cpp-full \
+  libvts_common \
+  libvts_datatype \
+  libvts_measurement \
+  libvts_multidevice_proto \
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+
+LOCAL_MULTILIB := both
+
+include $(BUILD_SHARED_LIBRARY)
+
+# build profiler for sensors.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libvts_profiler_hidl_sensors@1.0
+
+LOCAL_SRC_FILES := \
+  Sensors.vts \
+  types.vts \
+
+LOCAL_C_INCLUDES += \
+  test/vts/drivers/libprofiling \
+
+LOCAL_VTS_MODE := PROFILER
+
+LOCAL_SHARED_LIBRARIES := \
+   android.hardware.sensors@1.0 \
+   libbase \
+   libutils \
+   libcutils \
+   liblog \
+   libhidlbase \
+   libhidltransport \
+   libhwbinder \
+   libprotobuf-cpp-full \
+   libvts_common \
+   libvts_multidevice_proto \
+   libvts_profiling \
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+
+include $(BUILD_SHARED_LIBRARY)
+
+# include hidl test makefiles
+include $(LOCAL_PATH)/functional/vts/testcases/hal/sensors/hidl/Android.mk
+
diff --git a/sensors/1.0/vts/Sensors.vts b/sensors/1.0/vts/Sensors.vts
new file mode 100644
index 0000000..f80fff5
--- /dev/null
+++ b/sensors/1.0/vts/Sensors.vts
@@ -0,0 +1,139 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "ISensors"
+
+package: "android.hardware.sensors"
+
+import: "android.hardware.sensors@1.0::types"
+
+interface: {
+    api: {
+        name: "getSensorsList"
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_STRUCT
+                predefined_type: "::android::hardware::sensors::V1_0::SensorInfo"
+            }
+        }
+    }
+
+    api: {
+        name: "setOperationMode"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        arg: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::OperationMode"
+        }
+    }
+
+    api: {
+        name: "activate"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "bool_t"
+        }
+    }
+
+    api: {
+        name: "setDelay"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int64_t"
+        }
+    }
+
+    api: {
+        name: "poll"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_STRUCT
+                predefined_type: "::android::hardware::sensors::V1_0::Event"
+            }
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_STRUCT
+                predefined_type: "::android::hardware::sensors::V1_0::SensorInfo"
+            }
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+    }
+
+    api: {
+        name: "batch"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int64_t"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int64_t"
+        }
+    }
+
+    api: {
+        name: "flush"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "int32_t"
+        }
+    }
+
+    api: {
+        name: "injectSensorData"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "::android::hardware::sensors::V1_0::Result"
+        }
+        arg: {
+            type: TYPE_STRUCT
+            predefined_type: "::android::hardware::sensors::V1_0::Event"
+        }
+    }
+
+}
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..675484a
--- /dev/null
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "sensors_hidl_hal_test",
+    gtest: true,
+    srcs: ["sensors_hidl_hal_test.cpp"],
+    shared_libs: [
+        "liblog",
+        "libhidlbase",
+        "libutils",
+        "android.hardware.sensors@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
diff --git a/sensors/1.0/vts/functional/sensors_hidl_hal_test.cpp b/sensors/1.0/vts/functional/sensors_hidl_hal_test.cpp
new file mode 100644
index 0000000..8e85b23
--- /dev/null
+++ b/sensors/1.0/vts/functional/sensors_hidl_hal_test.cpp
@@ -0,0 +1,692 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "sensors_hidl_hal_test"
+#include <android-base/logging.h>
+#include <android/hardware/sensors/1.0/ISensors.h>
+#include <android/hardware/sensors/1.0/types.h>
+#include <android/log.h>
+#include <gtest/gtest.h>
+#include <hardware/sensors.h>       // for sensor type strings
+
+#include <algorithm>
+#include <cinttypes>
+#include <cmath>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <unistd.h>
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+using namespace ::android::hardware::sensors::V1_0;
+
+#define SENSORS_SERVICE_NAME "sensors"
+
+// Test environment for sensors
+class SensorsHidlEnvironment : public ::testing::Environment {
+ public:
+  // get the test environment singleton
+  static SensorsHidlEnvironment* Instance() {
+    static SensorsHidlEnvironment* instance = new SensorsHidlEnvironment;
+    return instance;
+  }
+
+  // sensors hidl service
+  sp<ISensors> sensors;
+
+  virtual void SetUp();
+  virtual void TearDown();
+
+  // Get and clear all events collected so far (like "cat" shell command).
+  // If output is nullptr, it clears all collected events.
+  void catEvents(std::vector<Event>* output);
+
+  // set sensor event collection status
+  void setCollection(bool enable);
+
+ private:
+  SensorsHidlEnvironment() {}
+
+  void addEvent(const Event& ev);
+  void startPollingThread();
+  static void pollingThread(SensorsHidlEnvironment* env, std::shared_ptr<bool> stop);
+
+  bool collectionEnabled;
+  std::shared_ptr<bool> stopThread;
+  std::thread pollThread;
+  std::vector<Event> events;
+  std::mutex events_mutex;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironment);
+};
+
+void SensorsHidlEnvironment::SetUp() {
+  sensors = ISensors::getService(SENSORS_SERVICE_NAME, false);
+  ALOGI_IF(sensors, "sensors is not nullptr, %p", sensors.get());
+  ASSERT_NE(sensors, nullptr);
+
+  collectionEnabled = false;
+  startPollingThread();
+}
+
+void SensorsHidlEnvironment::TearDown() {
+  ALOGI("TearDown SensorsHidlEnvironement");
+
+  if (stopThread) {
+    *stopThread = true;
+  }
+  pollThread.detach();
+}
+
+void SensorsHidlEnvironment::catEvents(std::vector<Event>* output) {
+  std::lock_guard<std::mutex> lock(events_mutex);
+  if (output) {
+    output->insert(output->end(), events.begin(), events.end());
+  }
+  events.clear();
+}
+
+void SensorsHidlEnvironment::setCollection(bool enable) {
+  std::lock_guard<std::mutex> lock(events_mutex);
+  collectionEnabled = enable;
+}
+
+void SensorsHidlEnvironment::addEvent(const Event& ev) {
+  std::lock_guard<std::mutex> lock(events_mutex);
+  if (collectionEnabled) {
+    events.push_back(ev);
+  }
+}
+
+void SensorsHidlEnvironment::startPollingThread() {
+  stopThread = std::shared_ptr<bool>(new bool(false));
+  pollThread = std::thread(pollingThread, this, stopThread);
+  events.reserve(128);
+}
+
+void SensorsHidlEnvironment::pollingThread(
+    SensorsHidlEnvironment* env, std::shared_ptr<bool> stop) {
+  ALOGD("polling thread start");
+  bool needExit = *stop;
+
+  while(!needExit) {
+    env->sensors->poll(1,
+        [&](auto result, const auto &events, const auto &dynamicSensorsAdded) {
+          if (result != Result::OK
+              || (events.size() == 0 && dynamicSensorsAdded.size() == 0)
+              || *stop) {
+            needExit = true;
+            return;
+          }
+
+          if (events.size() > 0) {
+            env->addEvent(events[0]);
+          }
+        });
+  }
+  ALOGD("polling thread end");
+}
+
+// The main test class for SENSORS HIDL HAL.
+class SensorsHidlTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+  }
+
+  virtual void TearDown() override {
+  }
+
+ protected:
+  inline sp<ISensors>& S() {
+    return SensorsHidlEnvironment::Instance()->sensors;
+  }
+
+  std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
+                                   bool clearBeforeStart = true,
+                                   bool changeCollection = true) {
+    std::vector<Event> events;
+    constexpr useconds_t SLEEP_GRANULARITY = 100*1000; //gradularity 100 ms
+
+    ALOGI("collect max of %zu events for %d us, clearBeforeStart %d",
+          nEventLimit, timeLimitUs, clearBeforeStart);
+
+    if (changeCollection) {
+      SensorsHidlEnvironment::Instance()->setCollection(true);
+    }
+    if (clearBeforeStart) {
+      SensorsHidlEnvironment::Instance()->catEvents(nullptr);
+    }
+
+    while (timeLimitUs > 0) {
+      useconds_t duration = std::min(SLEEP_GRANULARITY, timeLimitUs);
+      usleep(duration);
+      timeLimitUs -= duration;
+
+      SensorsHidlEnvironment::Instance()->catEvents(&events);
+      if (events.size() >= nEventLimit) {
+        break;
+      }
+      ALOGV("time to go = %d, events to go = %d",
+            (int)timeLimitUs, (int)(nEventLimit - events.size()));
+    }
+
+    if (changeCollection) {
+      SensorsHidlEnvironment::Instance()->setCollection(false);
+    }
+    return events;
+  }
+
+  static bool typeMatchStringType(SensorType type, const hidl_string& stringType);
+  static bool typeMatchReportMode(SensorType type, SensorFlagBits reportMode);
+  static bool delayMatchReportMode(int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode);
+
+  inline static SensorFlagBits extractReportMode(uint64_t flag) {
+    return (SensorFlagBits) (flag
+        & ((uint64_t) SensorFlagBits::SENSOR_FLAG_CONTINUOUS_MODE
+          | (uint64_t) SensorFlagBits::SENSOR_FLAG_ON_CHANGE_MODE
+          | (uint64_t) SensorFlagBits::SENSOR_FLAG_ONE_SHOT_MODE
+          | (uint64_t) SensorFlagBits::SENSOR_FLAG_SPECIAL_REPORTING_MODE));
+  }
+
+  inline static bool isMetaSensorType(SensorType type) {
+    return (type == SensorType::SENSOR_TYPE_META_DATA
+            || type == SensorType::SENSOR_TYPE_DYNAMIC_SENSOR_META
+            || type == SensorType::SENSOR_TYPE_ADDITIONAL_INFO);
+  }
+
+  inline static bool isValidType(SensorType type) {
+    return (int32_t) type > 0;
+  }
+
+  static SensorFlagBits expectedReportModeForType(SensorType type);
+  SensorInfo defaultSensorByType(SensorType type);
+};
+
+bool SensorsHidlTest::typeMatchStringType(SensorType type, const hidl_string& stringType) {
+
+  if (type >= SensorType::SENSOR_TYPE_DEVICE_PRIVATE_BASE) {
+    return true;
+  }
+
+  bool res = true;
+  switch (type) {
+#define CHECK_TYPE_STRING_FOR_SENSOR_TYPE(type) \
+    case SensorType::SENSOR_TYPE_ ## type: res = stringType == SENSOR_STRING_TYPE_ ## type;\
+      break;\
+
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TEMPERATURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(AMBIENT_TEMPERATURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GAME_ROTATION_VECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GEOMAGNETIC_ROTATION_VECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_RATE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TILT_DETECTOR);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WAKE_GESTURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WRIST_TILT_GESTURE);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
+    CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
+    default:
+      ALOGW("Type %d is not checked, stringType = %s", (int)type, stringType.c_str());
+#undef CHECK_TYPE_STRING_FOR_SENSOR_TYPE
+  }
+  return res;
+}
+
+bool SensorsHidlTest::typeMatchReportMode(SensorType type, SensorFlagBits reportMode) {
+  if (type >= SensorType::SENSOR_TYPE_DEVICE_PRIVATE_BASE) {
+    return true;
+  }
+
+  SensorFlagBits expected = expectedReportModeForType(type);
+
+  return expected == (SensorFlagBits)-1 || expected == reportMode;
+}
+
+bool SensorsHidlTest::delayMatchReportMode(
+    int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode) {
+  bool res = true;
+  switch(reportMode) {
+    case SensorFlagBits::SENSOR_FLAG_CONTINUOUS_MODE:
+      res = (minDelay > 0) && (maxDelay >= 0);
+      break;
+    case SensorFlagBits::SENSOR_FLAG_ON_CHANGE_MODE:
+      //TODO: current implementation does not satisfy minDelay == 0 on Proximity
+      res = (minDelay >= 0) && (maxDelay >= 0);
+      //res = (minDelay == 0) && (maxDelay >= 0);
+      break;
+    case SensorFlagBits::SENSOR_FLAG_ONE_SHOT_MODE:
+      res = (minDelay == -1) && (maxDelay == 0);
+      break;
+    case SensorFlagBits::SENSOR_FLAG_SPECIAL_REPORTING_MODE:
+      res = (minDelay == 0) && (maxDelay == 0);
+  }
+
+  return res;
+}
+
+SensorFlagBits SensorsHidlTest::expectedReportModeForType(SensorType type) {
+  switch (type) {
+    case SensorType::SENSOR_TYPE_ACCELEROMETER:
+    case SensorType::SENSOR_TYPE_GYROSCOPE:
+    case SensorType::SENSOR_TYPE_GEOMAGNETIC_FIELD:
+    case SensorType::SENSOR_TYPE_ORIENTATION:
+    case SensorType::SENSOR_TYPE_PRESSURE:
+    case SensorType::SENSOR_TYPE_TEMPERATURE:
+    case SensorType::SENSOR_TYPE_GRAVITY:
+    case SensorType::SENSOR_TYPE_LINEAR_ACCELERATION:
+    case SensorType::SENSOR_TYPE_ROTATION_VECTOR:
+    case SensorType::SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+    case SensorType::SENSOR_TYPE_GAME_ROTATION_VECTOR:
+    case SensorType::SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+    case SensorType::SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+    case SensorType::SENSOR_TYPE_POSE_6DOF:
+    case SensorType::SENSOR_TYPE_HEART_BEAT:
+      return SensorFlagBits::SENSOR_FLAG_CONTINUOUS_MODE;
+
+    case SensorType::SENSOR_TYPE_LIGHT:
+    case SensorType::SENSOR_TYPE_PROXIMITY:
+    case SensorType::SENSOR_TYPE_RELATIVE_HUMIDITY:
+    case SensorType::SENSOR_TYPE_AMBIENT_TEMPERATURE:
+    case SensorType::SENSOR_TYPE_HEART_RATE:
+    case SensorType::SENSOR_TYPE_DEVICE_ORIENTATION:
+    case SensorType::SENSOR_TYPE_MOTION_DETECT:
+    case SensorType::SENSOR_TYPE_STEP_COUNTER:
+      return SensorFlagBits::SENSOR_FLAG_ON_CHANGE_MODE;
+
+    case SensorType::SENSOR_TYPE_SIGNIFICANT_MOTION:
+    case SensorType::SENSOR_TYPE_WAKE_GESTURE:
+    case SensorType::SENSOR_TYPE_GLANCE_GESTURE:
+    case SensorType::SENSOR_TYPE_PICK_UP_GESTURE:
+      return SensorFlagBits::SENSOR_FLAG_ONE_SHOT_MODE;
+
+    case SensorType::SENSOR_TYPE_STEP_DETECTOR:
+    case SensorType::SENSOR_TYPE_TILT_DETECTOR:
+    case SensorType::SENSOR_TYPE_WRIST_TILT_GESTURE:
+    case SensorType::SENSOR_TYPE_DYNAMIC_SENSOR_META:
+      return SensorFlagBits::SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+
+    default:
+      ALOGW("Type %d is not implemented in expectedReportModeForType", (int)type);
+      return (SensorFlagBits)-1;
+  }
+}
+
+SensorInfo SensorsHidlTest::defaultSensorByType(SensorType type) {
+  SensorInfo ret;
+
+  ret.type = (SensorType) -1;
+  S()->getSensorsList(
+      [&] (const auto &list) {
+        const size_t count = list.size();
+        for (size_t i = 0; i < count; ++i) {
+          if (list[i].type == type) {
+            ret = list[i];
+            return;
+          }
+        }
+      });
+
+  return ret;
+}
+
+// Test if sensor list returned is valid
+TEST_F(SensorsHidlTest, SensorListValid) {
+  S()->getSensorsList(
+      [&] (const auto &list) {
+        const size_t count = list.size();
+        for (size_t i = 0; i < count; ++i) {
+          auto &s = list[i];
+          ALOGV("\t%zu: handle=%#08x type=%d name=%s",
+                i, s.sensorHandle, (int)s.type, s.name.c_str());
+
+          // Test non-empty type string
+          ASSERT_FALSE(s.typeAsString.empty());
+
+          // Test defined type matches defined string type
+          ASSERT_TRUE(typeMatchStringType(s.type, s.typeAsString));
+
+          // Test if all sensor has name and vendor
+          ASSERT_FALSE(s.name.empty());
+          ASSERT_FALSE(s.vendor.empty());
+
+          // Test power > 0, maxRange > 0
+          ASSERT_GE(s.power, 0);
+          ASSERT_GT(s.maxRange, 0);
+
+          // Info type, should have no sensor
+          ASSERT_FALSE(
+              s.type == SensorType::SENSOR_TYPE_ADDITIONAL_INFO
+              || s.type == SensorType::SENSOR_TYPE_META_DATA);
+
+          // Test fifoMax >= fifoReserved
+          ALOGV("max reserve = %d, %d", s.fifoMaxEventCount, s.fifoReservedEventCount);
+          ASSERT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount);
+
+          // Test Reporting mode valid
+          ASSERT_TRUE(typeMatchReportMode(s.type, extractReportMode(s.flags)));
+
+          // Test min max are in the right order
+          ASSERT_LE(s.minDelay, s.maxDelay);
+          // Test min/max delay matches reporting mode
+          ASSERT_TRUE(delayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
+        }
+      });
+}
+
+// Test if sensor hal can do normal accelerometer streaming properly
+TEST_F(SensorsHidlTest, NormalAccelerometerStreamingOperation) {
+
+  std::vector<Event> events;
+
+  constexpr int64_t samplingPeriodInNs = 20ull*1000*1000; // 20ms
+  constexpr int64_t batchingPeriodInNs = 0; // no batching
+  constexpr useconds_t minTimeUs = 5*1000*1000;  // 5 s
+  constexpr size_t minNEvent = 100;  // at lease 100 events
+  constexpr SensorType type = SensorType::SENSOR_TYPE_ACCELEROMETER;
+
+  SensorInfo sensor = defaultSensorByType(type);
+
+  if (!isValidType(sensor.type)) {
+    // no default sensor of this type
+    return;
+  }
+
+  int32_t handle = sensor.sensorHandle;
+
+  S()->batch(handle, 0, samplingPeriodInNs, batchingPeriodInNs);
+  S()->activate(handle, 1);
+  events = collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
+  S()->activate(handle, 0);
+
+  ALOGI("Collected %zu samples", events.size());
+
+  ASSERT_GT(events.size(), 0);
+
+  size_t nRealEvent = 0;
+  for (auto & e : events) {
+    if (e.sensorType == type) {
+
+      ASSERT_EQ(e.sensorHandle, handle);
+
+      Vec3 acc = e.u.vec3;
+
+      double gravityNorm = std::sqrt(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z);
+      ALOGV("Norm = %f", gravityNorm);
+
+      // assert this is earth gravity
+      ASSERT_TRUE(std::fabs(gravityNorm - GRAVITY_EARTH) < 1);
+
+      ++ nRealEvent;
+    } else {
+      ALOGI("Event type %d, handle %d", (int) e.sensorType, (int) e.sensorHandle);
+      // Only meta types are allowed besides the subscribed sensor
+      ASSERT_TRUE(isMetaSensorType(e.sensorType));
+    }
+  }
+
+  ASSERT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
+}
+
+// Test if sensor hal can do gyroscope streaming properly
+TEST_F(SensorsHidlTest, NormalGyroscopeStreamingOperation) {
+
+  std::vector<Event> events;
+
+  constexpr int64_t samplingPeriodInNs = 10ull*1000*1000; // 10ms
+  constexpr int64_t batchingPeriodInNs = 0; // no batching
+  constexpr useconds_t minTimeUs = 5*1000*1000;  // 5 s
+  constexpr size_t minNEvent = 200;
+  constexpr SensorType type = SensorType::SENSOR_TYPE_GYROSCOPE;
+
+  SensorInfo sensor = defaultSensorByType(type);
+
+  if (!isValidType(sensor.type)) {
+    // no default sensor of this type
+    return;
+  }
+
+  int32_t handle = sensor.sensorHandle;
+
+  S()->batch(handle, 0, samplingPeriodInNs, batchingPeriodInNs);
+  S()->activate(handle, 1);
+  events = collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
+  S()->activate(handle, 0);
+
+  ALOGI("Collected %zu samples", events.size());
+
+  ASSERT_GT(events.size(), 0u);
+
+  size_t nRealEvent = 0;
+  for (auto & e : events) {
+    if (e.sensorType == type) {
+
+      ASSERT_EQ(e.sensorHandle, handle);
+
+      Vec3 gyro = e.u.vec3;
+
+      double gyroNorm = std::sqrt(gyro.x * gyro.x + gyro.y * gyro.y + gyro.z * gyro.z);
+      ALOGV("Gyro Norm = %f", gyroNorm);
+
+      // assert not drifting
+      ASSERT_TRUE(gyroNorm < 0.1);  // < ~5 degree/s
+
+      ++ nRealEvent;
+    } else {
+      ALOGI("Event type %d, handle %d", (int) e.sensorType, (int) e.sensorHandle);
+      // Only meta types are allowed besides the subscribed sensor
+      ASSERT_TRUE(isMetaSensorType(e.sensorType));
+    }
+  }
+
+  ASSERT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
+}
+
+// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+
+  std::vector<Event> events1, events2;
+
+  constexpr int64_t batchingPeriodInNs = 0; // no batching
+  constexpr useconds_t minTimeUs = 5*1000*1000;  // 5 s
+  constexpr size_t minNEvent = 50;
+  constexpr SensorType type = SensorType::SENSOR_TYPE_ACCELEROMETER;
+
+  SensorInfo sensor = defaultSensorByType(type);
+
+  if (!isValidType(sensor.type)) {
+    // no default sensor of this type
+    return;
+  }
+
+  int32_t handle = sensor.sensorHandle;
+  int64_t minSamplingPeriodInNs = sensor.minDelay * 1000ll;
+  int64_t maxSamplingPeriodInNs = sensor.maxDelay * 1000ll;
+
+  if (minSamplingPeriodInNs == maxSamplingPeriodInNs) {
+    // only support single rate
+    return;
+  }
+
+  S()->batch(handle, 0, minSamplingPeriodInNs, batchingPeriodInNs);
+  S()->activate(handle, 1);
+
+  usleep(500000); // sleep 0.5 sec to wait for change rate to happen
+  events1 = collectEvents(sensor.minDelay * minNEvent, minNEvent, true /*clearBeforeStart*/);
+
+  S()->batch(handle, 0, maxSamplingPeriodInNs, batchingPeriodInNs);
+
+  usleep(500000); // sleep 0.5 sec to wait for change rate to happen
+  events2 = collectEvents(sensor.maxDelay * minNEvent, minNEvent, true /*clearBeforeStart*/);
+
+  S()->activate(handle, 0);
+
+  ALOGI("Collected %zu fast samples and %zu slow samples", events1.size(), events2.size());
+
+  ASSERT_GT(events1.size(), 0u);
+  ASSERT_GT(events2.size(), 0u);
+
+  int64_t minDelayAverageInterval, maxDelayAverageInterval;
+
+  size_t nEvent = 0;
+  int64_t prevTimestamp = -1;
+  int64_t timestampInterval = 0;
+  for (auto & e : events1) {
+    if (e.sensorType == type) {
+      ASSERT_EQ(e.sensorHandle, handle);
+      if (prevTimestamp > 0) {
+        timestampInterval += e.timestamp - prevTimestamp;
+      }
+      prevTimestamp = e.timestamp;
+      ++ nEvent;
+    }
+  }
+  ASSERT_GT(nEvent, 2);
+  minDelayAverageInterval = timestampInterval / (nEvent - 1);
+
+  nEvent = 0;
+  prevTimestamp = -1;
+  timestampInterval = 0;
+  for (auto & e : events2) {
+    if (e.sensorType == type) {
+      ASSERT_EQ(e.sensorHandle, handle);
+      if (prevTimestamp > 0) {
+        timestampInterval += e.timestamp - prevTimestamp;
+      }
+      prevTimestamp = e.timestamp;
+      ++ nEvent;
+    }
+  }
+  ASSERT_GT(nEvent, 2);
+  maxDelayAverageInterval = timestampInterval / (nEvent - 1);
+
+  // change of rate is significant.
+  ASSERT_GT((maxDelayAverageInterval - minDelayAverageInterval), minDelayAverageInterval / 10);
+
+  // fastest rate sampling time is close to spec
+  ALOGI("minDelayAverageInterval = %" PRId64, minDelayAverageInterval);
+  ASSERT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
+      minSamplingPeriodInNs / 10);
+}
+
+// Test if sensor hal can do normal accelerometer batching properly
+TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+
+  std::vector<Event> events;
+
+  constexpr int64_t oneSecondInNs = 1ull * 1000 * 1000 * 1000;
+  constexpr useconds_t minTimeUs = 5*1000*1000;  // 5 s
+  constexpr size_t minNEvent = 50;
+  constexpr SensorType type = SensorType::SENSOR_TYPE_ACCELEROMETER;
+  constexpr int64_t maxBatchingTestTimeNs = 30ull * 1000 * 1000 * 1000;
+
+  SensorInfo sensor = defaultSensorByType(type);
+
+  if (!isValidType(sensor.type)) {
+    // no default sensor of this type
+    return;
+  }
+
+  int32_t handle = sensor.sensorHandle;
+  int64_t minSamplingPeriodInNs = sensor.minDelay * 1000ll;
+  uint32_t minFifoCount = sensor.fifoReservedEventCount;
+  int64_t batchingPeriodInNs = minFifoCount * minSamplingPeriodInNs;
+
+  if (batchingPeriodInNs < oneSecondInNs) {
+    // batching size too small to test reliably
+    return;
+  }
+
+  batchingPeriodInNs = std::min(batchingPeriodInNs, maxBatchingTestTimeNs);
+
+  ALOGI("Test batching for %d ms", (int)(batchingPeriodInNs / 1000 / 1000));
+
+  int64_t allowedBatchDeliverTimeNs =
+      std::max(oneSecondInNs, batchingPeriodInNs / 10);
+
+  S()->batch(handle, 0, minSamplingPeriodInNs, INT64_MAX);
+  S()->activate(handle, 1);
+
+  usleep(500000); // sleep 0.5 sec to wait for initialization
+  S()->flush(handle);
+
+  // wait for 80% of the reserved batching period
+  // there should not be any significant amount of events
+  // since collection is not enabled all events will go down the drain
+  usleep(batchingPeriodInNs / 1000 * 8 / 10);
+
+
+  SensorsHidlEnvironment::Instance()->setCollection(true);
+  // 0.8 + 0.3 times the batching period
+  // plus some time for the event to deliver
+  events = collectEvents(
+      batchingPeriodInNs / 1000 * 3 / 10,
+        minFifoCount, true /*clearBeforeStart*/, false /*change collection*/);
+
+  S()->flush(handle);
+
+  events = collectEvents(allowedBatchDeliverTimeNs / 1000,
+        minFifoCount, true /*clearBeforeStart*/, false /*change collection*/);
+
+  SensorsHidlEnvironment::Instance()->setCollection(false);
+  S()->activate(handle, 0);
+
+  size_t nEvent = 0;
+  for (auto & e : events) {
+    if (e.sensorType == type && e.sensorHandle == handle) {
+      ++ nEvent;
+    }
+  }
+
+  // at least reach 90% of advertised capacity
+  ASSERT_GT(nEvent, (size_t)(batchingPeriodInNs / minSamplingPeriodInNs * 9 / 10));
+}
+
+
+int main(int argc, char **argv) {
+  ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironment::Instance());
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  ALOGI("Test result = %d", status);
+  return status;
+}
+
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/__init__.py b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/__init__.py
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/Android.mk b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/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/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/__init__.py b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/__init__.py
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/Android.mk b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/Android.mk
new file mode 100644
index 0000000..79f8f7a
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/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 := SensorsHidlTest
+VTS_CONFIG_SRC_DIR := testcases/hal/sensors/hidl/host
+include test/vts/tools/build/Android.host_config.mk
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/AndroidTest.xml b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/AndroidTest.xml
new file mode 100644
index 0000000..6e40610
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS HAL sensors 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/sensors/1.0/vts/Sensors.vts->/data/local/tmp/spec/Sensors.vts" />
+        <option name="push" value="spec/hardware/interfaces/sensors/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-module-name" value="SensorsHidlTest" />
+        <option name="test-case-path" value="vts/testcases/hal/sensors/hidl/host/SensorsHidlTest" />
+        <option name="test-timeout" value="3m" />
+    </test>
+</configuration>
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py
new file mode 100644
index 0000000..88fe675
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3.4
+#
+# 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 time
+
+from vts.runners.host import asserts
+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 SensorsHidlTest(base_test_with_webdb.BaseTestWithWebDbClass):
+    """Host testcase class for the SENSORS HIDL HAL.
+
+    This class set-up/tear-down the webDB host test framwork and contains host test cases for
+    sensors HIDL HAL.
+    """
+
+    def setUpClass(self):
+        """Creates a mirror and turns on the framework-layer SENSORS 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 self.enable_profiling:
+            profiling_utils.EnableVTSProfiling(self.dut.shell.one)
+
+        self.dut.hal.InitHidlHal(
+            target_type="sensors",
+            target_basepaths=["/system/lib64"],
+            target_version=1.0,
+            target_package="android.hardware.sensors",
+            target_component_name="ISensors",
+            bits=64)
+
+    def tearDownClass(self):
+        """ If profiling is enabled for the test, collect the profiling data
+            and disable profiling after the test is done.
+        """
+        if self.enable_profiling:
+            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 testSensorsBasic(self):
+        """Test the basic operation of test framework and sensor HIDL HAL
+
+        This test obtains predefined enum values via sensors HIDL HAL host test framework and
+        compares them to known values as a sanity check to make sure both sensors HAL
+        and the test framework are working properly.
+        """
+        sensors_types = self.dut.hal.sensors.GetHidlTypeInterface("types")
+        logging.info("sensors_types: %s", sensors_types)
+        logging.info("OK: %s", sensors_types.OK)
+        logging.info("BAD_VALUE: %s", sensors_types.BAD_VALUE)
+        logging.info("PERMISSION_DENIED: %s", sensors_types.PERMISSION_DENIED)
+        logging.info("INVALID_OPERATION: %s", sensors_types.INVALID_OPERATION)
+        asserts.assertEqual(sensors_types.OK, 0);
+        asserts.assertEqual(sensors_types.BAD_VALUE, 1);
+
+        logging.info("sensor types:")
+        logging.info("SENSOR_TYPE_ACCELEROMETER: %s", sensors_types.SENSOR_TYPE_ACCELEROMETER)
+        logging.info("SENSOR_TYPE_GEOMAGNETIC_FIELD: %s", sensors_types.SENSOR_TYPE_GEOMAGNETIC_FIELD)
+        logging.info("SENSOR_TYPE_GYROSCOPE: %s", sensors_types.SENSOR_TYPE_GYROSCOPE)
+        asserts.assertEqual(sensors_types.SENSOR_TYPE_ACCELEROMETER, 1);
+        asserts.assertEqual(sensors_types.SENSOR_TYPE_GEOMAGNETIC_FIELD, 2);
+        asserts.assertEqual(sensors_types.SENSOR_TYPE_GYROSCOPE, 4);
+
+if __name__ == "__main__":
+    test_runner.main()
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/__init__.py b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/__init__.py
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/Android.mk b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/Android.mk
new file mode 100644
index 0000000..c71a661
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/Android.mk
@@ -0,0 +1,25 @@
+#
+# 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)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := SensorsHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/sensors/hidl/target
+include test/vts/tools/build/Android.host_config.mk
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..66317f0
--- /dev/null
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/target/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS sensors HIDL HAL's target-side test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="push-group" value="HidlHalTest.push" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="SensorsHidlTargetTest" />
+        <option name="binary-test-sources" value="
+            _32bit::DATA/nativetest/sensors_hidl_hal_test/sensors_hidl_hal_test,
+            _64bit::DATA/nativetest64/sensors_hidl_hal_test/sensors_hidl_hal_test,
+            "/>
+        <option name="binary-test-type" value="gtest" />
+        <option name="test-timeout" value="10m" />
+    </test>
+</configuration>
+
diff --git a/sensors/1.0/vts/types.vts b/sensors/1.0/vts/types.vts
new file mode 100644
index 0000000..37271fd
--- /dev/null
+++ b/sensors/1.0/vts/types.vts
@@ -0,0 +1,699 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "types"
+
+package: "android.hardware.sensors"
+
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::Result"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int32_t"
+
+        enumerator: "OK"
+        scalar_value: {
+            int32_t: 0
+        }
+        enumerator: "BAD_VALUE"
+        scalar_value: {
+            int32_t: 1
+        }
+        enumerator: "PERMISSION_DENIED"
+        scalar_value: {
+            int32_t: 2
+        }
+        enumerator: "INVALID_OPERATION"
+        scalar_value: {
+            int32_t: 3
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::OperationMode"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int32_t"
+
+        enumerator: "SENSOR_HAL_NORMAL_MODE"
+        scalar_value: {
+            int32_t: 0
+        }
+        enumerator: "SENSOR_HAL_DATA_INJECTION_MODE"
+        scalar_value: {
+            int32_t: 1
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::SensorType"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int32_t"
+
+        enumerator: "SENSOR_TYPE_META_DATA"
+        scalar_value: {
+            int32_t: 0
+        }
+        enumerator: "SENSOR_TYPE_ACCELEROMETER"
+        scalar_value: {
+            int32_t: 1
+        }
+        enumerator: "SENSOR_TYPE_GEOMAGNETIC_FIELD"
+        scalar_value: {
+            int32_t: 2
+        }
+        enumerator: "SENSOR_TYPE_ORIENTATION"
+        scalar_value: {
+            int32_t: 3
+        }
+        enumerator: "SENSOR_TYPE_GYROSCOPE"
+        scalar_value: {
+            int32_t: 4
+        }
+        enumerator: "SENSOR_TYPE_LIGHT"
+        scalar_value: {
+            int32_t: 5
+        }
+        enumerator: "SENSOR_TYPE_PRESSURE"
+        scalar_value: {
+            int32_t: 6
+        }
+        enumerator: "SENSOR_TYPE_TEMPERATURE"
+        scalar_value: {
+            int32_t: 7
+        }
+        enumerator: "SENSOR_TYPE_PROXIMITY"
+        scalar_value: {
+            int32_t: 8
+        }
+        enumerator: "SENSOR_TYPE_GRAVITY"
+        scalar_value: {
+            int32_t: 9
+        }
+        enumerator: "SENSOR_TYPE_LINEAR_ACCELERATION"
+        scalar_value: {
+            int32_t: 10
+        }
+        enumerator: "SENSOR_TYPE_ROTATION_VECTOR"
+        scalar_value: {
+            int32_t: 11
+        }
+        enumerator: "SENSOR_TYPE_RELATIVE_HUMIDITY"
+        scalar_value: {
+            int32_t: 12
+        }
+        enumerator: "SENSOR_TYPE_AMBIENT_TEMPERATURE"
+        scalar_value: {
+            int32_t: 13
+        }
+        enumerator: "SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED"
+        scalar_value: {
+            int32_t: 14
+        }
+        enumerator: "SENSOR_TYPE_GAME_ROTATION_VECTOR"
+        scalar_value: {
+            int32_t: 15
+        }
+        enumerator: "SENSOR_TYPE_GYROSCOPE_UNCALIBRATED"
+        scalar_value: {
+            int32_t: 16
+        }
+        enumerator: "SENSOR_TYPE_SIGNIFICANT_MOTION"
+        scalar_value: {
+            int32_t: 17
+        }
+        enumerator: "SENSOR_TYPE_STEP_DETECTOR"
+        scalar_value: {
+            int32_t: 18
+        }
+        enumerator: "SENSOR_TYPE_STEP_COUNTER"
+        scalar_value: {
+            int32_t: 19
+        }
+        enumerator: "SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR"
+        scalar_value: {
+            int32_t: 20
+        }
+        enumerator: "SENSOR_TYPE_HEART_RATE"
+        scalar_value: {
+            int32_t: 21
+        }
+        enumerator: "SENSOR_TYPE_TILT_DETECTOR"
+        scalar_value: {
+            int32_t: 22
+        }
+        enumerator: "SENSOR_TYPE_WAKE_GESTURE"
+        scalar_value: {
+            int32_t: 23
+        }
+        enumerator: "SENSOR_TYPE_GLANCE_GESTURE"
+        scalar_value: {
+            int32_t: 24
+        }
+        enumerator: "SENSOR_TYPE_PICK_UP_GESTURE"
+        scalar_value: {
+            int32_t: 25
+        }
+        enumerator: "SENSOR_TYPE_WRIST_TILT_GESTURE"
+        scalar_value: {
+            int32_t: 26
+        }
+        enumerator: "SENSOR_TYPE_DEVICE_ORIENTATION"
+        scalar_value: {
+            int32_t: 27
+        }
+        enumerator: "SENSOR_TYPE_POSE_6DOF"
+        scalar_value: {
+            int32_t: 28
+        }
+        enumerator: "SENSOR_TYPE_STATIONARY_DETECT"
+        scalar_value: {
+            int32_t: 29
+        }
+        enumerator: "SENSOR_TYPE_MOTION_DETECT"
+        scalar_value: {
+            int32_t: 30
+        }
+        enumerator: "SENSOR_TYPE_HEART_BEAT"
+        scalar_value: {
+            int32_t: 31
+        }
+        enumerator: "SENSOR_TYPE_DYNAMIC_SENSOR_META"
+        scalar_value: {
+            int32_t: 32
+        }
+        enumerator: "SENSOR_TYPE_ADDITIONAL_INFO"
+        scalar_value: {
+            int32_t: 33
+        }
+        enumerator: "SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT"
+        scalar_value: {
+            int32_t: 34
+        }
+        enumerator: "SENSOR_TYPE_DEVICE_PRIVATE_BASE"
+        scalar_value: {
+            int32_t: 65536
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::SensorFlagBits"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint64_t"
+
+        enumerator: "SENSOR_FLAG_WAKE_UP"
+        scalar_value: {
+            uint64_t: 1
+        }
+        enumerator: "SENSOR_FLAG_CONTINUOUS_MODE"
+        scalar_value: {
+            uint64_t: 0
+        }
+        enumerator: "SENSOR_FLAG_ON_CHANGE_MODE"
+        scalar_value: {
+            uint64_t: 2
+        }
+        enumerator: "SENSOR_FLAG_ONE_SHOT_MODE"
+        scalar_value: {
+            uint64_t: 4
+        }
+        enumerator: "SENSOR_FLAG_SPECIAL_REPORTING_MODE"
+        scalar_value: {
+            uint64_t: 6
+        }
+        enumerator: "SENSOR_FLAG_SUPPORTS_DATA_INJECTION"
+        scalar_value: {
+            uint64_t: 16
+        }
+        enumerator: "SENSOR_FLAG_DYNAMIC_SENSOR"
+        scalar_value: {
+            uint64_t: 32
+        }
+        enumerator: "SENSOR_FLAG_ADDITIONAL_INFO"
+        scalar_value: {
+            uint64_t: 64
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::SensorInfo"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "sensorHandle"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "name"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "vendor"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "version"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "type"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::sensors::V1_0::SensorType"
+    }
+    struct_value: {
+        name: "typeAsString"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "maxRange"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "resolution"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "power"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "minDelay"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "fifoReservedEventCount"
+        type: TYPE_SCALAR
+        scalar_type: "uint32_t"
+    }
+    struct_value: {
+        name: "fifoMaxEventCount"
+        type: TYPE_SCALAR
+        scalar_type: "uint32_t"
+    }
+    struct_value: {
+        name: "requiredPermission"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "maxDelay"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "flags"
+        type: TYPE_SCALAR
+        scalar_type: "uint64_t"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::SensorStatus"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "int8_t"
+
+        enumerator: "SENSOR_STATUS_NO_CONTACT"
+        scalar_value: {
+            int8_t: -1
+        }
+        enumerator: "SENSOR_STATUS_UNRELIABLE"
+        scalar_value: {
+            int8_t: 0
+        }
+        enumerator: "SENSOR_STATUS_ACCURACY_LOW"
+        scalar_value: {
+            int8_t: 1
+        }
+        enumerator: "SENSOR_STATUS_ACCURACY_MEDIUM"
+        scalar_value: {
+            int8_t: 2
+        }
+        enumerator: "SENSOR_STATUS_ACCURACY_HIGH"
+        scalar_value: {
+            int8_t: 3
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::Vec3"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "x"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "y"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "z"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "status"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::sensors::V1_0::SensorStatus"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::Vec4"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "x"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "y"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "z"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "w"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::Uncal"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "x"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "y"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "z"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "x_bias"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "y_bias"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "z_bias"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::HeartRate"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "bpm"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "status"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::sensors::V1_0::SensorStatus"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::MetaDataEventType"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint32_t"
+
+        enumerator: "META_DATA_FLUSH_COMPLETE"
+        scalar_value: {
+            uint32_t: 1
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::MetaData"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "what"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::sensors::V1_0::MetaDataEventType"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::DynamicSensorInfo"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "connected"
+        type: TYPE_SCALAR
+        scalar_type: "bool_t"
+    }
+    struct_value: {
+        name: "sensorHandle"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "uuid"
+        type: TYPE_ARRAY
+        vector_value: {
+            vector_size: 16
+            type: TYPE_SCALAR
+            scalar_type: "uint8_t"
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::AdditionalInfoType"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint32_t"
+
+        enumerator: "AINFO_BEGIN"
+        scalar_value: {
+            uint32_t: 0
+        }
+        enumerator: "AINFO_END"
+        scalar_value: {
+            uint32_t: 1
+        }
+        enumerator: "AINFO_UNTRACKED_DELAY"
+        scalar_value: {
+            uint32_t: 65536
+        }
+        enumerator: "AINFO_INTERNAL_TEMPERATURE"
+        scalar_value: {
+            uint32_t: 65537
+        }
+        enumerator: "AINFO_VEC3_CALIBRATION"
+        scalar_value: {
+            uint32_t: 65538
+        }
+        enumerator: "AINFO_SENSOR_PLACEMENT"
+        scalar_value: {
+            uint32_t: 65539
+        }
+        enumerator: "AINFO_SAMPLING"
+        scalar_value: {
+            uint32_t: 65540
+        }
+        enumerator: "AINFO_CHANNEL_NOISE"
+        scalar_value: {
+            uint32_t: 131072
+        }
+        enumerator: "AINFO_CHANNEL_SAMPLER"
+        scalar_value: {
+            uint32_t: 131073
+        }
+        enumerator: "AINFO_CHANNEL_FILTER"
+        scalar_value: {
+            uint32_t: 131074
+        }
+        enumerator: "AINFO_CHANNEL_LINEAR_TRANSFORM"
+        scalar_value: {
+            uint32_t: 131075
+        }
+        enumerator: "AINFO_CHANNEL_NONLINEAR_MAP"
+        scalar_value: {
+            uint32_t: 131076
+        }
+        enumerator: "AINFO_CHANNEL_RESAMPLER"
+        scalar_value: {
+            uint32_t: 131077
+        }
+        enumerator: "AINFO_CUSTOM_START"
+        scalar_value: {
+            uint32_t: 268435456
+        }
+        enumerator: "AINFO_DEBUGGING_START"
+        scalar_value: {
+            uint32_t: 1073741824
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::AdditionalInfo"
+    type: TYPE_STRUCT
+    sub_struct: {
+        name: "::android::hardware::sensors::V1_0::AdditionalInfo::Payload"
+        type: TYPE_UNION
+        union_value: {
+            name: "data_int32"
+            type: TYPE_ARRAY
+            vector_value: {
+                vector_size: 14
+                type: TYPE_SCALAR
+                scalar_type: "int32_t"
+            }
+        }
+        union_value: {
+            name: "data_float"
+            type: TYPE_ARRAY
+            vector_value: {
+                vector_size: 14
+                type: TYPE_SCALAR
+                scalar_type: "float_t"
+            }
+        }
+    }
+    struct_value: {
+        name: "type"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::sensors::V1_0::AdditionalInfoType"
+    }
+    struct_value: {
+        name: "serial"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "u"
+        type: TYPE_UNION
+        predefined_type: "::android::hardware::sensors::V1_0::AdditionalInfo::Payload"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::EventPayload"
+    type: TYPE_UNION
+    union_value: {
+        name: "vec3"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::Vec3"
+    }
+    union_value: {
+        name: "vec4"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::Vec4"
+    }
+    union_value: {
+        name: "uncal"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::Uncal"
+    }
+    union_value: {
+        name: "meta"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::MetaData"
+    }
+    union_value: {
+        name: "scalar"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    union_value: {
+        name: "stepCount"
+        type: TYPE_SCALAR
+        scalar_type: "uint64_t"
+    }
+    union_value: {
+        name: "heartRate"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::HeartRate"
+    }
+    union_value: {
+        name: "pose6DOF"
+        type: TYPE_ARRAY
+        vector_value: {
+            vector_size: 15
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+    }
+    union_value: {
+        name: "dynamic"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::DynamicSensorInfo"
+    }
+    union_value: {
+        name: "additional"
+        type: TYPE_STRUCT
+        predefined_type: "::android::hardware::sensors::V1_0::AdditionalInfo"
+    }
+    union_value: {
+        name: "data"
+        type: TYPE_ARRAY
+        vector_value: {
+            vector_size: 16
+            type: TYPE_SCALAR
+            scalar_type: "float_t"
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::sensors::V1_0::Event"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "timestamp"
+        type: TYPE_SCALAR
+        scalar_type: "int64_t"
+    }
+    struct_value: {
+        name: "sensorHandle"
+        type: TYPE_SCALAR
+        scalar_type: "int32_t"
+    }
+    struct_value: {
+        name: "sensorType"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::sensors::V1_0::SensorType"
+    }
+    struct_value: {
+        name: "u"
+        type: TYPE_UNION
+        predefined_type: "::android::hardware::sensors::V1_0::EventPayload"
+    }
+}
+
diff --git a/sensors/Android.bp b/sensors/Android.bp
index ba90f2c..9c84fed 100644
--- a/sensors/Android.bp
+++ b/sensors/Android.bp
@@ -2,4 +2,5 @@
 subdirs = [
     "1.0",
     "1.0/default",
+    "1.0/vts/functional"
 ]