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"
]