From 67d23d4ace2d240fe064a81153d6c4444ae956ae Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Mon, 27 Nov 2023 18:26:10 +0000 Subject: [PATCH 1/5] Adds .aconfig flag for dynamic sensors + LE audio Bug: 298450041 Test: None Change-Id: I8ee86fd890f7cb2acd59c7c1798e574c6d2fd805 --- modules/sensors/dynamic_sensor/Android.bp | 13 +++++++++++++ .../sensors/dynamic_sensor/dynamic_sensors.aconfig | 8 ++++++++ 2 files changed, 21 insertions(+) create mode 100644 modules/sensors/dynamic_sensor/dynamic_sensors.aconfig diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp index 890da82d..b86b1dbe 100644 --- a/modules/sensors/dynamic_sensor/Android.bp +++ b/modules/sensors/dynamic_sensor/Android.bp @@ -182,3 +182,16 @@ cc_binary { "HidUtils/test", ], } + +aconfig_declarations { + name: "dynamic_sensors_flags", + package: "com.android.libhardware.dynamic.sensors.flags", + srcs: ["dynamic_sensors.aconfig"], +} + +cc_aconfig_library { + name: "dynamic_sensors_flags_c_lib", + aconfig_declarations: "dynamic_sensors_flags", + host_supported: true, + vendor: true, +} \ No newline at end of file diff --git a/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig b/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig new file mode 100644 index 00000000..740c9e46 --- /dev/null +++ b/modules/sensors/dynamic_sensor/dynamic_sensors.aconfig @@ -0,0 +1,8 @@ +package: "com.android.libhardware.dynamic.sensors.flags" + +flag { + name: "sensors_dynamic_sensors_le_audio" + namespace: "sensors" + description: "This flag controls the enablement of LE audio support on dynamic sensors" + bug: "298450041" +} \ No newline at end of file From 98996d121e3cb7be198ef0063bf25ad2b50a97ad Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Tue, 31 Oct 2023 23:47:41 +0000 Subject: [PATCH 2/5] Add support for LE audio capability detection Also fixes version handling in dynamic sensors sub HAL. Bug: 298450041 Test: To be tested on device Change-Id: I5eddd76b737f5ff5fe5ade2f8d9b271929223e76 --- modules/sensors/dynamic_sensor/Android.bp | 10 +- .../dynamic_sensor/DynamicSensorsSubHal.cpp | 4 +- .../sensors/dynamic_sensor/HidRawSensor.cpp | 113 ++++++++++++++++-- modules/sensors/dynamic_sensor/HidRawSensor.h | 19 +++ modules/sensors/dynamic_sensor/HidSensorDef.h | 1 + .../dynamic_sensor/dynamic_sensors.aconfig | 2 +- 6 files changed, 138 insertions(+), 11 deletions(-) diff --git a/modules/sensors/dynamic_sensor/Android.bp b/modules/sensors/dynamic_sensor/Android.bp index b86b1dbe..b6e0020c 100644 --- a/modules/sensors/dynamic_sensor/Android.bp +++ b/modules/sensors/dynamic_sensor/Android.bp @@ -35,9 +35,17 @@ cc_defaults { 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 @@ cc_defaults { "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 d5a9b3c0..101b983c 100644 --- a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -118,7 +118,7 @@ Return DynamicSensorsSubHal::getSensorsList_2_1( 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(sensor_info.type); sensors[0].typeAsString = sensor_info.stringType; sensors[0].maxRange = sensor_info.maxRange; @@ -210,7 +210,7 @@ void DynamicSensorsSubHal::onSensorConnected( 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(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 c90f4f1a..57df74d0 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 #include +#include #include "HidLog.h" #include @@ -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 &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 @@ void HidRawSensor::detectSensorFromDescription(const std::string &description) { 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#.# + // 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 @@ bool HidRawSensor::findSensorControlUsage(const std::vector(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 @@ int HidRawSensor::enable(bool enable) { } std::vector 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(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 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 @@ int HidRawSensor::enable(bool enable) { 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 @@ int HidRawSensor::enable(bool enable) { 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::string HidRawSensor::dump() const { 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 e4564a0f..3d2d94d0 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -200,6 +200,11 @@ private: double mReportIntervalScale; int64_t mReportIntervalOffset; + int mLeTransportId; + unsigned int mLeTransportBitOffset; + unsigned int mLeTransportBitSize; + bool mRequiresLeTransport; + // Input report translate table std::vector mTranslateTable; unsigned mInputReportId; @@ -214,6 +219,20 @@ private: 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#.# + * 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 8f47a850..30c2f88a 100644 --- a/modules/sensors/dynamic_sensor/HidSensorDef.h +++ b/modules/sensors/dynamic_sensor/HidSensorDef.h @@ -42,6 +42,7 @@ enum { 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 740c9e46..dc312c07 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" From 374655eeeaea0e54af29942f59f6e3a58828fcfb Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Tue, 5 Dec 2023 20:45:14 +0000 Subject: [PATCH 3/5] Updates LE transport selection logic Bug: 298450041 Test: Tested on device Change-Id: Ifb541280f12a72496e887b4d99d18064e97cda3f --- .../sensors/dynamic_sensor/HidRawSensor.cpp | 26 ++++++++++++++++++- modules/sensors/dynamic_sensor/HidRawSensor.h | 2 ++ modules/sensors/dynamic_sensor/HidSensorDef.h | 7 +++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 57df74d0..336461c7 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -849,6 +849,7 @@ bool HidRawSensor::findSensorControlUsage(const std::vectorid; mLeTransportBitOffset = leTransport->bitOffset; mLeTransportBitSize = leTransport->bitSize; + + mLeTransportAclIndex = -1; + mLeTransportIsoIndex = -1; + for (unsigned i = 0; i < leTransport->usageVector.size(); ++i) { + if (leTransport->usageVector[i] == LE_TRANSPORT_ACL) { + mLeTransportAclIndex = i; + } + if (leTransport->usageVector[i] == LE_TRANSPORT_ISO) { + mLeTransportIsoIndex = i; + } + } + if (mLeTransportAclIndex < 0) { + LOG_W << "Cannot find LE transport to enable ACL" + << LOG_ENDL; + mLeTransportId = -1; + } + if (mLeTransportIsoIndex < 0) { + LOG_W << "Cannot find LE transport to enable ISO" << LOG_ENDL; + mLeTransportId = -1; + } } } @@ -1009,7 +1030,10 @@ int HidRawSensor::enable(bool enable) { } else { value = (capability & kIsoBitMask) ? kLeIsoValue : kLeAclValue; } - HidUtil::copyBits(&value, &(buffer[0]), buffer.size(), 0, + + uint8_t index = (value == kLeAclValue) ? mLeTransportAclIndex : + mLeTransportIsoIndex; + HidUtil::copyBits(&index, &(buffer[0]), buffer.size(), 0, mLeTransportBitOffset, mLeTransportBitSize); setLeAudioTransportOk = device->setFeature(id, buffer); if (!setLeAudioTransportOk) { diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h index 3d2d94d0..a9847c8e 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.h +++ b/modules/sensors/dynamic_sensor/HidRawSensor.h @@ -204,6 +204,8 @@ private: unsigned int mLeTransportBitOffset; unsigned int mLeTransportBitSize; bool mRequiresLeTransport; + int mLeTransportAclIndex; + int mLeTransportIsoIndex; // Input report translate table std::vector mTranslateTable; diff --git a/modules/sensors/dynamic_sensor/HidSensorDef.h b/modules/sensors/dynamic_sensor/HidSensorDef.h index 30c2f88a..d347ef67 100644 --- a/modules/sensors/dynamic_sensor/HidSensorDef.h +++ b/modules/sensors/dynamic_sensor/HidSensorDef.h @@ -100,6 +100,13 @@ enum { }; } // namespace PowerStateUsage +namespace LeTransportUsage { +enum { + LE_TRANSPORT_ACL = 0xF800, + LE_TRANSPORT_ISO = 0xF801, +}; +} // namespace LeTransportUsage + } // namespace Sensor } // namespace Hid #endif // HID_SENSOR_DEF_H_ From 072d07df7f15c07f33f6f5565b0de9e1db0d677b Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Fri, 8 Dec 2023 17:43:14 +0000 Subject: [PATCH 4/5] Simplify transport selection logic Bug: 298450041 Test: Compile Change-Id: I35c7ed3c0a7ba603215b6b2c3fcfb9a7993f5c8e --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index 336461c7..dcf4b470 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -1004,9 +1004,6 @@ int HidRawSensor::enable(bool enable) { 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 @@ -1020,19 +1017,17 @@ int HidRawSensor::enable(bool enable) { } uint16_t capability = mFeatureInfo.version & 0x0000FFFF; - uint8_t value; + uint8_t index; if (capability == (kIsoBitMask | kAclBitMask)) { if (!priorityList.empty() && priorityList[0].compare("le-acl") == 0) { - value = kLeAclValue; + index = mLeTransportAclIndex; } else { - value = kLeIsoValue; + index = mLeTransportIsoIndex; } } else { - value = (capability & kIsoBitMask) ? kLeIsoValue : kLeAclValue; + index = (capability & kIsoBitMask) ? mLeTransportIsoIndex : mLeTransportAclIndex; } - uint8_t index = (value == kLeAclValue) ? mLeTransportAclIndex : - mLeTransportIsoIndex; HidUtil::copyBits(&index, &(buffer[0]), buffer.size(), 0, mLeTransportBitOffset, mLeTransportBitSize); setLeAudioTransportOk = device->setFeature(id, buffer); From 070e169bdbe050a193b1f34feb461360572618a5 Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Mon, 11 Dec 2023 23:22:55 +0000 Subject: [PATCH 5/5] Only send head tracker v2.0 transport selection on enable Bug: 298450041 Test: Compile Change-Id: I0da896913f09a8215189974cf294d6b2a26d12f8 --- modules/sensors/dynamic_sensor/HidRawSensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp index dcf4b470..939b58df 100644 --- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp +++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp @@ -998,7 +998,7 @@ int HidRawSensor::enable(bool enable) { std::vector buffer; // TODO(b/298450041): Refactor the operations below in a separate function. bool setLeAudioTransportOk = true; - if (mLeTransportId >= 0) { + if (mLeTransportId >= 0 && enable) { setLeAudioTransportOk = false; uint8_t id = static_cast(mLeTransportId); if (device->getFeature(id, &buffer)