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:
test(const char * devicePath)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
main(int argc,char * argv[])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