| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #define LOG_TAG "HidRawDeviceTest" |
| |
| #include "HidRawDevice.h" |
| #include "HidRawSensor.h" |
| #include "HidSensorDef.h" |
| #include "SensorEventCallback.h" |
| #include "Utils.h" |
| #include "HidLog.h" |
| #include "StreamIoUtil.h" |
| |
| namespace android { |
| namespace SensorHalExt { |
| |
| /* |
| * Host test that verifies HidRawDevice and HidRawSensor works correctly. |
| */ |
| class HidRawDeviceTest { |
| public: |
| static void test(const char *devicePath) { |
| using namespace Hid::Sensor::SensorTypeUsage; |
| using HidUtil::hexdumpToStream; |
| |
| std::unordered_set<unsigned int> interestedUsage{ |
| ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM}; |
| |
| SP(HidRawDevice) device = |
| std::make_shared<HidRawDevice>(std::string(devicePath), interestedUsage); |
| const HidDevice::HidDeviceInfo &info = device->getDeviceInfo(); |
| |
| LOG_V << "Sizeof descriptor: " << info.descriptor.size() << LOG_ENDL; |
| LOG_V << "Descriptor: " << LOG_ENDL; |
| hexdumpToStream(LOG_V, info.descriptor.begin(), info.descriptor.end()); |
| |
| if (!device->isValid()) { |
| LOG_E << "invalid device" << LOG_ENDL; |
| return; |
| } |
| |
| LOG_V << "Digest: " << LOG_ENDL; |
| LOG_V << device->mDigestVector; |
| |
| std::vector<uint8_t> buffer; |
| // Dump first few feature ID to help debugging. |
| // If device does not implement all these features, it will show error messages. |
| for (int featureId = 0; featureId <= 5; ++featureId) { |
| if (!device->getFeature(featureId, &buffer)) { |
| LOG_E << "cannot get feature " << featureId << LOG_ENDL; |
| } else { |
| LOG_V << "Dump of feature " << featureId << LOG_ENDL; |
| hexdumpToStream(LOG_V, buffer.begin(), buffer.end()); |
| } |
| } |
| // |
| // use HidRawSensor to operate the device, pick first digest |
| // |
| auto &reportDigest = device->mDigestVector[0]; |
| SP(HidRawSensor) sensor = std::make_shared<HidRawSensor>( |
| device, reportDigest.fullUsage, reportDigest.packets); |
| |
| if (!sensor->isValid()) { |
| LOG_E << "Sensor is not valid " << LOG_ENDL; |
| return; |
| } |
| |
| const sensor_t *s = sensor->getSensor(); |
| LOG_V << "Sensor name: " << s->name << ", vendor: " << s->vendor << LOG_ENDL; |
| LOG_V << sensor->dump() << LOG_ENDL; |
| |
| class Callback : public SensorEventCallback { |
| virtual int submitEvent(SP(BaseSensorObject) /*sensor*/, const sensors_event_t &e) { |
| LOG_V << "sensor: " << e.sensor << ", type: " << e.type << ", ts: " << e.timestamp |
| << ", values (" << e.data[0] << ", " << e.data[1] << ", " << e.data[2] << ")" |
| << LOG_ENDL; |
| return 1; |
| } |
| }; |
| Callback callback; |
| sensor->setEventCallback(&callback); |
| |
| // Request sensor samples at to 10Hz (100ms) |
| sensor->batch(100LL*1000*1000 /*ns*/, 0); |
| sensor->enable(true); |
| |
| // get a couple of events |
| for (size_t i = 0; i < 100; ++i) { |
| uint8_t id; |
| if (!device->receiveReport(&id, &buffer)) { |
| LOG_E << "Receive report error" << LOG_ENDL; |
| continue; |
| } |
| sensor->handleInput(id, buffer); |
| } |
| |
| // clean up |
| sensor->enable(false); |
| |
| LOG_V << "Done!" << LOG_ENDL; |
| } |
| }; |
| } //namespace SensorHalExt |
| } //namespace android |
| |
| int main(int argc, char* argv[]) { |
| if (argc != 2) { |
| LOG_E << "Usage: " << argv[0] << " hidraw-dev-path" << LOG_ENDL; |
| return -1; |
| } |
| android::SensorHalExt::HidRawDeviceTest::test(argv[1]); |
| return 0; |
| } |