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{new HidRawDevice(std::string(devicePath), interestedUsage)};
42         const HidDevice::HidDeviceInfo &info = device->getDeviceInfo();
43 
44         LOG_V << "Sizeof descriptor: " << info.descriptor.size() << LOG_ENDL;
45         LOG_V << "Descriptor: " << LOG_ENDL;
46         hexdumpToStream(LOG_V, info.descriptor.begin(), info.descriptor.end());
47 
48         if (!device->isValid()) {
49             LOG_E << "invalid device" << LOG_ENDL;
50             return;
51         }
52 
53         LOG_V << "Digest: " << LOG_ENDL;
54         LOG_V << device->mDigestVector;
55 
56         std::vector<uint8_t> buffer;
57         // Dump first few feature ID to help debugging.
58         // If device does not implement all these features, it will show error messages.
59         for (int featureId = 0; featureId <= 5; ++featureId) {
60             if (!device->getFeature(featureId, &buffer)) {
61                 LOG_E << "cannot get feature " << featureId << LOG_ENDL;
62             } else {
63                 LOG_V << "Dump of feature " << featureId << LOG_ENDL;
64                 hexdumpToStream(LOG_V, buffer.begin(), buffer.end());
65             }
66         }
67         //
68         // use HidRawSensor to operate the device, pick first digest
69         //
70         auto &reportDigest = device->mDigestVector[0];
71         SP(HidRawSensor) sensor{
72             new HidRawSensor(device, reportDigest.fullUsage, reportDigest.packets)};
73 
74         if (!sensor->isValid()) {
75             LOG_E << "Sensor is not valid " << LOG_ENDL;
76             return;
77         }
78 
79         const sensor_t *s = sensor->getSensor();
80         LOG_V << "Sensor name: " << s->name << ", vendor: " << s->vendor << LOG_ENDL;
81         LOG_V << sensor->dump() << LOG_ENDL;
82 
83         class Callback : public SensorEventCallback {
84             virtual int submitEvent(SP(BaseSensorObject) /*sensor*/, const sensors_event_t &e) {
85                 LOG_V << "sensor: " << e.sensor << ", type: " << e.type << ", ts: " << e.timestamp
86                       << ", values (" << e.data[0] << ", " << e.data[1] << ", " << e.data[2] << ")"
87                       << LOG_ENDL;
88                 return 1;
89             }
90         };
91         Callback callback;
92         sensor->setEventCallback(&callback);
93 
94         // Request sensor samples at to 10Hz (100ms)
95         sensor->batch(100LL*1000*1000 /*ns*/, 0);
96         sensor->enable(true);
97 
98         // get a couple of events
99         for (size_t i = 0; i < 100; ++i) {
100             uint8_t id;
101             if (!device->receiveReport(&id, &buffer)) {
102                 LOG_E << "Receive report error" << LOG_ENDL;
103                 continue;
104             }
105             sensor->handleInput(id, buffer);
106         }
107 
108         // clean up
109         sensor->enable(false);
110 
111         LOG_V << "Done!" << LOG_ENDL;
112     }
113 };
114 } //namespace SensorHalExt
115 } //namespace android
116 
main(int argc,char * argv[])117 int main(int argc, char* argv[]) {
118     if (argc != 2) {
119         LOG_E << "Usage: " << argv[0] << " hidraw-dev-path" << LOG_ENDL;
120         return -1;
121     }
122     android::SensorHalExt::HidRawDeviceTest::test(argv[1]);
123     return 0;
124 }
125