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