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 "HidRawSensorTest"
17
18 #include "HidDevice.h"
19 #include "HidLog.h"
20 #include "HidLog.h"
21 #include "HidParser.h"
22 #include "HidRawSensor.h"
23 #include "HidSensorDef.h"
24 #include "StreamIoUtil.h"
25 #include "TestHidDescriptor.h"
26 #include "Utils.h"
27
28 #include <deque>
29 #include <unordered_map>
30
31 namespace android {
32 namespace SensorHalExt {
33
34 class HidRawDummyDevice : public HidDevice {
35 public:
36 struct DataPair {
37 uint8_t id;
38 std::vector<uint8_t> data;
39 };
40
HidRawDummyDevice()41 HidRawDummyDevice() {
42 // dummy values
43 mInfo = {
44 .name = "Test sensor name",
45 .physicalPath = "/physical/path",
46 .busType = "USB",
47 .vendorId = 0x1234,
48 .productId = 0x5678,
49 .descriptor = {0}
50 };
51 }
52
getDeviceInfo()53 virtual const HidDeviceInfo& getDeviceInfo() {
54 return mInfo;
55 }
56
57 // get feature from device
getFeature(uint8_t id,std::vector<uint8_t> * out)58 virtual bool getFeature(uint8_t id, std::vector<uint8_t> *out) {
59 auto i = mFeature.find(id);
60 if (i == mFeature.end()) {
61 return false;
62 }
63 *out = i->second;
64 return true;
65 }
66
67 // write feature to device
setFeature(uint8_t id,const std::vector<uint8_t> & in)68 virtual bool setFeature(uint8_t id, const std::vector<uint8_t> &in) {
69 auto i = mFeature.find(id);
70 if (i == mFeature.end() || in.size() != i->second.size()) {
71 return false;
72 }
73 i->second = in;
74 return true;
75 }
76
77 // send report to default output endpoint
sendReport(uint8_t id,std::vector<uint8_t> & data)78 virtual bool sendReport(uint8_t id, std::vector<uint8_t> &data) {
79 DataPair pair = {
80 .id = id,
81 .data = data
82 };
83 mOutput.push_back(pair);
84 return true;
85 }
86
87 // receive from default input endpoint
receiveReport(uint8_t *,std::vector<uint8_t> *)88 virtual bool receiveReport(uint8_t * /*id*/, std::vector<uint8_t> * /*data*/) {
89 // not necessary, as input report can be directly feed to HidRawSensor for testing purpose
90 return false;
91 }
92
dequeuOutputReport(DataPair * pair)93 bool dequeuOutputReport(DataPair *pair) {
94 if (!mOutput.empty()) {
95 return false;
96 }
97 *pair = mOutput.front();
98 mOutput.pop_front();
99 return true;
100 }
101
102 private:
103 HidDeviceInfo mInfo;
104 std::deque<DataPair> mOutput;
105 std::unordered_map<uint8_t, std::vector<uint8_t>> mFeature;
106 };
107
108 class HidRawSensorTest {
109 public:
test()110 static bool test() {
111 bool ret = true;
112 using namespace Hid::Sensor::SensorTypeUsage;
113 std::unordered_set<unsigned int> interestedUsage{
114 ACCELEROMETER_3D, GYROMETER_3D, COMPASS_3D, CUSTOM};
115 SP(HidDevice) device(new HidRawDummyDevice());
116
117 HidParser hidParser;
118 for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
119 if (p->data == nullptr || p->len == 0) {
120 break;
121 }
122 const char *name = p->name != nullptr ? p->name : "unnamed";
123 if (!hidParser.parse(p->data, p->len)) {
124 LOG_E << name << " parsing error!" << LOG_ENDL;
125 ret = false;
126 continue;
127 }
128
129 hidParser.filterTree();
130 LOG_V << name << " digest: " << LOG_ENDL;
131 auto digestVector = hidParser.generateDigest(interestedUsage);
132 LOG_V << digestVector;
133
134 if (digestVector.empty()) {
135 LOG_V << name << " does not contain interested usage" << LOG_ENDL;
136 continue;
137 }
138
139 LOG_V << name << " sensor: " << LOG_ENDL;
140 for (const auto &digest : digestVector) {
141 LOG_I << "Sensor usage " << std::hex << digest.fullUsage << std::dec << LOG_ENDL;
142 auto *s = new HidRawSensor(device, digest.fullUsage, digest.packets);
143 if (s->mValid) {
144 LOG_V << "Usage " << std::hex << digest.fullUsage << std::dec << LOG_ENDL;
145 LOG_V << s->dump();
146 } else {
147 LOG_V << "Sensor of usage " << std::hex << digest.fullUsage << std::dec
148 << " not valid!" << LOG_ENDL;
149 }
150 }
151 LOG_V << LOG_ENDL;
152 }
153 return ret;
154 }
155 };
156
157 }// namespace SensorHalExt
158 }// namespace android
159
main()160 int main() {
161 return android::SensorHalExt::HidRawSensorTest::test() ? 0 : 1;
162 }
163