summaryrefslogtreecommitdiff
path: root/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp')
-rw-r--r--sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp1122
1 files changed, 35 insertions, 1087 deletions
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index c18eedd176..47308e13b9 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -15,583 +15,66 @@
*/
#define LOG_TAG "sensors_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-#include <android-base/logging.h>
+
+#include "SensorsHidlEnvironmentV1_0.h"
+#include "sensors-vts-utils/SensorsHidlTestBase.h"
+
#include <android/hardware/sensors/1.0/ISensors.h>
#include <android/hardware/sensors/1.0/types.h>
-#include <cutils/ashmem.h>
-#include <hardware/sensors.h> // for sensor type strings
#include <log/log.h>
#include <utils/SystemClock.h>
-#include "GrallocWrapper.h"
-#include <algorithm>
#include <cinttypes>
-#include <cmath>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <unordered_set>
#include <vector>
-#include <sys/mman.h>
-#include <unistd.h>
-
-using ::android::GrallocWrapper;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::hardware::hidl_string;
using ::android::sp;
using namespace ::android::hardware::sensors::V1_0;
-// Test environment for sensors
-class SensorsHidlTest;
-class SensorsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static SensorsHidlEnvironment* Instance() {
- static SensorsHidlEnvironment* instance = new SensorsHidlEnvironment;
- return instance;
- }
-
- virtual void HidlSetUp() override;
- virtual void HidlTearDown() override;
-
- virtual void registerTestServices() override { registerTestService<ISensors>(); }
-
- // 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:
- friend SensorsHidlTest;
- // sensors hidl service
- sp<ISensors> sensors;
-
- SensorsHidlEnvironment() {}
-
- void addEvent(const Event& ev);
- void startPollingThread();
- void resetHal();
- 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::HidlSetUp() {
- resetHal();
-
- ASSERT_NE(sensors, nullptr) << "sensors is nullptr, cannot get hidl service";
-
- collectionEnabled = false;
- startPollingThread();
-
- // In case framework just stopped for test and there is sensor events in the pipe,
- // wait some time for those events to be cleared to avoid them messing up the test.
- std::this_thread::sleep_for(std::chrono::seconds(3));
-}
+// The main test class for SENSORS HIDL HAL.
-void SensorsHidlEnvironment::HidlTearDown() {
- if (stopThread) {
- *stopThread = true;
+class SensorsHidlTest : public SensorsHidlTestBase {
+ protected:
+ SensorInfo defaultSensorByType(SensorType type) override;
+ std::vector<SensorInfo> getSensorsList();
+ // implementation wrapper
+ Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) override {
+ return S()->getSensorsList(_hidl_cb);
}
- pollThread.detach();
-}
-
-void SensorsHidlEnvironment::resetHal() {
- // wait upto 100ms * 10 = 1s for hidl service.
- constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
-
- std::string step;
- bool succeed = false;
- for (size_t retry = 10; retry > 0; --retry) {
- // this do ... while is for easy error handling
- do {
- step = "getService()";
- sensors = ISensors::getService(
- SensorsHidlEnvironment::Instance()->getServiceName<ISensors>());
- if (sensors == nullptr) {
- break;
- }
-
- step = "poll() check";
- // Poke ISensor service. If it has lingering connection from previous generation of
- // system server, it will kill itself. There is no intention to handle the poll result,
- // which will be done since the size is 0.
- if(!sensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
- break;
- }
-
- step = "getSensorList";
- std::vector<SensorInfo> sensorList;
- if (!sensors->getSensorsList(
- [&] (const ::android::hardware::hidl_vec<SensorInfo> &list) {
- sensorList.reserve(list.size());
- for (size_t i = 0; i < list.size(); ++i) {
- sensorList.push_back(list[i]);
- }
- }).isOk()) {
- break;
- }
- // stop each sensor individually
- step = "stop each sensor";
- bool ok = true;
- for (const auto &i : sensorList) {
- if (!sensors->activate(i.sensorHandle, false).isOk()) {
- ok = false;
- break;
- }
- }
- if (!ok) {
- break;
- }
-
- // mark it done
- step = "done";
- succeed = true;
- } while(0);
+ Return<Result> activate(int32_t sensorHandle, bool enabled) override;
- if (succeed) {
- return;
+ Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+ int64_t maxReportLatencyNs) override {
+ return S()->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
}
- // Delay 100ms before retry, hidl service is expected to come up in short time after crash.
- ALOGI("%s unsuccessful, try again soon (remaining retry %zu).", step.c_str(), retry - 1);
- std::this_thread::sleep_for(RETRY_DELAY);
- }
-
- sensors = nullptr;
-}
+ Return<Result> flush(int32_t sensorHandle) override { return S()->flush(sensorHandle); }
-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(64, [&](auto result, const auto& events, const auto& dynamicSensorsAdded) {
- if (result != Result::OK
- || (events.size() == 0 && dynamicSensorsAdded.size() == 0)
- || *stop) {
- needExit = true;
- return;
- }
-
- for (const auto& e : events) {
- env->addEvent(e);
- }
- });
- }
- ALOGD("polling thread end");
-}
-
-class SensorsTestSharedMemory {
- public:
- static SensorsTestSharedMemory* create(SharedMemType type, size_t size);
- SharedMemInfo getSharedMemInfo() const;
- char * getBuffer() const;
- std::vector<Event> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const;
- virtual ~SensorsTestSharedMemory();
- private:
- SensorsTestSharedMemory(SharedMemType type, size_t size);
-
- SharedMemType mType;
- native_handle_t* mNativeHandle;
- size_t mSize;
- char* mBuffer;
- std::unique_ptr<GrallocWrapper> mGrallocWrapper;
-
- DISALLOW_COPY_AND_ASSIGN(SensorsTestSharedMemory);
-};
-
-SharedMemInfo SensorsTestSharedMemory::getSharedMemInfo() const {
- SharedMemInfo mem = {
- .type = mType,
- .format = SharedMemFormat::SENSORS_EVENT,
- .size = static_cast<uint32_t>(mSize),
- .memoryHandle = mNativeHandle
- };
- return mem;
-}
-
-char * SensorsTestSharedMemory::getBuffer() const {
- return mBuffer;
-}
-
-std::vector<Event> SensorsTestSharedMemory::parseEvents(int64_t lastCounter, size_t offset) const {
-
- constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
- constexpr size_t kOffsetSize = static_cast<size_t>(SensorsEventFormatOffset::SIZE_FIELD);
- constexpr size_t kOffsetToken = static_cast<size_t>(SensorsEventFormatOffset::REPORT_TOKEN);
- constexpr size_t kOffsetType = static_cast<size_t>(SensorsEventFormatOffset::SENSOR_TYPE);
- constexpr size_t kOffsetAtomicCounter =
- static_cast<size_t>(SensorsEventFormatOffset::ATOMIC_COUNTER);
- constexpr size_t kOffsetTimestamp = static_cast<size_t>(SensorsEventFormatOffset::TIMESTAMP);
- constexpr size_t kOffsetData = static_cast<size_t>(SensorsEventFormatOffset::DATA);
-
- std::vector<Event> events;
- std::vector<float> data(16);
-
- while (offset + kEventSize <= mSize) {
- int64_t atomicCounter = *reinterpret_cast<uint32_t *>(mBuffer + offset + kOffsetAtomicCounter);
- if (atomicCounter <= lastCounter) {
- ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, lastCounter);
- break;
+ Return<Result> injectSensorData(const Event& event) override {
+ return S()->injectSensorData(event);
}
- int32_t size = *reinterpret_cast<int32_t *>(mBuffer + offset + kOffsetSize);
- if (size != kEventSize) {
- // unknown error, events parsed may be wrong, remove all
- events.clear();
- break;
- }
-
- int32_t token = *reinterpret_cast<int32_t *>(mBuffer + offset + kOffsetToken);
- int32_t type = *reinterpret_cast<int32_t *>(mBuffer + offset + kOffsetType);
- int64_t timestamp = *reinterpret_cast<int64_t *>(mBuffer + offset + kOffsetTimestamp);
-
- ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 ", timestamp %" PRId64,
- offset, atomicCounter, token, type, timestamp);
-
- Event event = {
- .timestamp = timestamp,
- .sensorHandle = token,
- .sensorType = static_cast<SensorType>(type),
- };
- event.u.data = android::hardware::hidl_array<float, 16>
- (reinterpret_cast<float*>(mBuffer + offset + kOffsetData));
+ Return<void> registerDirectChannel(const SharedMemInfo& mem,
+ ISensors::registerDirectChannel_cb _hidl_cb) override;
- events.push_back(event);
-
- lastCounter = atomicCounter;
- offset += kEventSize;
- }
-
- return events;
-}
-
-SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size)
- : mType(type), mSize(0), mBuffer(nullptr) {
- native_handle_t *handle = nullptr;
- char *buffer = nullptr;
- switch(type) {
- case SharedMemType::ASHMEM: {
- int fd;
- handle = ::native_handle_create(1 /*nFds*/, 0/*nInts*/);
- if (handle != nullptr) {
- handle->data[0] = fd = ::ashmem_create_region("SensorsTestSharedMemory", size);
- if (handle->data[0] > 0) {
- // memory is pinned by default
- buffer = static_cast<char *>
- (::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
- if (buffer != reinterpret_cast<char*>(MAP_FAILED)) {
- break;
- }
- ::native_handle_close(handle);
- }
- ::native_handle_delete(handle);
- handle = nullptr;
- }
- break;
+ Return<Result> unregisterDirectChannel(int32_t channelHandle) override {
+ return S()->unregisterDirectChannel(channelHandle);
}
- case SharedMemType::GRALLOC: {
- mGrallocWrapper = std::make_unique<GrallocWrapper>();
- if (mGrallocWrapper->getAllocator() == nullptr || mGrallocWrapper->getMapper() == nullptr) {
- break;
- }
- using android::hardware::graphics::common::V1_0::BufferUsage;
- using android::hardware::graphics::common::V1_0::PixelFormat;
- mapper2::IMapper::BufferDescriptorInfo buf_desc_info = {
- .width = static_cast<uint32_t>(size),
- .height = 1,
- .layerCount = 1,
- .usage = static_cast<uint64_t> (BufferUsage::SENSOR_DIRECT_DATA |
- BufferUsage::CPU_READ_OFTEN),
- .format = PixelFormat::BLOB
- };
-
- handle = const_cast<native_handle_t *>(mGrallocWrapper->allocate(buf_desc_info));
- if (handle != nullptr) {
- mapper2::IMapper::Rect region{0, 0,
- static_cast<int32_t>(buf_desc_info.width),
- static_cast<int32_t>(buf_desc_info.height)};
- buffer = static_cast<char *>
- (mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1));
- if (buffer != nullptr) {
- break;
- }
- mGrallocWrapper->freeBuffer(handle);
- handle = nullptr;
- }
- break;
- }
- default:
- break;
- }
-
- if (buffer != nullptr) {
- mNativeHandle = handle;
- mSize = size;
- mBuffer = buffer;
- }
-}
-
-SensorsTestSharedMemory::~SensorsTestSharedMemory() {
- switch(mType) {
- case SharedMemType::ASHMEM: {
- if (mSize != 0) {
- ::munmap(mBuffer, mSize);
- mBuffer = nullptr;
-
- ::native_handle_close(mNativeHandle);
- ::native_handle_delete(mNativeHandle);
-
- mNativeHandle = nullptr;
- mSize = 0;
- }
- break;
- }
- case SharedMemType::GRALLOC: {
- if (mSize != 0) {
- mGrallocWrapper->unlock(mNativeHandle);
- mGrallocWrapper->freeBuffer(mNativeHandle);
-
- mNativeHandle = nullptr;
- mSize = 0;
- }
- break;
- }
- default: {
- if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) {
- ALOGE("SensorsTestSharedMemory %p not properly destructed: "
- "type %d, native handle %p, size %zu, buffer %p",
- this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer);
- }
- break;
- }
- }
-}
-
-SensorsTestSharedMemory* SensorsTestSharedMemory::create(SharedMemType type, size_t size) {
- constexpr size_t kMaxSize = 128*1024*1024; // sensor test should not need more than 128M
- if (size == 0 || size >= kMaxSize) {
- return nullptr;
- }
-
- auto m = new SensorsTestSharedMemory(type, size);
- if (m->mSize != size || m->mBuffer == nullptr) {
- delete m;
- m = nullptr;
- }
- return m;
-}
-
-class SensorEventsChecker {
- public:
- virtual bool check(const std::vector<Event> &events, std::string *out) const = 0;
- virtual ~SensorEventsChecker() {}
-};
-
-class NullChecker : public SensorEventsChecker {
- public:
- virtual bool check(const std::vector<Event> &, std::string *) const {
- return true;
- }
-};
-
-class SensorEventPerEventChecker : public SensorEventsChecker {
- public:
- virtual bool checkEvent(const Event &event, std::string *out) const = 0;
- virtual bool check(const std::vector<Event> &events, std::string *out) const {
- for (const auto &e : events) {
- if (!checkEvent(e, out)) {
- return false;
- }
- }
- return true;
- }
-};
-
-class Vec3NormChecker : public SensorEventPerEventChecker {
- public:
- Vec3NormChecker(float min, float max) : mRange(min, max) {}
- static Vec3NormChecker byNominal(float nominal, float allowedError) {
- return Vec3NormChecker(nominal - allowedError, nominal + allowedError);
- }
- virtual bool checkEvent(const Event &event, std::string *out) const {
- Vec3 v = event.u.vec3;
- float norm = std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
- if (norm < mRange.first || norm > mRange.second) {
- if (out != nullptr) {
- std::ostringstream ss;
- ss << "Event @ " << event.timestamp << " (" << v.x << ", " << v.y << ", " << v.z << ")"
- << " has norm " << norm << ", which is beyond range"
- << " [" << mRange.first << ", " << mRange.second << "]";
- *out = ss.str();
- }
- return false;
+ Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
+ ISensors::configDirectReport_cb _hidl_cb) override {
+ return S()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
}
- return true;
- }
- protected:
- std::pair<float, float> mRange;
-};
-
-// The main test class for SENSORS HIDL HAL.
-class SensorsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
- virtual void SetUp() override {
- }
- virtual void TearDown() override {
- // stop all sensors
- for (auto s : mSensorHandles) {
- S()->activate(s, false);
- }
- mSensorHandles.clear();
+ inline sp<ISensors>& S() { return SensorsHidlEnvironmentV1_0::Instance()->sensors; }
- // stop all direct report and channels
- for (auto c : mDirectChannelHandles) {
- // disable all reports
- S()->configDirectReport(-1, c, RateLevel::STOP, [] (auto, auto){});
- S()->unregisterDirectChannel(c);
+ SensorsHidlEnvironmentBase* getEnvironment() override {
+ return SensorsHidlEnvironmentV1_0::Instance();
}
- mDirectChannelHandles.clear();
- }
-
- protected:
- SensorInfo defaultSensorByType(SensorType type);
- std::vector<SensorInfo> getSensorsList();
- std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
- bool clearBeforeStart = true, bool changeCollection = true);
-
- // implementation wrapper
- Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) {
- return S()->getSensorsList(_hidl_cb);
- }
-
- Return<Result> activate(
- int32_t sensorHandle, bool enabled);
-
- Return<Result> batch(
- int32_t sensorHandle,
- int64_t samplingPeriodNs,
- int64_t maxReportLatencyNs) {
- return S()->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
- }
-
- Return<Result> flush(int32_t sensorHandle) {
- return S()->flush(sensorHandle);
- }
-
- Return<Result> injectSensorData(const Event& event) {
- return S()->injectSensorData(event);
- }
-
- Return<void> registerDirectChannel(
- const SharedMemInfo& mem, ISensors::registerDirectChannel_cb _hidl_cb);
-
- Return<Result> unregisterDirectChannel(int32_t channelHandle) {
- return S()->unregisterDirectChannel(channelHandle);
- }
-
- Return<void> configDirectReport(
- int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
- ISensors::configDirectReport_cb _hidl_cb) {
- return S()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
- }
-
- inline sp<ISensors>& S() {
- return SensorsHidlEnvironment::Instance()->sensors;
- }
-
- inline static SensorFlagBits extractReportMode(uint64_t flag) {
- return (SensorFlagBits) (flag
- & ((uint64_t) SensorFlagBits::CONTINUOUS_MODE
- | (uint64_t) SensorFlagBits::ON_CHANGE_MODE
- | (uint64_t) SensorFlagBits::ONE_SHOT_MODE
- | (uint64_t) SensorFlagBits::SPECIAL_REPORTING_MODE));
- }
-
- inline static bool isMetaSensorType(SensorType type) {
- return (type == SensorType::META_DATA
- || type == SensorType::DYNAMIC_SENSOR_META
- || type == SensorType::ADDITIONAL_INFO);
- }
-
- inline static bool isValidType(SensorType type) {
- return (int32_t) type > 0;
- }
-
- void testStreamingOperation(SensorType type,
- std::chrono::nanoseconds samplingPeriod,
- std::chrono::seconds duration,
- const SensorEventsChecker &checker);
- void testSamplingRateHotSwitchOperation(SensorType type, bool fastToSlow = true);
- void testBatchingOperation(SensorType type);
- void testDirectReportOperation(
- SensorType type, SharedMemType memType, RateLevel rate, const SensorEventsChecker &checker);
-
- static void assertTypeMatchStringType(SensorType type, const hidl_string& stringType);
- static void assertTypeMatchReportMode(SensorType type, SensorFlagBits reportMode);
- static void assertDelayMatchReportMode(
- int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode);
- static SensorFlagBits expectedReportModeForType(SensorType type);
- static bool isDirectReportRateSupported(SensorInfo sensor, RateLevel rate);
- static bool isDirectChannelTypeSupported(SensorInfo sensor, SharedMemType type);
-
- // checkers
- static const Vec3NormChecker sAccelNormChecker;
- static const Vec3NormChecker sGyroNormChecker;
-
- // all sensors and direct channnels used
- std::unordered_set<int32_t> mSensorHandles;
- std::unordered_set<int32_t> mDirectChannelHandles;
};
-const Vec3NormChecker SensorsHidlTest::sAccelNormChecker(
- Vec3NormChecker::byNominal(GRAVITY_EARTH, 1.0f/*m/s^2*/));
-const Vec3NormChecker SensorsHidlTest::sGyroNormChecker(
- Vec3NormChecker::byNominal(0.f, 0.1f/*rad/s*/));
-
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
// If activating a sensor, add the handle in a set so that when test fails it can be turned off.
// The handle is not removed when it is deactivating on purpose so that it is not necessary to
@@ -618,195 +101,6 @@ Return<void> SensorsHidlTest::registerDirectChannel(
return Void();
}
-std::vector<Event> SensorsHidlTest::collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
- bool clearBeforeStart, bool changeCollection) {
- std::vector<Event> events;
- constexpr useconds_t SLEEP_GRANULARITY = 100*1000; //granularity 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;
-}
-
-void SensorsHidlTest::assertTypeMatchStringType(SensorType type, const hidl_string& stringType) {
-
- if (type >= SensorType::DEVICE_PRIVATE_BASE) {
- return;
- }
-
- switch (type) {
-#define CHECK_TYPE_STRING_FOR_SENSOR_TYPE(type) \
- case SensorType::type: ASSERT_STREQ(SENSOR_STRING_TYPE_ ## type, stringType.c_str()); break;
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER_UNCALIBRATED);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(AMBIENT_TEMPERATURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GAME_ROTATION_VECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GEOMAGNETIC_ROTATION_VECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_RATE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TEMPERATURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TILT_DETECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WAKE_GESTURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WRIST_TILT_GESTURE);
- default:
- FAIL() << "Type " << static_cast<int>(type) << " in android defined range is not checked, "
- << "stringType = " << stringType;
-#undef CHECK_TYPE_STRING_FOR_SENSOR_TYPE
- }
-}
-
-void SensorsHidlTest::assertTypeMatchReportMode(SensorType type, SensorFlagBits reportMode) {
- if (type >= SensorType::DEVICE_PRIVATE_BASE) {
- return;
- }
-
- SensorFlagBits expected = expectedReportModeForType(type);
-
- ASSERT_TRUE(expected == (SensorFlagBits) -1 || expected == reportMode)
- << "reportMode=" << static_cast<int>(reportMode)
- << "expected=" << static_cast<int>(expected);
-}
-
-void SensorsHidlTest::assertDelayMatchReportMode(
- int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode) {
- switch(reportMode) {
- case SensorFlagBits::CONTINUOUS_MODE:
- ASSERT_LT(0, minDelay);
- ASSERT_LE(0, maxDelay);
- break;
- case SensorFlagBits::ON_CHANGE_MODE:
- ASSERT_LE(0, minDelay);
- ASSERT_LE(0, maxDelay);
- break;
- case SensorFlagBits::ONE_SHOT_MODE:
- ASSERT_EQ(-1, minDelay);
- ASSERT_EQ(0, maxDelay);
- break;
- case SensorFlagBits::SPECIAL_REPORTING_MODE:
- // do not enforce anything for special reporting mode
- break;
- default:
- FAIL() << "Report mode " << static_cast<int>(reportMode) << " not checked";
- }
-}
-
-// return -1 means no expectation for this type
-SensorFlagBits SensorsHidlTest::expectedReportModeForType(SensorType type) {
- switch (type) {
- case SensorType::ACCELEROMETER:
- case SensorType::ACCELEROMETER_UNCALIBRATED:
- case SensorType::GYROSCOPE:
- case SensorType::MAGNETIC_FIELD:
- case SensorType::ORIENTATION:
- case SensorType::PRESSURE:
- case SensorType::TEMPERATURE:
- case SensorType::GRAVITY:
- case SensorType::LINEAR_ACCELERATION:
- case SensorType::ROTATION_VECTOR:
- case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
- case SensorType::GAME_ROTATION_VECTOR:
- case SensorType::GYROSCOPE_UNCALIBRATED:
- case SensorType::GEOMAGNETIC_ROTATION_VECTOR:
- case SensorType::POSE_6DOF:
- case SensorType::HEART_BEAT:
- return SensorFlagBits::CONTINUOUS_MODE;
-
- case SensorType::LIGHT:
- case SensorType::PROXIMITY:
- case SensorType::RELATIVE_HUMIDITY:
- case SensorType::AMBIENT_TEMPERATURE:
- case SensorType::HEART_RATE:
- case SensorType::DEVICE_ORIENTATION:
- case SensorType::STEP_COUNTER:
- case SensorType::LOW_LATENCY_OFFBODY_DETECT:
- return SensorFlagBits::ON_CHANGE_MODE;
-
- case SensorType::SIGNIFICANT_MOTION:
- case SensorType::WAKE_GESTURE:
- case SensorType::GLANCE_GESTURE:
- case SensorType::PICK_UP_GESTURE:
- case SensorType::MOTION_DETECT:
- case SensorType::STATIONARY_DETECT:
- return SensorFlagBits::ONE_SHOT_MODE;
-
- case SensorType::STEP_DETECTOR:
- case SensorType::TILT_DETECTOR:
- case SensorType::WRIST_TILT_GESTURE:
- case SensorType::DYNAMIC_SENSOR_META:
- return SensorFlagBits::SPECIAL_REPORTING_MODE;
-
- default:
- ALOGW("Type %d is not implemented in expectedReportModeForType", (int)type);
- return (SensorFlagBits)-1;
- }
-}
-
-bool SensorsHidlTest::isDirectReportRateSupported(SensorInfo sensor, RateLevel rate) {
- unsigned int r =
- static_cast<unsigned int>(sensor.flags & SensorFlagBits::MASK_DIRECT_REPORT)
- >> static_cast<unsigned int>(SensorFlagShift::DIRECT_REPORT);
- return r >= static_cast<unsigned int>(rate);
-}
-
-bool SensorsHidlTest::isDirectChannelTypeSupported(SensorInfo sensor, SharedMemType type) {
- switch (type) {
- case SharedMemType::ASHMEM:
- return (sensor.flags & SensorFlagBits::DIRECT_CHANNEL_ASHMEM) != 0;
- case SharedMemType::GRALLOC:
- return (sensor.flags & SensorFlagBits::DIRECT_CHANNEL_GRALLOC) != 0;
- default:
- return false;
- }
-}
-
SensorInfo SensorsHidlTest::defaultSensorByType(SensorType type) {
SensorInfo ret;
@@ -951,69 +245,6 @@ TEST_F(SensorsHidlTest, InjectSensorEventData) {
ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
}
-void SensorsHidlTest::testStreamingOperation(SensorType type,
- std::chrono::nanoseconds samplingPeriod,
- std::chrono::seconds duration,
- const SensorEventsChecker &checker) {
- std::vector<Event> events;
- std::vector<Event> sensorEvents;
-
- const int64_t samplingPeriodInNs = samplingPeriod.count();
- const int64_t batchingPeriodInNs = 0; // no batching
- const useconds_t minTimeUs = std::chrono::microseconds(duration).count();
- const size_t minNEvent = duration / samplingPeriod;
-
- SensorInfo sensor = defaultSensorByType(type);
-
- if (!isValidType(sensor.type)) {
- // no default sensor of this type
- return;
- }
-
- if (std::chrono::microseconds(sensor.minDelay) > samplingPeriod) {
- // rate not supported
- return;
- }
-
- int32_t handle = sensor.sensorHandle;
-
- ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
- ASSERT_EQ(activate(handle, 1), Result::OK);
- events = collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
- ASSERT_EQ(activate(handle, 0), Result::OK);
-
- ALOGI("Collected %zu samples", events.size());
-
- ASSERT_GT(events.size(), 0u);
-
- bool handleMismatchReported = false;
- bool metaSensorTypeErrorReported = false;
- for (auto & e : events) {
- if (e.sensorType == type) {
- // avoid generating hundreds of error
- if (!handleMismatchReported) {
- EXPECT_EQ(e.sensorHandle, handle)
- << (handleMismatchReported = true,
- "Event of the same type must come from the sensor registered");
- }
- sensorEvents.push_back(e);
- } else {
- // avoid generating hundreds of error
- if (!metaSensorTypeErrorReported) {
- EXPECT_TRUE(isMetaSensorType(e.sensorType))
- << (metaSensorTypeErrorReported = true,
- "Only meta types are allowed besides the type registered");
- }
- }
- }
-
- std::string s;
- EXPECT_TRUE(checker.check(sensorEvents, &s)) << s;
-
- EXPECT_GE(sensorEvents.size(),
- minNEvent / 2); // make sure returned events are not all meta
-}
-
// Test if sensor hal can do UI speed accelerometer streaming properly
TEST_F(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
testStreamingOperation(SensorType::ACCELEROMETER,
@@ -1086,103 +317,6 @@ TEST_F(SensorsHidlTest, MagnetometerStreamingOperationFast) {
NullChecker());
}
-void SensorsHidlTest::testSamplingRateHotSwitchOperation(SensorType type, bool fastToSlow) {
- std::vector<Event> events1, events2;
-
- constexpr int64_t batchingPeriodInNs = 0; // no batching
- constexpr int64_t collectionTimeoutUs = 60000000; // 60s
- constexpr size_t minNEvent = 50;
-
- 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;
- }
-
- int64_t firstCollectionPeriod = fastToSlow ? minSamplingPeriodInNs : maxSamplingPeriodInNs;
- int64_t secondCollectionPeriod = !fastToSlow ? minSamplingPeriodInNs : maxSamplingPeriodInNs;
-
- // first collection
- ASSERT_EQ(batch(handle, firstCollectionPeriod, batchingPeriodInNs), Result::OK);
- ASSERT_EQ(activate(handle, 1), Result::OK);
-
- usleep(500000); // sleep 0.5 sec to wait for change rate to happen
- events1 = collectEvents(collectionTimeoutUs, minNEvent);
-
- // second collection, without stop sensor
- ASSERT_EQ(batch(handle, secondCollectionPeriod, batchingPeriodInNs), Result::OK);
-
- usleep(500000); // sleep 0.5 sec to wait for change rate to happen
- events2 = collectEvents(collectionTimeoutUs, minNEvent);
-
- // end of collection, stop sensor
- ASSERT_EQ(activate(handle, 0), Result::OK);
-
- 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;
- std::vector<Event> &minDelayEvents(fastToSlow ? events1 : events2);
- std::vector<Event> &maxDelayEvents(fastToSlow ? events2 : events1);
-
- size_t nEvent = 0;
- int64_t prevTimestamp = -1;
- int64_t timestampInterval = 0;
- for (auto & e : minDelayEvents) {
- if (e.sensorType == type) {
- ASSERT_EQ(e.sensorHandle, handle);
- if (prevTimestamp > 0) {
- timestampInterval += e.timestamp - prevTimestamp;
- }
- prevTimestamp = e.timestamp;
- ++ nEvent;
- }
- }
- ASSERT_GT(nEvent, 2u);
- minDelayAverageInterval = timestampInterval / (nEvent - 1);
-
- nEvent = 0;
- prevTimestamp = -1;
- timestampInterval = 0;
- for (auto & e : maxDelayEvents) {
- if (e.sensorType == type) {
- ASSERT_EQ(e.sensorHandle, handle);
- if (prevTimestamp > 0) {
- timestampInterval += e.timestamp - prevTimestamp;
- }
- prevTimestamp = e.timestamp;
- ++ nEvent;
- }
- }
- ASSERT_GT(nEvent, 2u);
- maxDelayAverageInterval = timestampInterval / (nEvent - 1);
-
- // change of rate is significant.
- ALOGI("min/maxDelayAverageInterval = %" PRId64 " %" PRId64,
- minDelayAverageInterval, maxDelayAverageInterval);
- EXPECT_GT((maxDelayAverageInterval - minDelayAverageInterval), minDelayAverageInterval / 10);
-
- // fastest rate sampling time is close to spec
- EXPECT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
- minSamplingPeriodInNs / 10);
-
- // slowest rate sampling time is close to spec
- EXPECT_LT(std::abs(maxDelayAverageInterval - maxSamplingPeriodInNs),
- maxSamplingPeriodInNs / 10);
-}
-
// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
@@ -1201,74 +335,6 @@ TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
}
-void SensorsHidlTest::testBatchingOperation(SensorType type) {
- std::vector<Event> events;
-
- constexpr int64_t maxBatchingTestTimeNs = 30ull * 1000 * 1000 * 1000;
- constexpr int64_t oneSecondInNs = 1ull * 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);
-
- ASSERT_EQ(batch(handle, minSamplingPeriodInNs, INT64_MAX), Result::OK);
- ASSERT_EQ(activate(handle, 1), Result::OK);
-
- usleep(500000); // sleep 0.5 sec to wait for initialization
- ASSERT_EQ(flush(handle), Result::OK);
-
- // 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);
- // clean existing collections
- collectEvents(0 /*timeLimitUs*/, 0/*nEventLimit*/,
- true /*clearBeforeStart*/, false /*change collection*/);
-
- // 0.8 + 0.2 times the batching period
- usleep(batchingPeriodInNs / 1000 * 8 / 10);
- ASSERT_EQ(flush(handle), Result::OK);
-
- // plus some time for the event to deliver
- events = collectEvents(allowedBatchDeliverTimeNs / 1000,
- minFifoCount, false /*clearBeforeStart*/, false /*change collection*/);
-
- SensorsHidlEnvironment::Instance()->setCollection(false);
- ASSERT_EQ(activate(handle, 0), Result::OK);
-
- 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)(minFifoCount * 9 / 10));
-}
-
// Test if sensor hal can do accelerometer batching properly
TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
testBatchingOperation(SensorType::ACCELEROMETER);
@@ -1284,124 +350,6 @@ TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
testBatchingOperation(SensorType::MAGNETIC_FIELD);
}
-void SensorsHidlTest::testDirectReportOperation(
- SensorType type, SharedMemType memType, RateLevel rate, const SensorEventsChecker &checker) {
- constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
- constexpr size_t kNEvent = 4096;
- constexpr size_t kMemSize = kEventSize * kNEvent;
-
- constexpr float kNormalNominal = 50;
- constexpr float kFastNominal = 200;
- constexpr float kVeryFastNominal = 800;
-
- constexpr float kNominalTestTimeSec = 1.f;
- constexpr float kMaxTestTimeSec = kNominalTestTimeSec + 0.5f; // 0.5 second for initialization
-
- SensorInfo sensor = defaultSensorByType(type);
-
- if (!isValidType(sensor.type)) {
- // no default sensor of this type
- return;
- }
-
- if (!isDirectReportRateSupported(sensor, rate)) {
- return;
- }
-
- if (!isDirectChannelTypeSupported(sensor, memType)) {
- return;
- }
-
- std::unique_ptr<SensorsTestSharedMemory>
- mem(SensorsTestSharedMemory::create(memType, kMemSize));
- ASSERT_NE(mem, nullptr);
-
- char* buffer = mem->getBuffer();
- // fill memory with data
- for (size_t i = 0; i < kMemSize; ++i) {
- buffer[i] = '\xcc';
- }
-
- int32_t channelHandle;
- registerDirectChannel(mem->getSharedMemInfo(),
- [&channelHandle] (auto result, auto channelHandle_) {
- ASSERT_EQ(result, Result::OK);
- channelHandle = channelHandle_;
- });
-
- // check memory is zeroed
- for (size_t i = 0; i < kMemSize; ++i) {
- ASSERT_EQ(buffer[i], '\0');
- }
-
- int32_t eventToken;
- configDirectReport(sensor.sensorHandle, channelHandle, rate,
- [&eventToken] (auto result, auto token) {
- ASSERT_EQ(result, Result::OK);
- eventToken = token;
- });
-
- usleep(static_cast<useconds_t>(kMaxTestTimeSec * 1e6f));
- auto events = mem->parseEvents();
-
- // find norminal rate
- float nominalFreq = 0.f;
- switch (rate) {
- case RateLevel::NORMAL:
- nominalFreq = kNormalNominal;
- break;
- case RateLevel::FAST:
- nominalFreq = kFastNominal;
- break;
- case RateLevel::VERY_FAST:
- nominalFreq = kVeryFastNominal;
- break;
- case RateLevel::STOP:
- FAIL();
- }
-
- // allowed to be between 55% and 220% of nominal freq
- ASSERT_GT(events.size(), static_cast<size_t>(nominalFreq * 0.55f * kNominalTestTimeSec));
- ASSERT_LT(events.size(), static_cast<size_t>(nominalFreq * 2.2f * kMaxTestTimeSec));
-
- int64_t lastTimestamp = 0;
- bool typeErrorReported = false;
- bool tokenErrorReported = false;
- bool timestampErrorReported = false;
- std::vector<Event> sensorEvents;
- for (auto &e : events) {
- if (!tokenErrorReported) {
- EXPECT_EQ(eventToken, e.sensorHandle)
- << (tokenErrorReported = true,
- "Event token does not match that retured from configDirectReport");
- }
-
- if (isMetaSensorType(e.sensorType)) {
- continue;
- }
- sensorEvents.push_back(e);
-
- if (!typeErrorReported) {
- EXPECT_EQ(type, e.sensorType)
- << (typeErrorReported = true,
- "Type in event does not match type of sensor registered.");
- }
- if (!timestampErrorReported) {
- EXPECT_GT(e.timestamp, lastTimestamp)
- << (timestampErrorReported = true, "Timestamp not monotonically increasing");
- }
- lastTimestamp = e.timestamp;
- }
-
- std::string s;
- EXPECT_TRUE(checker.check(sensorEvents, &s)) << s;
-
- // stop sensor and unregister channel
- configDirectReport(sensor.sensorHandle, channelHandle, RateLevel::STOP,
- [](auto result, auto) { EXPECT_EQ(result, Result::OK); });
- EXPECT_EQ(unregisterDirectChannel(channelHandle), Result::OK);
-}
-
// Test sensor event direct report with ashmem for accel sensor at normal rate
TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
@@ -1511,11 +459,11 @@ TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
}
int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SensorsHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
+ ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV1_0::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ SensorsHidlEnvironmentV1_0::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
}
// vim: set ts=2 sw=2