xref: /aosp_15_r20/frameworks/native/services/inputflinger/reader/mapper/SensorInputMapper.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2020 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 
17 #include <locale>
18 
19 #include <ftl/enum.h>
20 
21 #include "../Macros.h"
22 #include "SensorInputMapper.h"
23 
24 // Log detailed debug messages about each sensor event notification to the dispatcher.
25 constexpr bool DEBUG_SENSOR_EVENT_DETAILS = false;
26 
27 namespace android {
28 
29 // Mask for the LSB 2nd, 3rd and fourth bits.
30 constexpr int REPORTING_MODE_MASK = 0xE;
31 constexpr int REPORTING_MODE_SHIFT = 1;
32 constexpr float GRAVITY_MS2_UNIT = 9.80665f;
33 constexpr float DEGREE_RADIAN_UNIT = 0.0174533f;
34 
35 /* Convert the sensor data from Linux to Android
36  * Linux accelerometer unit is per g,  Android unit is m/s^2
37  * Linux gyroscope unit is degree/second, Android unit is radians/second
38  */
convertFromLinuxToAndroid(std::vector<float> & values,InputDeviceSensorType sensorType)39 static void convertFromLinuxToAndroid(std::vector<float>& values,
40                                       InputDeviceSensorType sensorType) {
41     for (size_t i = 0; i < values.size(); i++) {
42         switch (sensorType) {
43             case InputDeviceSensorType::ACCELEROMETER:
44                 values[i] *= GRAVITY_MS2_UNIT;
45                 break;
46             case InputDeviceSensorType::GYROSCOPE:
47                 values[i] *= DEGREE_RADIAN_UNIT;
48                 break;
49             default:
50                 break;
51         }
52     }
53 }
54 
SensorInputMapper(InputDeviceContext & deviceContext,const InputReaderConfiguration & readerConfig)55 SensorInputMapper::SensorInputMapper(InputDeviceContext& deviceContext,
56                                      const InputReaderConfiguration& readerConfig)
57       : InputMapper(deviceContext, readerConfig) {}
58 
~SensorInputMapper()59 SensorInputMapper::~SensorInputMapper() {}
60 
getSources() const61 uint32_t SensorInputMapper::getSources() const {
62     return AINPUT_SOURCE_SENSOR;
63 }
64 
parseSensorConfiguration(InputDeviceSensorType sensorType,int32_t absCode,int32_t sensorDataIndex,const Axis & axis)65 void SensorInputMapper::parseSensorConfiguration(InputDeviceSensorType sensorType, int32_t absCode,
66                                                  int32_t sensorDataIndex, const Axis& axis) {
67     auto it = mSensors.find(sensorType);
68     if (it == mSensors.end()) {
69         Sensor sensor = createSensor(sensorType, axis);
70         sensor.dataVec[sensorDataIndex] = absCode;
71         mSensors.emplace(sensorType, sensor);
72     } else {
73         it->second.dataVec[sensorDataIndex] = absCode;
74     }
75 }
76 
populateDeviceInfo(InputDeviceInfo & info)77 void SensorInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
78     InputMapper::populateDeviceInfo(info);
79 
80     for (const auto& [sensorType, sensor] : mSensors) {
81         info.addSensorInfo(sensor.sensorInfo);
82         info.setHasSensor(true);
83     }
84 }
85 
dump(std::string & dump)86 void SensorInputMapper::dump(std::string& dump) {
87     dump += INDENT2 "Sensor Input Mapper:\n";
88     dump += StringPrintf(INDENT3 " isDeviceEnabled %d\n", getDeviceContext().isDeviceEnabled());
89     dump += StringPrintf(INDENT3 " mHasHardwareTimestamp %d\n", mHasHardwareTimestamp);
90     dump += INDENT3 "Sensors:\n";
91     for (const auto& [sensorType, sensor] : mSensors) {
92         dump += StringPrintf(INDENT4 "%s\n", ftl::enum_string(sensorType).c_str());
93         dump += StringPrintf(INDENT5 "enabled: %d\n", sensor.enabled);
94         dump += StringPrintf(INDENT5 "samplingPeriod: %lld\n", sensor.samplingPeriod.count());
95         dump += StringPrintf(INDENT5 "maxBatchReportLatency: %lld\n",
96                              sensor.maxBatchReportLatency.count());
97         dump += StringPrintf(INDENT5 "maxRange: %f\n", sensor.sensorInfo.maxRange);
98         dump += StringPrintf(INDENT5 "power: %f\n", sensor.sensorInfo.power);
99         for (ssize_t i = 0; i < SENSOR_VEC_LEN; i++) {
100             int32_t rawAxis = sensor.dataVec[i];
101             dump += StringPrintf(INDENT5 "[%zd]: rawAxis: %d \n", i, rawAxis);
102             const auto it = mAxes.find(rawAxis);
103             if (it != mAxes.end()) {
104                 const Axis& axis = it->second;
105                 dump += StringPrintf(INDENT5 " min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f,"
106                                              "resolution=%0.5f\n",
107                                      axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
108                 dump += StringPrintf(INDENT5 "  scale=%0.5f, offset=%0.5f\n", axis.scale,
109                                      axis.offset);
110                 dump += StringPrintf(INDENT5 " rawMin=%d, rawMax=%d, "
111                                              "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
112                                      axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
113                                      axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz,
114                                      axis.rawAxisInfo.resolution);
115             }
116         }
117     }
118 }
119 
reconfigure(nsecs_t when,const InputReaderConfiguration & config,ConfigurationChanges changes)120 std::list<NotifyArgs> SensorInputMapper::reconfigure(nsecs_t when,
121                                                      const InputReaderConfiguration& config,
122                                                      ConfigurationChanges changes) {
123     std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
124 
125     if (!changes.any()) { // first time only
126         mDeviceEnabled = true;
127         // Check if device has MSC_TIMESTAMP event.
128         mHasHardwareTimestamp = getDeviceContext().hasMscEvent(MSC_TIMESTAMP);
129         // Collect all axes.
130         for (int32_t abs = ABS_X; abs <= ABS_MAX; abs++) {
131             // axis must be claimed by sensor class device
132             if (!(getAbsAxisUsage(abs, getDeviceContext().getDeviceClasses())
133                           .test(InputDeviceClass::SENSOR))) {
134                 continue;
135             }
136             if (std::optional<RawAbsoluteAxisInfo> rawAxisInfo = getAbsoluteAxisInfo(abs);
137                 rawAxisInfo) {
138                 AxisInfo axisInfo;
139                 // Axis doesn't need to be mapped, as sensor mapper doesn't generate any motion
140                 // input events
141                 axisInfo.mode = AxisInfo::MODE_NORMAL;
142                 axisInfo.axis = -1;
143                 // Check key layout map for sensor data mapping to axes
144                 auto ret = getDeviceContext().mapSensor(abs);
145                 if (ret.ok()) {
146                     InputDeviceSensorType sensorType = (*ret).first;
147                     int32_t sensorDataIndex = (*ret).second;
148                     const Axis& axis = createAxis(axisInfo, rawAxisInfo.value());
149                     parseSensorConfiguration(sensorType, abs, sensorDataIndex, axis);
150 
151                     mAxes.insert({abs, axis});
152                 }
153             }
154         }
155     }
156     return out;
157 }
158 
createAxis(const AxisInfo & axisInfo,const RawAbsoluteAxisInfo & rawAxisInfo)159 SensorInputMapper::Axis SensorInputMapper::createAxis(const AxisInfo& axisInfo,
160                                                       const RawAbsoluteAxisInfo& rawAxisInfo) {
161     // Apply flat override.
162     int32_t rawFlat = axisInfo.flatOverride < 0 ? rawAxisInfo.flat : axisInfo.flatOverride;
163 
164     float scale = std::numeric_limits<float>::signaling_NaN();
165     float offset = 0;
166 
167     // resolution is 1 of sensor's unit.  For accelerometer, it is G, for gyroscope,
168     // it is degree/s.
169     scale = 1.0f / rawAxisInfo.resolution;
170     offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
171 
172     const float max = rawAxisInfo.maxValue / rawAxisInfo.resolution;
173     const float min = rawAxisInfo.minValue / rawAxisInfo.resolution;
174     const float flat = rawFlat * scale;
175     const float fuzz = rawAxisInfo.fuzz * scale;
176     const float resolution = rawAxisInfo.resolution;
177 
178     // To eliminate noise while the Sensor is at rest, filter out small variations
179     // in axis values up front.
180     const float filter = fuzz ? fuzz : flat * 0.25f;
181     return Axis(rawAxisInfo, axisInfo, scale, offset, min, max, flat, fuzz, resolution, filter);
182 }
183 
reset(nsecs_t when)184 std::list<NotifyArgs> SensorInputMapper::reset(nsecs_t when) {
185     // Recenter all axes.
186     for (std::pair<const int32_t, Axis>& pair : mAxes) {
187         Axis& axis = pair.second;
188         axis.resetValue();
189     }
190     mHardwareTimestamp = 0;
191     mPrevMscTime = 0;
192     return InputMapper::reset(when);
193 }
194 
createSensor(InputDeviceSensorType sensorType,const Axis & axis)195 SensorInputMapper::Sensor SensorInputMapper::createSensor(InputDeviceSensorType sensorType,
196                                                           const Axis& axis) {
197     InputDeviceIdentifier identifier = getDeviceContext().getDeviceIdentifier();
198     const auto& config = getDeviceContext().getConfiguration();
199 
200     std::string prefix = "sensor." + ftl::enum_string(sensorType);
201     transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
202 
203     int32_t flags = 0;
204     std::optional<int32_t> reportingMode = config.getInt(prefix + ".reportingMode");
205     if (reportingMode.has_value()) {
206         flags |= (*reportingMode & REPORTING_MODE_MASK) << REPORTING_MODE_SHIFT;
207     }
208 
209     // Sensor Id will be assigned to device Id to distinguish same sensor from multiple input
210     // devices, in such a way that the sensor Id will be same as input device Id.
211     // The sensorType is to distinguish different sensors within one device.
212     // One input device can only have 1 sensor for each sensor Type.
213     InputDeviceSensorInfo sensorInfo(identifier.name, std::to_string(identifier.vendor),
214                                      identifier.version, sensorType,
215                                      InputDeviceSensorAccuracy::HIGH,
216                                      /*maxRange=*/axis.max, /*resolution=*/axis.scale,
217                                      /*power=*/config.getFloat(prefix + ".power").value_or(0.0f),
218                                      /*minDelay=*/config.getInt(prefix + ".minDelay").value_or(0),
219                                      /*fifoReservedEventCount=*/
220                                      config.getInt(prefix + ".fifoReservedEventCount").value_or(0),
221                                      /*fifoMaxEventCount=*/
222                                      config.getInt(prefix + ".fifoMaxEventCount").value_or(0),
223                                      ftl::enum_string(sensorType),
224                                      /*maxDelay=*/config.getInt(prefix + ".maxDelay").value_or(0),
225                                      /*flags=*/flags, getDeviceId());
226 
227     return Sensor(sensorInfo);
228 }
229 
processHardWareTimestamp(nsecs_t evTime,int32_t mscTime)230 void SensorInputMapper::processHardWareTimestamp(nsecs_t evTime, int32_t mscTime) {
231     // Since MSC_TIMESTAMP initial state is different from the system time, we
232     // calculate the difference between two MSC_TIMESTAMP events, and use that
233     // to calculate the system time that should be tagged on the event.
234     // if the first time MSC_TIMESTAMP, store it
235     // else calculate difference between previous and current MSC_TIMESTAMP
236     if (mPrevMscTime == 0) {
237         mHardwareTimestamp = evTime;
238         if (DEBUG_SENSOR_EVENT_DETAILS) {
239             ALOGD("Initialize hardware timestamp = %" PRId64, mHardwareTimestamp);
240         }
241     } else {
242         // Calculate the difference between current msc_timestamp and
243         // previous msc_timestamp, including when msc_timestamp wraps around.
244         uint32_t timeDiff = (mPrevMscTime > static_cast<uint32_t>(mscTime))
245                 ? (UINT32_MAX - mPrevMscTime + static_cast<uint32_t>(mscTime + 1))
246                 : (static_cast<uint32_t>(mscTime) - mPrevMscTime);
247 
248         mHardwareTimestamp += timeDiff * 1000LL;
249     }
250     mPrevMscTime = static_cast<uint32_t>(mscTime);
251 }
252 
process(const RawEvent & rawEvent)253 std::list<NotifyArgs> SensorInputMapper::process(const RawEvent& rawEvent) {
254     std::list<NotifyArgs> out;
255     switch (rawEvent.type) {
256         case EV_ABS: {
257             auto it = mAxes.find(rawEvent.code);
258             if (it != mAxes.end()) {
259                 Axis& axis = it->second;
260                 axis.newValue = rawEvent.value * axis.scale + axis.offset;
261             }
262             break;
263         }
264 
265         case EV_SYN:
266             switch (rawEvent.code) {
267                 case SYN_REPORT:
268                     for (std::pair<const int32_t, Axis>& pair : mAxes) {
269                         Axis& axis = pair.second;
270                         axis.currentValue = axis.newValue;
271                     }
272                     out += sync(rawEvent.when, /*force=*/false);
273                     break;
274             }
275             break;
276 
277         case EV_MSC:
278             switch (rawEvent.code) {
279                 case MSC_TIMESTAMP:
280                     // hardware timestamp is nano seconds
281                     processHardWareTimestamp(rawEvent.when, rawEvent.value);
282                     break;
283             }
284     }
285     return out;
286 }
287 
setSensorEnabled(InputDeviceSensorType sensorType,bool enabled)288 bool SensorInputMapper::setSensorEnabled(InputDeviceSensorType sensorType, bool enabled) {
289     auto it = mSensors.find(sensorType);
290     if (it == mSensors.end()) {
291         return false;
292     }
293 
294     it->second.enabled = enabled;
295     if (!enabled) {
296         it->second.resetValue();
297     }
298 
299     /* Currently we can't enable/disable sensors individually. Enabling any sensor will enable
300      * the device
301      */
302     mDeviceEnabled = false;
303     for (const auto& [_, sensor] : mSensors) {
304         // If any sensor is on we will turn on the device.
305         if (sensor.enabled) {
306             mDeviceEnabled = true;
307             break;
308         }
309     }
310     return true;
311 }
312 
flushSensor(InputDeviceSensorType sensorType)313 void SensorInputMapper::flushSensor(InputDeviceSensorType sensorType) {
314     auto it = mSensors.find(sensorType);
315     if (it == mSensors.end()) {
316         return;
317     }
318     auto& sensor = it->second;
319     sensor.lastSampleTimeNs = 0;
320     for (size_t i = 0; i < SENSOR_VEC_LEN; i++) {
321         int32_t abs = sensor.dataVec[i];
322         auto itAxis = mAxes.find(abs);
323         if (itAxis != mAxes.end()) {
324             Axis& axis = itAxis->second;
325             axis.resetValue();
326         }
327     }
328 }
329 
enableSensor(InputDeviceSensorType sensorType,std::chrono::microseconds samplingPeriod,std::chrono::microseconds maxBatchReportLatency)330 bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType,
331                                      std::chrono::microseconds samplingPeriod,
332                                      std::chrono::microseconds maxBatchReportLatency) {
333     if (DEBUG_SENSOR_EVENT_DETAILS) {
334         ALOGD("Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld",
335               ftl::enum_string(sensorType).c_str(), samplingPeriod.count(),
336               maxBatchReportLatency.count());
337     }
338 
339     if (!setSensorEnabled(sensorType, /*enabled=*/true)) {
340         return false;
341     }
342 
343     // Enable device
344     if (mDeviceEnabled) {
345         getDeviceContext().enableDevice();
346     }
347 
348     // We know the sensor exists now, update the sampling period and batch report latency.
349     auto it = mSensors.find(sensorType);
350     it->second.samplingPeriod =
351             std::chrono::duration_cast<std::chrono::nanoseconds>(samplingPeriod);
352     it->second.maxBatchReportLatency =
353             std::chrono::duration_cast<std::chrono::nanoseconds>(maxBatchReportLatency);
354     return true;
355 }
356 
disableSensor(InputDeviceSensorType sensorType)357 void SensorInputMapper::disableSensor(InputDeviceSensorType sensorType) {
358     if (DEBUG_SENSOR_EVENT_DETAILS) {
359         ALOGD("Disable Sensor %s", ftl::enum_string(sensorType).c_str());
360     }
361 
362     if (!setSensorEnabled(sensorType, /*enabled=*/false)) {
363         return;
364     }
365 
366     // Disable device
367     if (!mDeviceEnabled) {
368         mHardwareTimestamp = 0;
369         mPrevMscTime = 0;
370         getDeviceContext().disableDevice();
371     }
372 }
373 
sync(nsecs_t when,bool force)374 std::list<NotifyArgs> SensorInputMapper::sync(nsecs_t when, bool force) {
375     std::list<NotifyArgs> out;
376     for (auto& [sensorType, sensor] : mSensors) {
377         // Skip if sensor not enabled
378         if (!sensor.enabled) {
379             continue;
380         }
381         std::vector<float> values;
382         for (ssize_t i = 0; i < SENSOR_VEC_LEN; i++) {
383             int32_t abs = sensor.dataVec[i];
384             auto it = mAxes.find(abs);
385             if (it != mAxes.end()) {
386                 const Axis& axis = it->second;
387                 values.push_back(axis.currentValue);
388             }
389         }
390 
391         nsecs_t timestamp = mHasHardwareTimestamp ? mHardwareTimestamp : when;
392         if (DEBUG_SENSOR_EVENT_DETAILS) {
393             ALOGD("Sensor %s timestamp %" PRIu64 " values [%f %f %f]",
394                   ftl::enum_string(sensorType).c_str(), timestamp, values[0], values[1], values[2]);
395         }
396         if (sensor.lastSampleTimeNs.has_value() &&
397             timestamp - sensor.lastSampleTimeNs.value() < sensor.samplingPeriod.count()) {
398             if (DEBUG_SENSOR_EVENT_DETAILS) {
399                 ALOGD("Sensor %s Skip a sample.", ftl::enum_string(sensorType).c_str());
400             }
401         } else {
402             // Convert to Android unit
403             convertFromLinuxToAndroid(values, sensorType);
404             // Notify dispatcher for sensor event
405             out.push_back(NotifySensorArgs(getContext()->getNextId(), when, getDeviceId(),
406                                            AINPUT_SOURCE_SENSOR, sensorType,
407                                            sensor.sensorInfo.accuracy,
408                                            /*accuracyChanged=*/sensor.accuracy !=
409                                                    sensor.sensorInfo.accuracy,
410                                            /*hwTimestamp=*/timestamp, values));
411             sensor.lastSampleTimeNs = timestamp;
412             sensor.accuracy = sensor.sensorInfo.accuracy;
413         }
414     }
415     return out;
416 }
417 
418 } // namespace android
419