Merge "Audio HAL: Add latency mode APIs"
diff --git a/include/hardware/sensors-base.h b/include/hardware/sensors-base.h
index 7dc42a0..dbf99f5 100644
--- a/include/hardware/sensors-base.h
+++ b/include/hardware/sensors-base.h
@@ -57,6 +57,7 @@
SENSOR_TYPE_GYROSCOPE_LIMITED_AXES = 39,
SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 40,
SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 41,
+ SENSOR_TYPE_HEADING = 42,
SENSOR_TYPE_DEVICE_PRIVATE_BASE = 65536 /* 0x10000 */,
};
diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h
index 589aba0..6f4baf8 100644
--- a/include/hardware/sensors.h
+++ b/include/hardware/sensors.h
@@ -191,6 +191,7 @@
#define SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES "android.sensor.gyroscope_limited_axes"
#define SENSOR_STRING_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED "android.sensor.accelerometer_limited_axes_uncalibrated"
#define SENSOR_STRING_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED "android.sensor.gyroscope_limited_axes_uncalibrated"
+#define SENSOR_STRING_TYPE_HEADING "android.sensor.heading"
/**
* Values returned by the accelerometer in various locations in the universe.
@@ -359,6 +360,14 @@
} limited_axes_imu_uncalibrated_event_t;
/**
+ * Heading event data
+ */
+typedef struct {
+ float heading;
+ float accuracy;
+} heading_event_t;
+
+/**
* Union of the various types of sensor data
* that can be returned.
*/
@@ -452,6 +461,9 @@
* SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED for details.
*/
limited_axes_imu_uncalibrated_event_t limited_axes_imu_uncalibrated;
+
+ /* heading data containing value in degrees and its accuracy */
+ heading_event_t heading;
};
union {
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
index 6654228..4520dda 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
@@ -635,8 +635,8 @@
return false;
}
- mFeatureInfo.type = SENSOR_TYPE_DEVICE_PRIVATE_BASE;
- mFeatureInfo.typeString = CUSTOM_TYPE_PREFIX + "headtracker";
+ mFeatureInfo.type = SENSOR_TYPE_HEAD_TRACKER;
+ mFeatureInfo.typeString = SENSOR_STRING_TYPE_HEAD_TRACKER;
mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
mFeatureInfo.permission = "";
mFeatureInfo.isWakeUp = false;
@@ -1011,6 +1011,50 @@
.type = mSensor.type
};
bool valid = true;
+
+ switch (mFeatureInfo.type) {
+ case SENSOR_TYPE_HEAD_TRACKER:
+ valid = getHeadTrackerEventData(message, &event);
+ break;
+ default:
+ valid = getSensorEventData(message, &event);
+ break;
+ }
+ if (!valid) {
+ LOG_E << "Invalid data observed in decoding, discard" << LOG_ENDL;
+ return;
+ }
+ event.timestamp = -1;
+ generateEvent(event);
+}
+
+bool HidRawSensor::getHeadTrackerEventData(const std::vector<uint8_t> &message,
+ sensors_event_t *event) {
+ head_tracker_event_t *head_tracker;
+
+ head_tracker = &(event->head_tracker);
+ if (!getReportFieldValue(message, &(mTranslateTable[0]),
+ &(head_tracker->rx))
+ || !getReportFieldValue(message, &(mTranslateTable[1]),
+ &(head_tracker->ry))
+ || !getReportFieldValue(message, &(mTranslateTable[2]),
+ &(head_tracker->rz))
+ || !getReportFieldValue(message, &(mTranslateTable[3]),
+ &(head_tracker->vx))
+ || !getReportFieldValue(message, &(mTranslateTable[4]),
+ &(head_tracker->vy))
+ || !getReportFieldValue(message, &(mTranslateTable[5]),
+ &(head_tracker->vz))
+ || !getReportFieldValue(message, &(mTranslateTable[6]),
+ &(head_tracker->discontinuity_count))) {
+ return false;
+ }
+
+ return true;
+}
+
+bool HidRawSensor::getSensorEventData(const std::vector<uint8_t> &message,
+ sensors_event_t *event) {
for (const auto &rec : mTranslateTable) {
int64_t v = (message[rec.byteOffset + rec.byteSize - 1] & 0x80) ? -1 : 0;
for (int i = static_cast<int>(rec.byteSize) - 1; i >= 0; --i) {
@@ -1020,26 +1064,23 @@
switch (rec.type) {
case TYPE_FLOAT:
if (v > rec.maxValue || v < rec.minValue) {
- valid = false;
+ return false;
}
- event.data[rec.index] = rec.a * (v + rec.b);
+ event->data[rec.index] = rec.a * (v + rec.b);
break;
case TYPE_INT64:
if (v > rec.maxValue || v < rec.minValue) {
- valid = false;
+ return false;
}
- event.u64.data[rec.index] = v + rec.b;
+ event->u64.data[rec.index] = v + rec.b;
break;
case TYPE_ACCURACY:
- event.magnetic.status = (v & 0xFF) + rec.b;
+ event->magnetic.status = (v & 0xFF) + rec.b;
break;
}
}
- if (!valid) {
- LOG_V << "Range error observed in decoding, discard" << LOG_ENDL;
- }
- event.timestamp = -1;
- generateEvent(event);
+
+ return true;
}
std::string HidRawSensor::dump() const {
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h
index f6d13b5..66843fc 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.h
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.h
@@ -46,6 +46,14 @@
// handle input report received
void handleInput(uint8_t id, const std::vector<uint8_t> &message);
+ // get head tracker sensor event data
+ bool getHeadTrackerEventData(const std::vector<uint8_t> &message,
+ sensors_event_t *event);
+
+ // get generic sensor event data
+ bool getSensorEventData(const std::vector<uint8_t> &message,
+ sensors_event_t *event);
+
// indicate if the HidRawSensor is a valid one
bool isValid() const { return mValid; };
@@ -141,6 +149,33 @@
// process HID snesor spec defined orientation(quaternion) sensor usages.
bool processQuaternionUsage(const std::vector<HidParser::ReportPacket> &packets);
+ // get the value of a report field
+ template<typename ValueType>
+ bool getReportFieldValue(const std::vector<uint8_t> &message,
+ ReportTranslateRecord* rec, ValueType* value) {
+ bool valid = true;
+ int64_t v;
+
+ v = (message[rec->byteOffset + rec->byteSize - 1] & 0x80) ? -1 : 0;
+ for (int i = static_cast<int>(rec->byteSize) - 1; i >= 0; --i) {
+ v = (v << 8) | message[rec->byteOffset + i]; // HID is little endian
+ }
+ if (v > rec->maxValue || v < rec->minValue) {
+ valid = false;
+ }
+
+ switch (rec->type) {
+ case TYPE_FLOAT:
+ *value = rec->a * (v + rec->b);
+ break;
+ case TYPE_INT64:
+ *value = v + rec->b;
+ break;
+ }
+
+ return valid;
+ }
+
// dump data for test/debug purpose
std::string dump() const;