1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #define LOG_TAG "HidRawDeviceTest" 17 18 #include "HidRawDevice.h" 19 #include "HidRawSensor.h" 20 #include "HidSensorDef.h" 21 #include "SensorEventCallback.h" 22 #include "Utils.h" 23 #include "HidLog.h" 24 #include "StreamIoUtil.h" 25 26 namespace android { 27 namespace SensorHalExt { 28 29 /* 30 * Host test that verifies HidRawDevice and HidRawSensor works correctly. 31 */ 32 class HidRawDeviceTest { 33 public: 34 static void test(const char *devicePath) { 35 using namespace Hid::Sensor::SensorTypeUsage; 36 using HidUtil::hexdumpToStream; 37 38 std::unordered_set<unsigned int> interestedUsage{ 39 ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM}; 40 41 SP(HidRawDevice) device = 42 std::make_shared<HidRawDevice>(std::string(devicePath), interestedUsage); 43 const HidDevice::HidDeviceInfo &info = device->getDeviceInfo(); 44 45 LOG_V << "Sizeof descriptor: " << info.descriptor.size() << LOG_ENDL; 46 LOG_V << "Descriptor: " << LOG_ENDL; 47 hexdumpToStream(LOG_V, info.descriptor.begin(), info.descriptor.end()); 48 49 if (!device->isValid()) { 50 LOG_E << "invalid device" << LOG_ENDL; 51 return; 52 } 53 54 LOG_V << "Digest: " << LOG_ENDL; 55 LOG_V << device->mDigestVector; 56 57 std::vector<uint8_t> buffer; 58 // Dump first few feature ID to help debugging. 59 // If device does not implement all these features, it will show error messages. 60 for (int featureId = 0; featureId <= 5; ++featureId) { 61 if (!device->getFeature(featureId, &buffer)) { 62 LOG_E << "cannot get feature " << featureId << LOG_ENDL; 63 } else { 64 LOG_V << "Dump of feature " << featureId << LOG_ENDL; 65 hexdumpToStream(LOG_V, buffer.begin(), buffer.end()); 66 } 67 } 68 // 69 // use HidRawSensor to operate the device, pick first digest 70 // 71 auto &reportDigest = device->mDigestVector[0]; 72 SP(HidRawSensor) sensor = std::make_shared<HidRawSensor>( 73 device, reportDigest.fullUsage, reportDigest.packets); 74 75 if (!sensor->isValid()) { 76 LOG_E << "Sensor is not valid " << LOG_ENDL; 77 return; 78 } 79 80 const sensor_t *s = sensor->getSensor(); 81 LOG_V << "Sensor name: " << s->name << ", vendor: " << s->vendor << LOG_ENDL; 82 LOG_V << sensor->dump() << LOG_ENDL; 83 84 class Callback : public SensorEventCallback { 85 virtual int submitEvent(SP(BaseSensorObject) /*sensor*/, const sensors_event_t &e) { 86 LOG_V << "sensor: " << e.sensor << ", type: " << e.type << ", ts: " << e.timestamp 87 << ", values (" << e.data[0] << ", " << e.data[1] << ", " << e.data[2] << ")" 88 << LOG_ENDL; 89 return 1; 90 } 91 }; 92 Callback callback; 93 sensor->setEventCallback(&callback); 94 95 // Request sensor samples at to 10Hz (100ms) 96 sensor->batch(100LL*1000*1000 /*ns*/, 0); 97 sensor->enable(true); 98 99 // get a couple of events 100 for (size_t i = 0; i < 100; ++i) { 101 uint8_t id; 102 if (!device->receiveReport(&id, &buffer)) { 103 LOG_E << "Receive report error" << LOG_ENDL; 104 continue; 105 } 106 sensor->handleInput(id, buffer); 107 } 108 109 // clean up 110 sensor->enable(false); 111 112 LOG_V << "Done!" << LOG_ENDL; 113 } 114 }; 115 } //namespace SensorHalExt 116 } //namespace android 117 118 int main(int argc, char* argv[]) { 119 if (argc != 2) { 120 LOG_E << "Usage: " << argv[0] << " hidraw-dev-path" << LOG_ENDL; 121 return -1; 122 } 123 android::SensorHalExt::HidRawDeviceTest::test(argv[1]); 124 return 0; 125 } 126