• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
17 #define ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
18 
19 #include "BaseSensorObject.h"
20 #include "HidDevice.h"
21 #include "Utils.h"
22 
23 #include <HidParser.h>
24 #include <hardware/sensors.h>
25 
26 namespace android {
27 namespace SensorHalExt {
28 
29 using HidUtil::HidParser;
30 using ReportPacket = HidParser::ReportPacket;
31 using ReportItem = HidParser::ReportItem;
32 
33 class HidRawSensor : public BaseSensorObject {
34     friend class HidRawSensorTest;
35     friend class HidRawDeviceTest;
36 public:
37     HidRawSensor(SP(HidDevice) device, uint32_t usage,
38                  const std::vector<HidParser::ReportPacket> &report);
39 
40     // implements BaseSensorObject
41     virtual const sensor_t* getSensor() const;
42     virtual void getUuid(uint8_t* uuid) const;
43     virtual int enable(bool enable);
44     virtual int batch(int64_t samplePeriod, int64_t batchPeriod); // unit nano-seconds
45 
46     // handle input report received
47     void handleInput(uint8_t id, const std::vector<uint8_t> &message);
48 
49     // get head tracker sensor event data
50     bool getHeadTrackerEventData(const std::vector<uint8_t> &message,
51                                  sensors_event_t *event);
52 
53     // get generic sensor event data
54     bool getSensorEventData(const std::vector<uint8_t> &message,
55                             sensors_event_t *event);
56 
57     // indicate if the HidRawSensor is a valid one
isValid()58     bool isValid() const { return mValid; };
59 
60 private:
61 
62     // structure used for holding descriptor parse result for each report field
63     enum {
64         TYPE_FLOAT,
65         TYPE_INT64,
66         TYPE_ACCURACY
67     };
68     struct ReportTranslateRecord {
69         int type;
70         int index;
71         int64_t maxValue;
72         int64_t minValue;
73         size_t byteOffset;
74         size_t byteSize;
75         double a;
76         int64_t b;
77     };
78 
79     // sensor related information parsed from HID descriptor
80     struct FeatureValue {
81         // information needed to furnish sensor_t structure (see hardware/sensors.h)
82         std::string name;
83         std::string vendor;
84         std::string permission;
85         std::string typeString;
86         int32_t type;
87         int version;
88         float maxRange;
89         float resolution;
90         float power;
91         int32_t minDelay;
92         int64_t maxDelay;
93         size_t fifoSize;
94         size_t fifoMaxSize;
95         uint32_t reportModeFlag;
96         bool isWakeUp;
97         bool useUniqueIdForUuid;
98 
99         // dynamic sensor specific
100         std::string uniqueId;
101         uint8_t uuid[16];
102 
103         // if the device is custom sensor HID device that furnished android specific descriptors
104         bool isAndroidCustom;
105     };
106 
107     // helper function to find the first report item with specified usage, type and id.
108     // if parameter id is omitted, this function looks for usage with all ids.
109     // return nullptr if nothing is found.
110     static const HidParser::ReportItem* find
111             (const std::vector<HidParser::ReportPacket> &packets,
112             unsigned int usage, int type, int id = -1);
113 
114     // helper function to decode std::string from HID feature report buffer.
115     static bool decodeString(
116             const HidParser::ReportItem &report,
117             const std::vector<uint8_t> &buffer, std::string *d);
118 
119     // initialize default feature values default based on hid device info
120     static void initFeatureValueFromHidDeviceInfo(
121             FeatureValue *featureValue, const HidDevice::HidDeviceInfo &info);
122 
123     // populates feature values from descripitors and hid feature reports
124     bool populateFeatureValueFromFeatureReport(
125             FeatureValue *featureValue, const std::vector<HidParser::ReportPacket> &packets);
126 
127     // validate feature values and construct sensor_t structure if values are ok.
128     bool validateFeatureValueAndBuildSensor();
129 
130     // helper function to find sensor control feature usage from packets
131     bool findSensorControlUsage(const std::vector<HidParser::ReportPacket> &packets);
132 
133     // try to parse sensor description feature value to see if it matches any
134     // known sensors
135     void detectSensorFromDescription(const std::string &description);
136 
137     // try to parse sensor description feature value to see if it matches the
138     // Android header tracker sensor
139     bool detectAndroidHeadTrackerSensor(const std::string &description);
140 
141     // try to parse sensor description feature value to see if it matches
142     // android specified custom sensor definition.
143     bool detectAndroidCustomSensor(const std::string &description);
144 
145     // process HID sensor spec defined three axis sensors usages: accel, gyro, mag.
146     bool processTriAxisUsage(const std::vector<HidParser::ReportPacket> &packets,
147             uint32_t usageX, uint32_t usageY, uint32_t usageZ, double defaultScaling = 1);
148 
149     // process HID snesor spec defined orientation(quaternion) sensor usages.
150     bool processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets);
151 
152     // get the value of a report field
153     template<typename ValueType>
getReportFieldValue(const std::vector<uint8_t> & message,ReportTranslateRecord * rec,ValueType * value)154     bool getReportFieldValue(const std::vector<uint8_t> &message,
155                              ReportTranslateRecord* rec, ValueType* value) {
156         bool valid = true;
157         int64_t v = 0;
158         if (rec->minValue < 0) {
159             v = (message[rec->byteOffset + rec->byteSize - 1] & 0x80) ? -1 : 0;
160         }
161 
162         for (int i = static_cast<int>(rec->byteSize) - 1; i >= 0; --i) {
163             v = (v << 8) | message[rec->byteOffset + i]; // HID is little endian
164         }
165         if (v > rec->maxValue || v < rec->minValue) {
166             valid = false;
167         }
168 
169         switch (rec->type) {
170             case TYPE_FLOAT:
171                 *value = rec->a * (v + rec->b);
172                 break;
173             case TYPE_INT64:
174                 *value = v + rec->b;
175                 break;
176         }
177 
178         return valid;
179     }
180 
181     // dump data for test/debug purpose
182     std::string dump() const;
183 
184     // Features for control sensor
185     int mReportingStateId;
186     unsigned int mReportingStateBitOffset;
187     unsigned int mReportingStateBitSize;
188     int mReportingStateDisableIndex;
189     int mReportingStateEnableIndex;
190 
191     int mPowerStateId;
192     unsigned int mPowerStateBitOffset;
193     unsigned int mPowerStateBitSize;
194     int mPowerStateOffIndex;
195     int mPowerStateOnIndex;
196 
197     int mReportIntervalId;
198     unsigned int mReportIntervalBitOffset;
199     unsigned int mReportIntervalBitSize;
200     double mReportIntervalScale;
201     int64_t mReportIntervalOffset;
202 
203     // Input report translate table
204     std::vector<ReportTranslateRecord> mTranslateTable;
205     unsigned mInputReportId;
206 
207     FeatureValue mFeatureInfo;
208     sensor_t mSensor;
209 
210     // runtime states variable
211     bool mEnabled;
212     int64_t mSamplingPeriod;    // ns
213     int64_t mBatchingPeriod;    // ns
214 
215     WP(HidDevice) mDevice;
216     bool mValid;
217 };
218 
219 } // namespace SensorHalExt
220 } // namespace android
221 #endif // ANDROID_SENSORHAL_EXT_HIDRAW_SENSOR_H
222 
223