Merge "Add support for LE audio capability detection" into main
diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp
index b86b1db..b6e0020 100644
--- a/modules/sensors/dynamic_sensor/Android.bp
+++ b/modules/sensors/dynamic_sensor/Android.bp
@@ -35,9 +35,17 @@
export_include_dirs: ["."],
shared_libs: [
+ "libbase",
"libhidparser",
+ "server_configurable_flags",
],
+ static_libs: [
+ "dynamic_sensors_flags_c_lib",
+ ],
+
+ cpp_std: "c++20",
+
target: {
android: {
srcs: [
@@ -53,12 +61,12 @@
"RingBuffer.cpp",
],
shared_libs: [
- "libbase",
"libcutils",
"liblog",
"libutils",
],
header_libs: [
+ "libbase_headers",
"libhardware_headers",
"libstagefright_foundation_headers",
],
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp
index d5a9b3c..101b983 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp
+++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp
@@ -118,7 +118,7 @@
sensors[0].sensorHandle = sensor_info.handle;
sensors[0].name = sensor_info.name;
sensors[0].vendor = sensor_info.vendor;
- sensors[0].version = 1;
+ sensors[0].version = sensor_info.version;
sensors[0].type = static_cast<SensorType>(sensor_info.type);
sensors[0].typeAsString = sensor_info.stringType;
sensors[0].maxRange = sensor_info.maxRange;
@@ -210,7 +210,7 @@
sensor_list[0].sensorHandle = handle;
sensor_list[0].name = sensor_info->name;
sensor_list[0].vendor = sensor_info->vendor;
- sensor_list[0].version = 1;
+ sensor_list[0].version = sensor_info->version;
sensor_list[0].type = static_cast<SensorType>(sensor_info->type);
sensor_list[0].typeAsString = sensor_info->stringType;
sensor_list[0].maxRange = sensor_info->maxRange;
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
index c90f4f1..57df74d 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
@@ -16,7 +16,9 @@
#include "HidRawSensor.h"
#include "HidSensorDef.h"
+#include <android-base/properties.h>
#include <utils/Errors.h>
+#include <com_android_libhardware_dynamic_sensors_flags.h>
#include "HidLog.h"
#include <HidUtils.h>
@@ -30,15 +32,20 @@
namespace android {
namespace SensorHalExt {
+using ::android::base::GetProperty;
+
+namespace dynamic_sensors_flags = com::android::libhardware::dynamic::sensors::flags;
+
namespace {
const std::string CUSTOM_TYPE_PREFIX("com.google.hardware.sensor.hid_dynamic.");
+
}
HidRawSensor::HidRawSensor(
SP(HidDevice) device, uint32_t usage, const std::vector<HidParser::ReportPacket> &packets)
- : mReportingStateId(-1), mPowerStateId(-1), mReportIntervalId(-1), mInputReportId(-1),
- mEnabled(false), mSamplingPeriod(1000LL*1000*1000), mBatchingPeriod(0),
- mDevice(device), mValid(false) {
+ : mReportingStateId(-1), mPowerStateId(-1), mReportIntervalId(-1), mLeTransportId(-1),
+ mRequiresLeTransport(false), mInputReportId(-1), mEnabled(false),
+ mSamplingPeriod(1000LL*1000*1000), mBatchingPeriod(0), mDevice(device), mValid(false) {
if (device == nullptr) {
return;
}
@@ -631,10 +638,35 @@
bool HidRawSensor::detectAndroidHeadTrackerSensor(
const std::string &description) {
- if (description.find("#AndroidHeadTracker#1.") != 0) {
+ bool leAudioFlagEnabled = dynamic_sensors_flags::dynamic_sensors_le_audio();
+ LOG_I << "detectAndroidHeadTrackerSensor: " << description << LOG_ENDL;
+ if (!description.starts_with("#AndroidHeadTracker#1.")
+ && (!leAudioFlagEnabled || !description.starts_with("#AndroidHeadTracker#2."))) {
return false;
}
+ // #AndroidHeadTracker#<major version>.<minor version>#<capability>
+ // We encode the major, minor, and capabilities in the following format:
+ // 0xMMmmcccc (Major, minor, capability bits)
+ if (leAudioFlagEnabled) {
+ uint32_t majorVersion = 0, minorVersion = 0, capability = 0;
+ mFeatureInfo.version = 0;
+ int ret = sscanf(description.c_str(), "#AndroidHeadTracker#%d.%d#%d",
+ &majorVersion, &minorVersion, &capability);
+ if (ret > 0) {
+ mRequiresLeTransport = (majorVersion == kLeAudioCapabilitiesMajorVersion);
+ mFeatureInfo.version = (majorVersion & 0xFF) << 24;
+ }
+ if (ret > 1) {
+ mFeatureInfo.version |= (minorVersion & 0xFF) << 16;
+ }
+ if (ret > 2) {
+ mFeatureInfo.version |= (capability & 0xFFFF);
+ }
+ } else {
+ mFeatureInfo.version = 1;
+ }
+
mFeatureInfo.type = SENSOR_TYPE_HEAD_TRACKER;
mFeatureInfo.typeString = SENSOR_STRING_TYPE_HEAD_TRACKER;
mFeatureInfo.reportModeFlag = SENSOR_FLAG_CONTINUOUS_MODE;
@@ -904,8 +936,23 @@
mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000000),
mFeatureInfo.maxDelay);
}
- return true;
- return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0;
+
+ bool leTransportExpected = mRequiresLeTransport;
+ if (leTransportExpected) {
+ //VENDOR_LE_TRANSPORT
+ const HidParser::ReportItem *leTransport
+ = find(packets, VENDOR_LE_TRANSPORT, HidParser::REPORT_TYPE_FEATURE);
+ if (leTransport == nullptr) {
+ LOG_W << "Cannot find valid LE transport feature" << LOG_ENDL;
+ } else {
+ mLeTransportId = leTransport->id;
+ mLeTransportBitOffset = leTransport->bitOffset;
+ mLeTransportBitSize = leTransport->bitSize;
+ }
+ }
+
+ return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0 &&
+ (!leTransportExpected || mLeTransportId >= 0);
}
const sensor_t* HidRawSensor::getSensor() const {
@@ -928,6 +975,51 @@
}
std::vector<uint8_t> buffer;
+ // TODO(b/298450041): Refactor the operations below in a separate function.
+ bool setLeAudioTransportOk = true;
+ if (mLeTransportId >= 0) {
+ setLeAudioTransportOk = false;
+ uint8_t id = static_cast<uint8_t>(mLeTransportId);
+ if (device->getFeature(id, &buffer)
+ && (8 * buffer.size()) >=
+ (mLeTransportBitOffset + mLeTransportBitSize)) {
+ constexpr uint8_t kLeAclValue = 0;
+ constexpr uint8_t kLeIsoValue = 1;
+
+ // The following property, if defined, represents a comma-separated list of
+ // transport preferences for the following types: le-acl or iso-[sw|hw],
+ // which describes the priority list of transport selections used based on the
+ // capabilities reported by the HID device.
+ std::string prop = GetProperty("bluetooth.core.le.dsa_transport_preference", "");
+ std::istringstream tokenStream(prop);
+ std::string line;
+ std::vector<std::string> priorityList;
+ while (std::getline(tokenStream, line, ',')) {
+ priorityList.push_back(line);
+ }
+
+ uint16_t capability = mFeatureInfo.version & 0x0000FFFF;
+ uint8_t value;
+ if (capability == (kIsoBitMask | kAclBitMask)) {
+ if (!priorityList.empty() && priorityList[0].compare("le-acl") == 0) {
+ value = kLeAclValue;
+ } else {
+ value = kLeIsoValue;
+ }
+ } else {
+ value = (capability & kIsoBitMask) ? kLeIsoValue : kLeAclValue;
+ }
+ HidUtil::copyBits(&value, &(buffer[0]), buffer.size(), 0,
+ mLeTransportBitOffset, mLeTransportBitSize);
+ setLeAudioTransportOk = device->setFeature(id, buffer);
+ if (!setLeAudioTransportOk) {
+ LOG_E << "enable: setFeature VENDOR LE TRANSPORT failed" << LOG_ENDL;
+ }
+ } else {
+ LOG_E << "enable: changing VENDOR LE TRANSPORT failed" << LOG_ENDL;
+ }
+ }
+
bool setPowerOk = true;
if (mPowerStateId >= 0) {
setPowerOk = false;
@@ -939,6 +1031,9 @@
HidUtil::copyBits(&index, &(buffer[0]), buffer.size(),
0, mPowerStateBitOffset, mPowerStateBitSize);
setPowerOk = device->setFeature(id, buffer);
+ if (!setPowerOk) {
+ LOG_E << "enable: setFeature POWER STATE failed" << LOG_ENDL;
+ }
} else {
LOG_E << "enable: changing POWER STATE failed" << LOG_ENDL;
}
@@ -956,12 +1051,15 @@
HidUtil::copyBits(&index, &(buffer[0]), buffer.size(),0,
mReportingStateBitOffset, mReportingStateBitSize);
setReportingOk = device->setFeature(id, buffer);
+ if (!setReportingOk) {
+ LOG_E << "enable: setFeature REPORTING STATE failed" << LOG_ENDL;
+ }
} else {
LOG_E << "enable: changing REPORTING STATE failed" << LOG_ENDL;
}
}
- if (setPowerOk && setReportingOk) {
+ if (setPowerOk && setReportingOk && setLeAudioTransportOk) {
mEnabled = enable;
return NO_ERROR;
} else {
@@ -1100,6 +1198,7 @@
std::ostringstream ss;
ss << "Feature Values " << LOG_ENDL
<< " name: " << mFeatureInfo.name << LOG_ENDL
+ << " version: 0x" << std::setfill('0') << std::setw(8) << std::hex << mFeatureInfo.version << LOG_ENDL
<< " vendor: " << mFeatureInfo.vendor << LOG_ENDL
<< " permission: " << mFeatureInfo.permission << LOG_ENDL
<< " typeString: " << mFeatureInfo.typeString << LOG_ENDL
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h
index e4564a0..3d2d94d 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.h
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.h
@@ -200,6 +200,11 @@
double mReportIntervalScale;
int64_t mReportIntervalOffset;
+ int mLeTransportId;
+ unsigned int mLeTransportBitOffset;
+ unsigned int mLeTransportBitSize;
+ bool mRequiresLeTransport;
+
// Input report translate table
std::vector<ReportTranslateRecord> mTranslateTable;
unsigned mInputReportId;
@@ -214,6 +219,20 @@
WP(HidDevice) mDevice;
bool mValid;
+
+ /**
+ * The first major version which LE audio capabilities are encoded.
+ * For this version, we expect the HID descriptor to be the following format:
+ * #AndroidHeadTracker#<major version>.<minor version>#<capability>
+ * where capability is an integer that defines where LE audio supported
+ * transports are indicated:
+ * - 1: ACL
+ * - 2: ISO
+ * - 3: ACL + ISO
+ */
+ const uint8_t kLeAudioCapabilitiesMajorVersion = 2;
+ const uint8_t kAclBitMask = 0x1;
+ const uint8_t kIsoBitMask = 0x2;
};
} // namespace SensorHalExt
diff --git a/modules/sensors/dynamic_sensor/HidSensorDef.h b/modules/sensors/dynamic_sensor/HidSensorDef.h
index 8f47a85..30c2f88 100644
--- a/modules/sensors/dynamic_sensor/HidSensorDef.h
+++ b/modules/sensors/dynamic_sensor/HidSensorDef.h
@@ -42,6 +42,7 @@
SENSOR_MODEL = 0x200306,
SENSOR_SERIAL_NUMBER = 0x200307,
SENSOR_STATUS = 0x200303,
+ VENDOR_LE_TRANSPORT = 0x20F410,
};
} // nsmespace PropertyUsage
diff --git a/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig b/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig
index 740c9e4..dc312c0 100644
--- a/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig
+++ b/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig
@@ -1,7 +1,7 @@
package: "com.android.libhardware.dynamic.sensors.flags"
flag {
- name: "sensors_dynamic_sensors_le_audio"
+ name: "dynamic_sensors_le_audio"
namespace: "sensors"
description: "This flag controls the enablement of LE audio support on dynamic sensors"
bug: "298450041"