Merge "Add findWithParams and connectWithParams to the P2P Supplicant AIDL Interface" into main
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index 57a5252..3a1f098 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -274,6 +274,13 @@
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ},
{VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ},
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index 5bc41b5..5a58298 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -274,6 +274,13 @@
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index 97d9a24..4bc1852 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -265,7 +265,14 @@
Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ),
- Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE)
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess.READ)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index cb0240b..1e00d9f 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -265,7 +265,14 @@
Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
- Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE)
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
index 144d0e1..958d84b 100644
--- a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
@@ -93,7 +93,11 @@
Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, List.of(CruiseControlState.class, ErrorState.class)),
Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, List.of(CruiseControlCommand.class)),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, List.of(HandsOnDetectionDriverState.class, ErrorState.class)),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, List.of(HandsOnDetectionWarning.class, ErrorState.class))
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, List.of(HandsOnDetectionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, List.of(DriverDrowsinessAttentionState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, List.of(DriverDrowsinessAttentionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, List.of(DriverDistractionState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, List.of(DriverDistractionWarning.class, ErrorState.class))
);
}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 82dc8a6..e4d134e 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -41,6 +41,10 @@
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlState;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
using ::aidl::android::hardware::automotive::vehicle::EmergencyLaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
@@ -252,6 +256,14 @@
std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
mConstantParsersByType["HandsOnDetectionWarning"] =
std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
+ mConstantParsersByType["DriverDrowsinessAttentionState"] =
+ std::make_unique<ConstantParser<DriverDrowsinessAttentionState>>();
+ mConstantParsersByType["DriverDrowsinessAttentionWarning"] =
+ std::make_unique<ConstantParser<DriverDrowsinessAttentionWarning>>();
+ mConstantParsersByType["DriverDistractionState"] =
+ std::make_unique<ConstantParser<DriverDistractionState>>();
+ mConstantParsersByType["DriverDistractionWarning"] =
+ std::make_unique<ConstantParser<DriverDistractionWarning>>();
mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
mConstantParsersByType["AutomaticEmergencyBrakingState"] =
std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index bd40ca2..e462609 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -3554,6 +3554,109 @@
}
},
{
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDrowsinessAttentionState::KSS_RATING_1_EXTREMELY_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_2_VERY_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_4_RATHER_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
+ "DriverDrowsinessAttentionState::KSS_RATING_6_SOME_SLEEPINESS",
+ "DriverDrowsinessAttentionState::KSS_RATING_7_SLEEPY_NO_EFFORT",
+ "DriverDrowsinessAttentionState::KSS_RATING_8_SLEEPY_SOME_EFFORT",
+ "DriverDrowsinessAttentionState::KSS_RATING_9_VERY_SLEEPY"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDrowsinessAttentionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDrowsinessAttentionWarning::NO_WARNING",
+ "DriverDrowsinessAttentionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDistractionState::NOT_DISTRACTED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDistractionState::NOT_DISTRACTED",
+ "DriverDistractionState::DISTRACTED"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDistractionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDistractionWarning::NO_WARNING",
+ "DriverDistractionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::INITIAL_USER_INFO"
},
{
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index acee9b3..754ae1e 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -53,6 +53,10 @@
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
@@ -192,6 +196,35 @@
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
+ // Driver Drowsiness and Attention
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE),
+ },
+ },
+ // Driver Drowsiness and Attention Warning
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING),
+ },
+ },
+ // Driver Distraction
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_STATE),
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING),
+ },
+ },
+ // Driver Distraction Warning
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING),
+ },
+ },
};
} // namespace
@@ -304,13 +337,13 @@
}
// OBD2_LIVE_FRAME and OBD2_FREEZE_FRAME must be configured in default configs.
- auto maybeObd2LiveFrame = mServerSidePropStore->getConfig(OBD2_LIVE_FRAME);
+ auto maybeObd2LiveFrame = mServerSidePropStore->getPropConfig(OBD2_LIVE_FRAME);
if (maybeObd2LiveFrame.has_value()) {
- mFakeObd2Frame->initObd2LiveFrame(*maybeObd2LiveFrame.value());
+ mFakeObd2Frame->initObd2LiveFrame(maybeObd2LiveFrame.value());
}
- auto maybeObd2FreezeFrame = mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME);
+ auto maybeObd2FreezeFrame = mServerSidePropStore->getPropConfig(OBD2_FREEZE_FRAME);
if (maybeObd2FreezeFrame.has_value()) {
- mFakeObd2Frame->initObd2FreezeFrame(*maybeObd2FreezeFrame.value());
+ mFakeObd2Frame->initObd2FreezeFrame(maybeObd2FreezeFrame.value());
}
mServerSidePropStore->setOnValueChangeCallback(
@@ -472,7 +505,7 @@
VhalResult<void> FakeVehicleHardware::setHvacTemperatureValueSuggestion(
const VehiclePropValue& hvacTemperatureValueSuggestion) {
auto hvacTemperatureSetConfigResult =
- mServerSidePropStore->getConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
+ mServerSidePropStore->getPropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
if (!hvacTemperatureSetConfigResult.ok()) {
return StatusError(getErrorCode(hvacTemperatureSetConfigResult)) << StringPrintf(
@@ -499,7 +532,7 @@
}
auto updatedValue = mValuePool->obtain(hvacTemperatureValueSuggestion);
- const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value()->configArray;
+ const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value().configArray;
auto& hvacTemperatureValueSuggestionInput = updatedValue->value.floatValues;
updateHvacTemperatureValueSuggestionInput(hvacTemperatureSetConfigArray,
@@ -822,14 +855,14 @@
void FakeVehicleHardware::sendAdasPropertiesState(int32_t propertyId, int32_t state) {
auto& adasDependentPropIds = mAdasEnabledPropToAdasPropWithErrorState.find(propertyId)->second;
for (auto dependentPropId : adasDependentPropIds) {
- auto dependentPropConfigResult = mServerSidePropStore->getConfig(dependentPropId);
+ auto dependentPropConfigResult = mServerSidePropStore->getPropConfig(dependentPropId);
if (!dependentPropConfigResult.ok()) {
ALOGW("Failed to get config for ADAS property 0x%x, error: %s", dependentPropId,
getErrorMsg(dependentPropConfigResult).c_str());
continue;
}
auto& dependentPropConfig = dependentPropConfigResult.value();
- for (auto& areaConfig : dependentPropConfig->areaConfigs) {
+ for (auto& areaConfig : dependentPropConfig.areaConfigs) {
int32_t hardcoded_state = state;
// TODO: restore old/initial values here instead of hardcoded value (b/295542701)
if (state == 1 && dependentPropId == toInt(VehicleProperty::CRUISE_CONTROL_TYPE)) {
@@ -1702,12 +1735,12 @@
continue;
}
int32_t prop = propResult.value();
- auto result = mServerSidePropStore->getConfig(prop);
+ auto result = mServerSidePropStore->getPropConfig(prop);
if (!result.ok()) {
msg += StringPrintf("No property %d\n", prop);
continue;
}
- msg += dumpOnePropertyByConfig(rowNumber++, *result.value());
+ msg += dumpOnePropertyByConfig(rowNumber++, result.value());
}
return msg;
}
@@ -2014,7 +2047,7 @@
StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {
int32_t propId = options.propId;
- auto configResult = mServerSidePropStore->getConfig(propId);
+ auto configResult = mServerSidePropStore->getPropConfig(propId);
if (!configResult.ok()) {
ALOGE("subscribe: property: %" PRId32 " is not supported", propId);
return StatusCode::INVALID_ARG;
@@ -2024,7 +2057,7 @@
for (int areaId : options.areaIds) {
if (StatusCode status = subscribePropIdAreaIdLocked(propId, areaId, options.sampleRate,
options.enableVariableUpdateRate,
- *configResult.value());
+ configResult.value());
status != StatusCode::OK) {
return status;
}
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index e6d657d..6c1d0a0 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -24,6 +24,10 @@
#include <aidl/android/hardware/automotive/vehicle/CruiseControlType.h>
#include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
#include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.h>
#include <aidl/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/ErrorState.h>
#include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index ef36532..7b328f2 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -143,11 +143,17 @@
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig> getAllConfigs()
const EXCLUDES(mLock);
- // Get the property config for the requested property.
+ // Deprecated, use getPropConfig instead. This is unsafe to use if registerProperty overwrites
+ // an existing config.
android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*,
VhalError>
getConfig(int32_t propId) const EXCLUDES(mLock);
+ // Get the property config for the requested property.
+ android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropConfig,
+ VhalError>
+ getPropConfig(int32_t propId) const EXCLUDES(mLock);
+
// Set a callback that would be called when a property value has been updated.
void setOnValueChangeCallback(const OnValueChangeCallback& callback) EXCLUDES(mLock);
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index 7d9d8b7..4171cf7 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -318,6 +318,17 @@
return &record->propConfig;
}
+VhalResult<VehiclePropConfig> VehiclePropertyStore::getPropConfig(int32_t propId) const {
+ std::scoped_lock<std::mutex> g(mLock);
+
+ const VehiclePropertyStore::Record* record = getRecordLocked(propId);
+ if (record == nullptr) {
+ return StatusError(StatusCode::INVALID_ARG) << "property: " << propId << " not registered";
+ }
+
+ return record->propConfig;
+}
+
void VehiclePropertyStore::setOnValueChangeCallback(
const VehiclePropertyStore::OnValueChangeCallback& callback) {
std::scoped_lock<std::mutex> g(mLock);
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 625652e..328d244 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -101,16 +101,16 @@
ASSERT_EQ(configs.size(), static_cast<size_t>(2));
}
-TEST_F(VehiclePropertyStoreTest, testGetConfig) {
- VhalResult<const VehiclePropConfig*> result =
- mStore->getConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
+TEST_F(VehiclePropertyStoreTest, testGetPropConfig) {
+ VhalResult<VehiclePropConfig> result =
+ mStore->getPropConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
ASSERT_RESULT_OK(result);
- ASSERT_EQ(*(result.value()), mConfigFuelCapacity);
+ ASSERT_EQ(result.value(), mConfigFuelCapacity);
}
-TEST_F(VehiclePropertyStoreTest, testGetConfigWithInvalidPropId) {
- VhalResult<const VehiclePropConfig*> result = mStore->getConfig(INVALID_PROP_ID);
+TEST_F(VehiclePropertyStoreTest, testGetPropConfigWithInvalidPropId) {
+ VhalResult<VehiclePropConfig> result = mStore->getPropConfig(INVALID_PROP_ID);
EXPECT_FALSE(result.ok()) << "expect error when getting a config for an invalid property ID";
EXPECT_EQ(result.error().code(), StatusCode::INVALID_ARG);
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl
new file mode 100644
index 0000000..54c02d5
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDistractionState {
+ OTHER = 0,
+ NOT_DISTRACTED = 1,
+ DISTRACTED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
new file mode 100644
index 0000000..9236b1c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDistractionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
new file mode 100644
index 0000000..22a90f3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDrowsinessAttentionState {
+ OTHER = 0,
+ KSS_RATING_1_EXTREMELY_ALERT = 1,
+ KSS_RATING_2_VERY_ALERT = 2,
+ KSS_RATING_3_ALERT = 3,
+ KSS_RATING_4_RATHER_ALERT = 4,
+ KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY = 5,
+ KSS_RATING_6_SOME_SLEEPINESS = 6,
+ KSS_RATING_7_SLEEPY_NO_EFFORT = 7,
+ KSS_RATING_8_SLEEPY_SOME_EFFORT = 8,
+ KSS_RATING_9_VERY_SLEEPY = 9,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
new file mode 100644
index 0000000..dbf2364
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDrowsinessAttentionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index db28615..649396a 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -272,4 +272,11 @@
HANDS_ON_DETECTION_DRIVER_STATE = (((0x1017 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411095 */,
HANDS_ON_DETECTION_WARNING = (((0x1018 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411096 */,
DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED = (((0x1019 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313945 */,
+ DRIVER_DROWSINESS_ATTENTION_STATE = (((0x101A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411098 */,
+ DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED = (((0x101B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313947 */,
+ DRIVER_DROWSINESS_ATTENTION_WARNING = (((0x101C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411100 */,
+ DRIVER_DISTRACTION_SYSTEM_ENABLED = (((0x101D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313949 */,
+ DRIVER_DISTRACTION_STATE = (((0x101E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411102 */,
+ DRIVER_DISTRACTION_WARNING_ENABLED = (((0x101F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313951 */,
+ DRIVER_DISTRACTION_WARNING = (((0x1020 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411104 */,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
new file mode 100644
index 0000000..f350a6c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of driver distraction monitoring.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDistractionState {
+ /**
+ * This state is used as an alternative for any DriverDistractionState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DISTRACTION_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDistractionState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * The system detects that the driver is attentive / not distracted.
+ */
+ NOT_DISTRACTED = 1,
+ /**
+ * The system detects that the driver is distracted, which can be anything that reduces the
+ * driver's foucs on the primary task of driving/controlling the vehicle.
+ */
+ DISTRACTED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
new file mode 100644
index 0000000..a4b1984
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of the driver distraction monitoring system.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDistractionWarning {
+ /**
+ * This state is used as an alternative for any DriverDistractionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DISTRACTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDistractionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * When the driver distraction warning is enabled and the driver's current distraction level
+ * does not warrant the system to send a warning.
+ */
+ NO_WARNING = 1,
+ /**
+ * When the driver distraction warning is enabled and the system is warning the driver based on
+ * its assessment of the driver's current distraction level.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
new file mode 100644
index 0000000..d2aec1f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of driver drowsiness and attention monitoring.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDrowsinessAttentionState {
+ /**
+ * This state is used as an alternative for any DriverDrowsinessAttentionState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DROWSINESS_ATTENTION_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDrowsinessAttentionState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Karolinska Sleepiness Scale Rating 1 described as extermely alert.
+ */
+ KSS_RATING_1_EXTREMELY_ALERT = 1,
+ /**
+ * Karolinska Sleepiness Scale Rating 2 described as very alert.
+ */
+ KSS_RATING_2_VERY_ALERT = 2,
+ /**
+ * Karolinska Sleepiness Scale Rating 3 described as alert.
+ */
+ KSS_RATING_3_ALERT = 3,
+ /**
+ * Karolinska Sleepiness Scale Rating 4 described as rather alert.
+ */
+ KSS_RATING_4_RATHER_ALERT = 4,
+ /**
+ * Karolinska Sleepiness Scale Rating 5 described as neither alert nor sleepy.
+ */
+ KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY = 5,
+ /**
+ * Karolinska Sleepiness Scale Rating 6 described as some signs of sleepiness.
+ */
+ KSS_RATING_6_SOME_SLEEPINESS = 6,
+ /**
+ * Karolinska Sleepiness Scale Rating 7 described as sleepy with no effort to
+ * keep awake.
+ */
+ KSS_RATING_7_SLEEPY_NO_EFFORT = 7,
+ /**
+ * Karolinska Sleepiness Scale Rating 8 described as sleepy with some effort to
+ * keep awake.
+ */
+ KSS_RATING_8_SLEEPY_SOME_EFFORT = 8,
+ /**
+ * Karolinska Sleepiness Scale Rating 9 described as very sleepy, with great
+ * effort to keep away, and fighthing sleep.
+ */
+ KSS_RATING_9_VERY_SLEEPY = 9,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
new file mode 100644
index 0000000..53b66b9
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of the driver drowsiness and attention monitoring
+ * system.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDrowsinessAttentionWarning {
+ /**
+ * This state is used as an alternative for any DriverDrowsinessAttentionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DROWSINESS_ATTENTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDrowsinessAttentionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * When the driver drowsiness and attention warning is enabled, and the driver's current
+ * drowsiness and attention level does not warrant the system to send a warning.
+ */
+ NO_WARNING = 1,
+ /**
+ * When the driver drowsiness and attention warning is enabled, and the system is warning the
+ * driver based on its assessment of the driver's current drowsiness and attention level.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index b2e4d05..8784fc8 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -5109,6 +5109,167 @@
DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED =
0x1019 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Driver drowsiness and attention level state.
+ *
+ * Returns the current detected state of driver drowiness and attention level based on the
+ * Karolinska Sleepiness scale. If alternative measurement methods are used, the value should be
+ * translated to the Karolinska Sleepiness Scale equivalent.
+ *
+ * Generally, this property should return a valid state defined in the
+ * DriverDrowsinessAttentionState or ErrorState. For example, if the feature is not available
+ * due to some temporary state, that information should be conveyed through ErrorState.
+ *
+ * If the vehicle is sending a warning to the user because the driver is too drowsy, the warning
+ * should be surfaced through {@link #DRIVER_DROWSINESS_ATTENTION_WARNING}.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDrowsinessAttentionState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDrowsinessAttentionState
+ * @data_enum ErrorState
+ */
+ DRIVER_DROWSINESS_ATTENTION_STATE =
+ 0x101A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver drowsiness and attention warnings.
+ *
+ * Set true to enable driver drowsiness and attention warnings and false to disable driver
+ * drowsiness and attention warnings.
+ *
+ * When driver drowsiness and attention warnings are enabled, the driver drowsiness and
+ * attention monitoring system inside the vehicle should warn the driver when it detects the
+ * driver is drowsy or not attentive.
+ *
+ * In general, DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, that information must be
+ * conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_WARNING property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED =
+ 0x101B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver drowsiness and attention warning.
+ *
+ * Returns whether a warning is being sent to the driver for being drowsy or not attentive.
+ *
+ * Generally, this property should return a valid state defined in
+ * DriverDrowsinessAttentionWarning or ErrorState. For example, if the feature is not available
+ * due to some temporary state, that information should be conveyed through an ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDrowsinessAttentionWarning (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDrowsinessAttentionWarning
+ * @data_enum ErrorState
+ */
+ DRIVER_DROWSINESS_ATTENTION_WARNING =
+ 0x101C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver distraction monitoring.
+ *
+ * Set true to enable driver distraction monitoring and false to disable driver
+ * distraction monitoring. When driver distraction monitoring is enabled, a system
+ * inside the vehicle should be monitoring the distraction level of the driver and
+ * warn the driver if needed.
+ *
+ * In general, DRIVER_DISTRACTION_SYSTEM_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, that information must be conveyed
+ * through the ErrorState values in the DRIVER_DISTRACTION_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DISTRACTION_SYSTEM_ENABLED =
+ 0x101D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver distraction state.
+ *
+ * Returns the current detected driver distraction state.
+ *
+ * Generally, this property should return a valid state defined in the DriverDistractionState or
+ * ErrorState. For example, if the feature is not available due to some temporary state, that
+ * information should be conveyed through ErrorState.
+ *
+ * If the vehicle is sending a warning to the user because the driver is too distracted, the
+ * warning should be surfaced through {@link #DRIVER_DISTRACTION_WARNING}.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDistractionState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDistractionState
+ * @data_enum ErrorState
+ */
+ DRIVER_DISTRACTION_STATE =
+ 0x101E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver distraction warnings.
+ *
+ * Set true to enable driver distraction warnings and false to disable driver distraction
+ * warnings.
+ *
+ * When driver distraction warnings are enabled, the driver distraction monitoring system inside
+ * the vehicle should warn the driver when it detects the driver is distracted.
+ *
+ * In general, DRIVER_DISTRACTION_WARNING_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, that information must be conveyed
+ * through the ErrorState values in the DRIVER_DISTRACTION_WARNING property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DISTRACTION_WARNING_ENABLED =
+ 0x101F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver distraction warning.
+ *
+ * Returns whether a warning is being sent to the driver for being distracted.
+ *
+ * Generally, this property should return a valid state defined in DriverDistractionWarning or
+ * ErrorState. For example, if the feature is not available due to some temporary state, that
+ * information should be conveyed through an ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDistractionWarning (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDistractionWarning
+ * @data_enum ErrorState
+ */
+ DRIVER_DISTRACTION_WARNING =
+ 0x1020 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
/***************************************************************************
* End of ADAS Properties
**************************************************************************/
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 785d192..6f81807 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -627,6 +627,48 @@
VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionStateConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionWarningConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionSystemEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionStateConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionWarningConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBrakeRegenerationLevelConfig) {
verifyProperty(VehicleProperty::EV_BRAKE_REGENERATION_LEVEL,
VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
index b990812..599c491 100644
--- a/biometrics/common/util/Android.bp
+++ b/biometrics/common/util/Android.bp
@@ -13,6 +13,6 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
],
}
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 6c8cd78..0d977a9 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,7 +14,7 @@
"android/hardware/biometrics/face/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V3",
+ "android.hardware.biometrics.common-V4",
"android.hardware.common-V2",
"android.hardware.keymaster-V4",
],
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index ecd0934..4816219 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -40,7 +40,7 @@
],
stl: "c++_static",
static_libs: [
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.face-V4-ndk",
@@ -75,7 +75,7 @@
static_libs: [
"libandroid.hardware.biometrics.face.VirtualProps",
"android.hardware.biometrics.face-V4-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index c543a93..1a099a5 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,7 +14,7 @@
"android/hardware/biometrics/fingerprint/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V3",
+ "android.hardware.biometrics.common-V4",
"android.hardware.keymaster-V4",
],
stability: "vintf",
@@ -50,5 +50,5 @@
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index a173a00..c3ec4d0 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -30,8 +30,8 @@
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
"libbase",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.keymaster-V4-ndk",
@@ -54,8 +54,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -80,8 +80,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -104,8 +104,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -130,8 +130,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
index e977b98..827813f 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.xml
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.biometrics.fingerprint</name>
- <version>3</version>
+ <version>4</version>
<fqname>IFingerprint/virtual</fqname>
</hal>
</manifest>
diff --git a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
index 937cd57..0699781 100644
--- a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
+++ b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
@@ -162,9 +162,9 @@
(struct mgmt_ev_read_index_list*)ev.data;
for (int i = 0; i < data->num_controllers; i++) {
- if (data->index[i] == hci_interface) {
- ALOGI("hci interface %d found", hci_interface);
- ret = 0;
+ if (data->index[i] >= hci_interface) {
+ ALOGI("hci interface %d found", data->index[i]);
+ ret = data->index[i];
goto end;
}
}
@@ -253,8 +253,9 @@
rfkill(1);
// Wait for the HCI interface to complete initialization or to come online.
- if (waitHciDev(hci_interface)) {
- ALOGE("hci interface %d not found", hci_interface);
+ hci_interface = waitHciDev(hci_interface);
+ if (hci_interface < 0) {
+ ALOGE("hci interface not found");
return -1;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
new file mode 100644
index 0000000..9e67b15
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpConfiguration {
+ int remoteSeid;
+ android.hardware.bluetooth.audio.CodecId id;
+ android.hardware.bluetooth.audio.CodecParameters parameters;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
new file mode 100644
index 0000000..0a5b489
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpConfigurationHint {
+ byte[6] bdAddr;
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ @nullable android.hardware.bluetooth.audio.CodecId codecId;
+ @nullable android.hardware.bluetooth.audio.CodecParameters codecParameters;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
new file mode 100644
index 0000000..9c1e971
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpRemoteCapabilities {
+ int seid;
+ android.hardware.bluetooth.audio.CodecId id;
+ byte[] capabilities;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl
new file mode 100644
index 0000000..ac22e25
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum A2dpStatus {
+ OK = 0,
+ BAD_LENGTH = 0x11u8,
+ BAD_PAYLOAD_FORMAT = 0x18u8,
+ INVALID_CODEC_TYPE = 0xC1u8,
+ NOT_SUPPORTED_CODEC_TYPE = 0xC2u8,
+ INVALID_SAMPLING_FREQUENCY = 0xC3u8,
+ NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4u8,
+ INVALID_CHANNEL_MODE = 0xC5u8,
+ NOT_SUPPORTED_CHANNEL_MODE = 0xC6u8,
+ INVALID_SUBBANDS = 0xC7u8,
+ NOT_SUPPORTED_SUBBANDS = 0xC8u8,
+ INVALID_ALLOCATION_METHOD = 0xC9u8,
+ NOT_SUPPORTED_ALLOCATION_METHOD = 0xCAu8,
+ INVALID_MINIMUM_BITPOOL_VALUE = 0xCBu8,
+ NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCCu8,
+ INVALID_MAXIMUM_BITPOOL_VALUE = 0xCDu8,
+ NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCEu8,
+ NOT_SUPPORTED_VBR = 0xD3u8,
+ NOT_SUPPORTED_BIT_RATE = 0xD5u8,
+ INVALID_OBJECT_TYPE = 0xD6u8,
+ NOT_SUPPORTED_OBJECT_TYPE = 0xD7u8,
+ INVALID_CHANNELS = 0xD8u8,
+ NOT_SUPPORTED_CHANNELS = 0xD9u8,
+ INVALID_BLOCK_LENGTH = 0xDDu8,
+ INVALID_CODEC_PARAMETER = 0xE2u8,
+ NOT_SUPPORTED_CODEC_PARAMETER = 0xE3u8,
+ INVALID_DRC = 0xE4u8,
+ NOT_SUPPORTED_DRC = 0xE5u8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
new file mode 100644
index 0000000..ff5a1bc
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpStreamConfiguration {
+ int peerMtu;
+ @nullable byte[1] cpHeaderScmst;
+ android.hardware.bluetooth.audio.CodecId codecId;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index 3abfb31..2c40267 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -38,4 +38,6 @@
android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+ android.hardware.bluetooth.audio.HfpConfiguration hfpConfig;
+ android.hardware.bluetooth.audio.A2dpStreamConfiguration a2dp;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl
new file mode 100644
index 0000000..60cf82a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable CodecParameters {
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ int samplingFrequencyHz;
+ int bitdepth;
+ int minBitrate;
+ int maxBitrate;
+ boolean lowLatency;
+ boolean lossless;
+ byte[] vendorSpecificParameters;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl
new file mode 100644
index 0000000..490a05d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable HfpConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ int connectionHandle;
+ boolean nrec;
+ boolean controllerCodec;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 267af0f..ccf5524 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -40,4 +40,6 @@
void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
void setLowLatencyModeAllowed(in boolean allowed);
+ android.hardware.bluetooth.audio.A2dpStatus parseA2dpConfiguration(in android.hardware.bluetooth.audio.CodecId codecId, in byte[] configuration, out android.hardware.bluetooth.audio.CodecParameters codecParameters);
+ @nullable android.hardware.bluetooth.audio.A2dpConfiguration getA2dpConfiguration(in List<android.hardware.bluetooth.audio.A2dpRemoteCapabilities> remoteA2dpCapabilities, in android.hardware.bluetooth.audio.A2dpConfigurationHint hint);
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 4b2c10f..71cca53 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -46,4 +46,7 @@
LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
A2DP_SOFTWARE_DECODING_DATAPATH,
A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ HFP_SOFTWARE_ENCODING_DATAPATH,
+ HFP_SOFTWARE_DECODING_DATAPATH,
+ HFP_HARDWARE_OFFLOAD_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
new file mode 100644
index 0000000..a7fd9ff
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+
+/**
+ * A2DP Service Configuration
+ */
+@VintfStability
+parcelable A2dpConfiguration {
+ /**
+ * Remote Stream Endpoint Identifier
+ */
+ int remoteSeid;
+
+ /**
+ * Codec Selection and configuration, in a generic way with `parameters`
+ * and as defined by A2DP for codec interoperability requirements, with
+ * `configuration`. Using `id.a2dp`, the format is given by the `Codec
+ * Specific Information Elements` [A2DP - 4.3-6.2], and using `id.vendor`,
+ * by `Vendor Specific Value` [A2DP - 4.7.2].
+ * In any case, this byte array is limited by the framework to 128 Bytes.
+ */
+ CodecId id;
+ CodecParameters parameters;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
new file mode 100644
index 0000000..f707a8a
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioContext;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+
+/**
+ * A2DP Configuration Hints
+ */
+@VintfStability
+parcelable A2dpConfigurationHint {
+ /**
+ * Bluetooth Device Address, intended to be used for interoperabilities.
+ */
+ byte[6] bdAddr;
+
+ /**
+ * Audio configuration hints:
+ * - The starting audio context of the session
+ * - An optional preference of codec and / or parameters
+ */
+
+ AudioContext audioContext;
+ @nullable CodecId codecId;
+ @nullable CodecParameters codecParameters;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
new file mode 100644
index 0000000..87277f1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+/**
+ * A2DP Remote Capabilites
+ */
+@VintfStability
+parcelable A2dpRemoteCapabilities {
+ /**
+ * Remote Stream Endpoint identifier
+ */
+ int seid;
+
+ /**
+ * Codec Identifier and `capabilities` as defined by A2DP for codec
+ * interoperability requirements. Using `id.a2dp`, the format is given
+ * by the `Codec Specific Information Elements` [A2DP - 4.3-6.2], and
+ * using `id.vendor`, by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ CodecId id;
+ byte[] capabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl
new file mode 100644
index 0000000..8eba3c9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum A2dpStatus {
+
+ OK = 0,
+
+ /**
+ * Error codes defined by AVDTP [AVDTP - 8.20.6.2]
+ */
+
+ BAD_LENGTH = 0x11u8,
+ BAD_PAYLOAD_FORMAT = 0x18u8,
+
+ /**
+ * Error codecs defined by A2DP for AVDTP Interoperability [A2DP - 5.1.3]
+ */
+
+ INVALID_CODEC_TYPE = 0xC1u8,
+ NOT_SUPPORTED_CODEC_TYPE = 0xC2u8,
+ INVALID_SAMPLING_FREQUENCY = 0xC3u8,
+ NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4u8,
+ INVALID_CHANNEL_MODE = 0xC5u8,
+ NOT_SUPPORTED_CHANNEL_MODE = 0xC6u8,
+ INVALID_SUBBANDS = 0xC7u8,
+ NOT_SUPPORTED_SUBBANDS = 0xC8u8,
+ INVALID_ALLOCATION_METHOD = 0xC9u8,
+ NOT_SUPPORTED_ALLOCATION_METHOD = 0xCAu8,
+ INVALID_MINIMUM_BITPOOL_VALUE = 0xCBu8,
+ NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCCu8,
+ INVALID_MAXIMUM_BITPOOL_VALUE = 0xCDu8,
+ NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCEu8,
+ NOT_SUPPORTED_VBR = 0xD3u8,
+ NOT_SUPPORTED_BIT_RATE = 0xD5u8,
+ INVALID_OBJECT_TYPE = 0xD6u8,
+ NOT_SUPPORTED_OBJECT_TYPE = 0xD7u8,
+ INVALID_CHANNELS = 0xD8u8,
+ NOT_SUPPORTED_CHANNELS = 0xD9u8,
+ INVALID_BLOCK_LENGTH = 0xDDu8,
+ INVALID_CODEC_PARAMETER = 0xE2u8,
+ NOT_SUPPORTED_CODEC_PARAMETER = 0xE3u8,
+ INVALID_DRC = 0xE4u8,
+ NOT_SUPPORTED_DRC = 0xE5u8,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
new file mode 100644
index 0000000..2a0c4d8
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+@VintfStability
+parcelable A2dpStreamConfiguration {
+ /**
+ * Peer MTU (16 bits)
+ */
+ int peerMtu;
+
+ /**
+ * Optional SCMS-T Content Protection header
+ * that precedes audio content when enabled [A2DP - 3.2.1-2].
+ * The content protection byte is defined by [Assigned Number - 6.3.2].
+ */
+ @nullable byte[1] cpHeaderScmst;
+
+ /**
+ * Codec Identifier and `configuration` as defined by A2DP for codec
+ * interoperability requirements. Using `codecId.a2dp`, the format is given
+ * by the `Codec Specific Information Elements` [A2DP - 4.3-6.2], and
+ * using `codecId.vendor`, by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ CodecId codecId;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index a06337e..5317dfb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -16,7 +16,9 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.A2dpStreamConfiguration;
import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.HfpConfiguration;
import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration;
import android.hardware.bluetooth.audio.LeAudioConfiguration;
import android.hardware.bluetooth.audio.PcmConfiguration;
@@ -30,4 +32,6 @@
CodecConfiguration a2dpConfig;
LeAudioConfiguration leAudioConfig;
LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+ HfpConfiguration hfpConfig;
+ A2dpStreamConfiguration a2dp;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl
new file mode 100644
index 0000000..b6f8a94
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used to exchange generic codec parameters between the stack and the provider.
+ */
+@VintfStability
+parcelable CodecParameters {
+ /**
+ * PCM related parameters:
+ * - Mono, Dual-Mono or Stereo
+ * - Sampling frequencies, in Hz.
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation..
+ */
+ ChannelMode channelMode;
+ int samplingFrequencyHz;
+ int bitdepth;
+
+ /**
+ * Encoding parameters:
+ *
+ * - Bitrate limits on a frame basis, defined in bits per second.
+ * The encoder bitrate mode can be encoded following this rule:
+ * . minBitrate equals to maxBitrate for constant bitrate
+ * . minBitrate set to 0, for VBR with peak bitrate at maxBitratre value.
+ * . minBitrate greater than 0, for ABR, the bitrate of the stream varies
+ * between minBitrate to maxBitrate according to link quality.
+ * The 0 value for both means "undefined" or "don't care".
+ *
+ * - Low-latency configuration privileged
+ * - Lossless effort indication. The 'False' value can be used as "don't care"
+ */
+ int minBitrate;
+ int maxBitrate;
+
+ boolean lowLatency;
+ boolean lossless;
+
+ /**
+ * Vendor specific parameters, inserted in the Vendor Specific HCI Command
+ * `Start A2DP Offload` as it is. The stack operates as a pass-through;
+ * the data SHALL NOT be inspected nor written by the client.
+ * The size is limited to 128 bytes by the client; a larger size is
+ * interpreted as a zero-sized buffer.
+ */
+ byte[] vendorSpecificParameters;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl
new file mode 100644
index 0000000..9494bb9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+@VintfStability
+parcelable HfpConfiguration {
+ /**
+ * Codec identifier.
+ */
+ CodecId codecId;
+
+ /**
+ * The connection handle used for SCO connection.
+ * Range: 0x0000 to 0x0EFF.
+ */
+ int connectionHandle;
+
+ /**
+ * Echo canceling and noise reduction functions resident in the AG.
+ */
+ boolean nrec;
+
+ /**
+ * Indicate whether the codec is encoded and decoded in the controller.
+ * If the codec is inside the DSP, then it would be transparent mode.
+ */
+ boolean controllerCodec;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 558173e..b5c8a31 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -16,8 +16,14 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.A2dpConfiguration;
+import android.hardware.bluetooth.audio.A2dpConfigurationHint;
+import android.hardware.bluetooth.audio.A2dpRemoteCapabilities;
+import android.hardware.bluetooth.audio.A2dpStatus;
import android.hardware.bluetooth.audio.AudioConfiguration;
import android.hardware.bluetooth.audio.BluetoothAudioStatus;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
import android.hardware.bluetooth.audio.IBluetoothAudioPort;
import android.hardware.bluetooth.audio.LatencyMode;
import android.hardware.common.fmq.MQDescriptor;
@@ -92,4 +98,30 @@
* mode, the API will be called with supported is false.
*/
void setLowLatencyModeAllowed(in boolean allowed);
+
+ /**
+ * Validate and parse an A2DP Configuration,
+ * shall be used with A2DP session types
+ *
+ * @param codecId Identify the codec
+ * @param The configuration as defined by the A2DP's `Codec Specific
+ * Information Elements`, or `Vendor Specific Value` when CodecId
+ * format is set to `VENDOR`.
+ * @param codecParameters result of parsing, when the validation succeeded.
+ * @return A2DP Status of the parsing
+ */
+ A2dpStatus parseA2dpConfiguration(
+ in CodecId codecId, in byte[] configuration, out CodecParameters codecParameters);
+
+ /**
+ * Return a configuration, from a list of remote Capabilites,
+ * shall be used with A2DP session types
+ *
+ * @param remoteCapabilities The capabilities of the remote device
+ * @param hint Hint on selection (audio context and/or codec)
+ * @return The requested configuration. A null value value is returned
+ * when no suitable configuration has been found.
+ */
+ @nullable A2dpConfiguration getA2dpConfiguration(
+ in List<A2dpRemoteCapabilities> remoteA2dpCapabilities, in A2dpConfigurationHint hint);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
index 7acb5c6..35292a1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -70,4 +70,17 @@
* The decoding of AVDTP media is done by HW and there is control only
*/
A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ /**
+ * Used when audio is encoded by Bluetooth Stack and is streaming to HFP device.
+ */
+ HFP_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * Used when audio is decoded by Bluetooth Stack and is streaming to HFP device.
+ */
+ HFP_SOFTWARE_DECODING_DATAPATH,
+ /**
+ * Used when encoded and decoded by hardware offload and is streamed to HFP device.
+ * This is a control path only.
+ */
+ HFP_HARDWARE_OFFLOAD_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/default/A2dpBits.h b/bluetooth/audio/aidl/default/A2dpBits.h
new file mode 100644
index 0000000..f467c95
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpBits.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpBits {
+ const uint8_t* cdata_;
+ uint8_t* data_;
+
+ public:
+ A2dpBits(const std::vector<uint8_t>& vector) : cdata_(vector.data()) {}
+
+ A2dpBits(std::vector<uint8_t>& vector)
+ : cdata_(vector.data()), data_(vector.data()) {}
+
+ struct Range {
+ const int first, len;
+ constexpr Range(int first, int last)
+ : first(first), len(last - first + 1) {}
+ constexpr Range(int index) : first(index), len(1) {}
+ };
+
+ constexpr bool get(int bit) const {
+ return (cdata_[bit >> 3] >> (7 - (bit & 7))) & 1;
+ }
+
+ constexpr unsigned get(const Range& range) const {
+ unsigned v(0);
+ for (int i = 0; i < range.len; i++)
+ v |= get(range.first + i) << ((range.len - 1) - i);
+ return v;
+ }
+
+ constexpr void set(int bit, int value = 1) {
+ uint8_t m = 1 << (7 - (bit & 7));
+ if (value)
+ data_[bit >> 3] |= m;
+ else
+ data_[bit >> 3] &= ~m;
+ }
+
+ constexpr void set(const Range& range, int value) {
+ for (int i = 0; i < range.len; i++)
+ set(range.first + i, (value >> ((range.len - 1) - i)) & 1);
+ }
+
+ constexpr int find_active_bit(const Range& range) const {
+ unsigned v = get(range);
+ int i = 0;
+ for (; i < range.len && ((v >> i) & 1) == 0; i++)
+ ;
+ return i < range.len && (v ^ (1 << i)) == 0
+ ? range.first + (range.len - 1) - i
+ : -1;
+ }
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
index 2d0d8c9..ba7a89d 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -22,6 +22,10 @@
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
+#include "A2dpOffloadCodecAac.h"
+#include "A2dpOffloadCodecFactory.h"
+#include "A2dpOffloadCodecSbc.h"
+
namespace aidl {
namespace android {
namespace hardware {
@@ -48,19 +52,44 @@
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
- if (audio_config.getTag() != AudioConfiguration::a2dpConfig) {
+ if (audio_config.getTag() == AudioConfiguration::Tag::a2dp) {
+ auto a2dp_config = audio_config.get<AudioConfiguration::Tag::a2dp>();
+ A2dpStatus a2dp_status = A2dpStatus::NOT_SUPPORTED_CODEC_TYPE;
+
+ if (a2dp_config.codecId ==
+ A2dpOffloadCodecSbc::GetInstance()->GetCodecId()) {
+ SbcParameters sbc_parameters;
+ a2dp_status = A2dpOffloadCodecSbc::GetInstance()->ParseConfiguration(
+ a2dp_config.configuration, &sbc_parameters);
+
+ } else if (a2dp_config.codecId ==
+ A2dpOffloadCodecAac::GetInstance()->GetCodecId()) {
+ AacParameters aac_parameters;
+ a2dp_status = A2dpOffloadCodecAac::GetInstance()->ParseConfiguration(
+ a2dp_config.configuration, &aac_parameters);
+ }
+ if (a2dp_status != A2dpStatus::OK) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else if (audio_config.getTag() == AudioConfiguration::Tag::a2dpConfig) {
+ if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
+ session_type_,
+ audio_config.get<AudioConfiguration::a2dpConfig>())) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
- session_type_, audio_config.get<AudioConfiguration::a2dpConfig>())) {
- LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
- << audio_config.toString();
- *_aidl_return = DataMQDesc();
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
+
return BluetoothAudioProvider::startSession(
host_if, audio_config, latency_modes, _aidl_return);
}
@@ -73,6 +102,36 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus A2dpOffloadAudioProvider::parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return) {
+ auto codec = A2dpOffloadCodecFactory::GetInstance()->GetCodec(codec_id);
+ if (!codec) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " - CodecId=" << codec_id.toString() << " is not found";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ *_aidl_return = codec->ParseConfiguration(configuration, codec_parameters);
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus A2dpOffloadAudioProvider::getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return) {
+ *_aidl_return = std::nullopt;
+ A2dpConfiguration avdtp_configuration;
+
+ if (A2dpOffloadCodecFactory::GetInstance()->GetConfiguration(
+ remote_a2dp_capabilities, hint, &avdtp_configuration))
+ *_aidl_return =
+ std::make_optional<A2dpConfiguration>(std::move(avdtp_configuration));
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
index e6f188b..7cc6dee 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
@@ -34,7 +34,16 @@
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ DataMQDesc* _aidl_return) override;
+
+ ndk::ScopedAStatus parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return) override;
+
+ ndk::ScopedAStatus getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return) override;
private:
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodec.h b/bluetooth/audio/aidl/default/A2dpOffloadCodec.h
new file mode 100644
index 0000000..7ed5872
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodec.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/A2dpStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecParameters.h>
+
+#include "BluetoothAudioProviderFactory.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpOffloadCodec {
+ protected:
+ A2dpOffloadCodec(const CodecInfo& info) : info(info) {}
+ virtual ~A2dpOffloadCodec() {}
+
+ public:
+ const CodecInfo& info;
+
+ const CodecId& GetCodecId() const { return info.id; }
+
+ virtual A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const = 0;
+
+ virtual bool BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const = 0;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp
new file mode 100644
index 0000000..0f5533a
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecAac.h"
+
+#include "A2dpBits.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * AAC Local Capabilities
+ */
+
+enum : bool {
+ kEnableObjectTypeMpeg2AacLc = true,
+ kEnableObjectTypeMpeg4AacLc = true,
+};
+
+enum : bool {
+ kEnableSamplingFrequency44100 = true,
+ kEnableSamplingFrequency48000 = true,
+ kEnableSamplingFrequency88200 = false,
+ kEnableSamplingFrequency96000 = false,
+};
+
+enum : bool {
+ kEnableChannels1 = true,
+ kEnableChannels2 = true,
+};
+
+enum : bool {
+ kEnableVbrSupported = true,
+};
+
+enum : int {
+ kBitdepth = 24,
+};
+
+/**
+ * AAC Signaling format [A2DP - 4.5]
+ */
+
+// clang-format off
+
+constexpr A2dpBits::Range kObjectType ( 0, 6 );
+constexpr A2dpBits::Range kDrcEnable ( 7 );
+constexpr A2dpBits::Range kSamplingFrequency ( 8, 19 );
+constexpr A2dpBits::Range kChannels ( 20, 23 );
+constexpr A2dpBits::Range kVbrSupported ( 24 );
+constexpr A2dpBits::Range kBitrate ( 25, 47 );
+constexpr size_t kCapabilitiesSize = 48/8;
+
+// clang-format on
+
+enum {
+ kObjectTypeMpeg2AacLc = kObjectType.first,
+ kObjectTypeMpeg4AacLc,
+ kObjectTypeMpeg4AacLtp,
+ kObjectTypeMpeg4AacScalable,
+ kObjectTypeMpeg4AacHeV1,
+ kObjectTypeMpeg4AacHeV2,
+ kObjectTypeMpeg4AacEldV2
+};
+
+enum {
+ kSamplingFrequency8000 = kSamplingFrequency.first,
+ kSamplingFrequency11025,
+ kSamplingFrequency12000,
+ kSamplingFrequency16000,
+ kSamplingFrequency22050,
+ kSamplingFrequency24000,
+ kSamplingFrequency32000,
+ kSamplingFrequency44100,
+ kSamplingFrequency48000,
+ kSamplingFrequency64000,
+ kSamplingFrequency88200,
+ kSamplingFrequency96000
+};
+
+enum { kChannels1 = kChannels.first, kChannels2, kChannels51, kChannels71 };
+
+/**
+ * AAC Conversion functions
+ */
+
+static AacParameters::ObjectType GetObjectTypeEnum(int object_type) {
+ switch (object_type) {
+ case kObjectTypeMpeg2AacLc:
+ return AacParameters::ObjectType::MPEG2_AAC_LC;
+ case kObjectTypeMpeg4AacLc:
+ default:
+ return AacParameters::ObjectType::MPEG4_AAC_LC;
+ }
+}
+
+static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
+ switch (sampling_frequency) {
+ case 8000:
+ return kSamplingFrequency8000;
+ case 11025:
+ return kSamplingFrequency11025;
+ case 12000:
+ return kSamplingFrequency12000;
+ case 16000:
+ return kSamplingFrequency16000;
+ case 22050:
+ return kSamplingFrequency22050;
+ case 24000:
+ return kSamplingFrequency24000;
+ case 32000:
+ return kSamplingFrequency32000;
+ case 44100:
+ return kSamplingFrequency44100;
+ case 48000:
+ return kSamplingFrequency48000;
+ case 64000:
+ return kSamplingFrequency64000;
+ case 88200:
+ return kSamplingFrequency88200;
+ case 96000:
+ return kSamplingFrequency96000;
+ default:
+ return -1;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
+ switch (sampling_frequency) {
+ case kSamplingFrequency8000:
+ return 8000;
+ case kSamplingFrequency11025:
+ return 11025;
+ case kSamplingFrequency12000:
+ return 12000;
+ case kSamplingFrequency16000:
+ return 16000;
+ case kSamplingFrequency22050:
+ return 22050;
+ case kSamplingFrequency24000:
+ return 24000;
+ case kSamplingFrequency32000:
+ return 32000;
+ case kSamplingFrequency44100:
+ return 44100;
+ case kSamplingFrequency48000:
+ return 48000;
+ case kSamplingFrequency64000:
+ return 64000;
+ case kSamplingFrequency88200:
+ return 88200;
+ case kSamplingFrequency96000:
+ return 96000;
+ default:
+ return 0;
+ }
+}
+
+static int GetChannelsBit(ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::MONO:
+ return kChannels1;
+ case ChannelMode::STEREO:
+ return kChannels2;
+ default:
+ return -1;
+ }
+}
+
+static ChannelMode GetChannelModeEnum(int channel_mode) {
+ switch (channel_mode) {
+ case kChannels1:
+ return ChannelMode::MONO;
+ case kChannels2:
+ return ChannelMode::STEREO;
+ default:
+ return ChannelMode::UNKNOWN;
+ }
+}
+
+/**
+ * AAC Class implementation
+ */
+
+const A2dpOffloadCodecAac* A2dpOffloadCodecAac::GetInstance() {
+ static A2dpOffloadCodecAac instance;
+ return &instance;
+}
+
+A2dpOffloadCodecAac::A2dpOffloadCodecAac()
+ : A2dpOffloadCodec(info_),
+ info_({.id = CodecId(CodecId::A2dp::AAC), .name = "AAC"}) {
+ info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ /* --- Setup Capabilities --- */
+
+ a2dp_info.capabilities.resize(kCapabilitiesSize);
+ std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
+
+ auto capabilities = A2dpBits(a2dp_info.capabilities);
+
+ capabilities.set(kObjectTypeMpeg2AacLc, kEnableObjectTypeMpeg2AacLc);
+ capabilities.set(kObjectTypeMpeg4AacLc, kEnableObjectTypeMpeg4AacLc);
+
+ capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
+ capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
+ capabilities.set(kSamplingFrequency88200, kEnableSamplingFrequency88200);
+ capabilities.set(kSamplingFrequency96000, kEnableSamplingFrequency96000);
+
+ capabilities.set(kChannels1, kEnableChannels1);
+ capabilities.set(kChannels2, kEnableChannels2);
+
+ capabilities.set(kVbrSupported, kEnableVbrSupported);
+
+ /* --- Setup Sampling Frequencies --- */
+
+ auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
+
+ for (auto v : {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+ 64000, 88200, 96000})
+ if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
+ sampling_frequency.push_back(v);
+
+ /* --- Setup Channel Modes --- */
+
+ auto& channel_modes = a2dp_info.channelMode;
+
+ for (auto v : {ChannelMode::MONO, ChannelMode::STEREO})
+ if (capabilities.get(GetChannelsBit(v))) channel_modes.push_back(v);
+
+ /* --- Setup Bitdepth --- */
+
+ a2dp_info.bitdepth.push_back(kBitdepth);
+}
+
+A2dpStatus A2dpOffloadCodecAac::ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, AacParameters* aac_parameters) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (configuration.size() != a2dp_info.capabilities.size())
+ return A2dpStatus::BAD_LENGTH;
+
+ auto config = A2dpBits(configuration);
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+
+ /* --- Check Object Type --- */
+
+ int object_type = config.find_active_bit(kObjectType);
+ if (object_type < 0) return A2dpStatus::INVALID_OBJECT_TYPE;
+ if (!lcaps.get(object_type)) return A2dpStatus::NOT_SUPPORTED_OBJECT_TYPE;
+
+ /* --- Check Sampling Frequency --- */
+
+ int sampling_frequency = config.find_active_bit(kSamplingFrequency);
+ if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
+ if (!lcaps.get(sampling_frequency))
+ return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
+
+ /* --- Check Channels --- */
+
+ int channels = config.find_active_bit(kChannels);
+ if (channels < 0) return A2dpStatus::INVALID_CHANNELS;
+ if (!lcaps.get(channels)) return A2dpStatus::NOT_SUPPORTED_CHANNELS;
+
+ /* --- Check Bitrate --- */
+
+ bool vbr = config.get(kVbrSupported);
+ if (vbr && !lcaps.get(kVbrSupported)) return A2dpStatus::NOT_SUPPORTED_VBR;
+
+ int bitrate = config.get(kBitrate);
+ if (vbr && lcaps.get(kBitrate) && bitrate > lcaps.get(kBitrate))
+ return A2dpStatus::NOT_SUPPORTED_BIT_RATE;
+
+ /* --- Return --- */
+
+ codec_parameters->channelMode = GetChannelModeEnum(channels);
+ codec_parameters->samplingFrequencyHz =
+ GetSamplingFrequencyValue(sampling_frequency);
+ codec_parameters->bitdepth = kBitdepth;
+
+ codec_parameters->minBitrate = vbr ? 0 : bitrate;
+ codec_parameters->maxBitrate = bitrate;
+
+ if (aac_parameters)
+ aac_parameters->object_type = GetObjectTypeEnum(object_type);
+
+ return A2dpStatus::OK;
+}
+
+bool A2dpOffloadCodecAac::BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const {
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
+
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+ auto rcaps = A2dpBits(remote_capabilities);
+
+ configuration->resize(a2dp_info.capabilities.size());
+ std::fill(begin(*configuration), end(*configuration), 0);
+ auto config = A2dpBits(*configuration);
+
+ /* --- Select Object Type --- */
+
+ if (lcaps.get(kObjectTypeMpeg2AacLc) && rcaps.get(kObjectTypeMpeg2AacLc))
+ config.set(kObjectTypeMpeg2AacLc);
+ else if (lcaps.get(kObjectTypeMpeg4AacLc) && rcaps.get(kObjectTypeMpeg4AacLc))
+ config.set(kObjectTypeMpeg4AacLc);
+ else
+ return false;
+
+ /* --- Select Sampling Frequency --- */
+
+ auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
+
+ if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
+ config.set(sf_hint);
+ else if (lcaps.get(kSamplingFrequency96000) &&
+ rcaps.get(kSamplingFrequency96000))
+ config.set(kSamplingFrequency96000);
+ else if (lcaps.get(kSamplingFrequency88200) &&
+ rcaps.get(kSamplingFrequency88200))
+ config.set(kSamplingFrequency88200);
+ else if (lcaps.get(kSamplingFrequency48000) &&
+ rcaps.get(kSamplingFrequency48000))
+ config.set(kSamplingFrequency48000);
+ else if (lcaps.get(kSamplingFrequency44100) &&
+ rcaps.get(kSamplingFrequency44100))
+ config.set(kSamplingFrequency44100);
+ else
+ return false;
+
+ /* --- Select Channels --- */
+
+ auto ch_hint = hint ? GetChannelsBit(hint->channelMode) : -1;
+
+ if (ch_hint >= 0 && lcaps.get(ch_hint) && rcaps.get(ch_hint))
+ config.set(ch_hint);
+ else if (lcaps.get(kChannels2) && rcaps.get(kChannels2))
+ config.set(kChannels2);
+ else if (lcaps.get(kChannels1) && rcaps.get(kChannels1))
+ config.set(kChannels1);
+ else
+ return false;
+
+ /* --- Select Bitrate --- */
+
+ if (!hint || hint->minBitrate == 0)
+ config.set(kVbrSupported,
+ lcaps.get(kVbrSupported) && rcaps.get(kVbrSupported));
+
+ int32_t bitrate = lcaps.get(kBitrate);
+ if (hint && hint->maxBitrate > 0 && bitrate)
+ bitrate = std::min(hint->maxBitrate, bitrate);
+ else if (hint && hint->maxBitrate > 0)
+ bitrate = hint->maxBitrate;
+ config.set(kBitrate, bitrate);
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h
new file mode 100644
index 0000000..eefa89b
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+struct AacParameters : public CodecParameters {
+ enum class ObjectType { MPEG2_AAC_LC, MPEG4_AAC_LC };
+
+ ObjectType object_type;
+};
+
+class A2dpOffloadCodecAac : public A2dpOffloadCodec {
+ CodecInfo info_;
+
+ A2dpOffloadCodecAac();
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters,
+ AacParameters* aac_parameters) const;
+
+ public:
+ static const A2dpOffloadCodecAac* GetInstance();
+
+ A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const override {
+ return ParseConfiguration(configuration, codec_parameters, nullptr);
+ }
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ AacParameters* aac_parameters) const {
+ return ParseConfiguration(configuration, aac_parameters, aac_parameters);
+ }
+
+ bool BuildConfiguration(const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp
new file mode 100644
index 0000000..73d8fb1
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecFactory.h"
+
+#include <algorithm>
+#include <cassert>
+
+#include "A2dpOffloadCodecAac.h"
+#include "A2dpOffloadCodecSbc.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * Local Capabilities Configuration
+ */
+
+enum : bool {
+ kEnableAac = true,
+ kEnableSbc = true,
+};
+
+/**
+ * Class implementation
+ */
+
+const A2dpOffloadCodecFactory* A2dpOffloadCodecFactory::GetInstance() {
+ static A2dpOffloadCodecFactory instance;
+ return &instance;
+}
+
+A2dpOffloadCodecFactory::A2dpOffloadCodecFactory()
+ : name("Offload"), codecs(ranked_codecs_) {
+ ranked_codecs_.reserve(kEnableAac + kEnableSbc);
+
+ if (kEnableAac) ranked_codecs_.push_back(A2dpOffloadCodecAac::GetInstance());
+ if (kEnableSbc) ranked_codecs_.push_back(A2dpOffloadCodecSbc::GetInstance());
+}
+
+const A2dpOffloadCodec* A2dpOffloadCodecFactory::GetCodec(CodecId id) const {
+ auto codec = std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
+ [&](auto c) { return id == c->info.id; });
+
+ return codec != end(ranked_codecs_) ? *codec : nullptr;
+}
+
+bool A2dpOffloadCodecFactory::GetConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_capabilities,
+ const A2dpConfigurationHint& hint, A2dpConfiguration* configuration) const {
+ decltype(ranked_codecs_) codecs;
+
+ codecs.reserve(ranked_codecs_.size());
+
+ auto hinted_codec =
+ std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
+ [&](auto c) { return hint.codecId == c->info.id; });
+
+ if (hinted_codec != end(ranked_codecs_)) codecs.push_back(*hinted_codec);
+
+ std::copy_if(begin(ranked_codecs_), end(ranked_codecs_),
+ std::back_inserter(codecs),
+ [&](auto c) { return c != *hinted_codec; });
+
+ for (auto codec : codecs) {
+ auto rc =
+ std::find_if(begin(remote_capabilities), end(remote_capabilities),
+ [&](auto& rc__) { return codec->info.id == rc__.id; });
+
+ if ((rc == end(remote_capabilities)) ||
+ !codec->BuildConfiguration(rc->capabilities, hint.codecParameters,
+ &configuration->configuration))
+ continue;
+
+ configuration->id = codec->info.id;
+ A2dpStatus status = codec->ParseConfiguration(configuration->configuration,
+ &configuration->parameters);
+ assert(status == A2dpStatus::OK);
+
+ configuration->remoteSeid = rc->seid;
+
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h
new file mode 100644
index 0000000..3fb5b1d
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpOffloadCodecFactory {
+ std::vector<const A2dpOffloadCodec*> ranked_codecs_;
+
+ A2dpOffloadCodecFactory();
+
+ public:
+ const std::string name;
+ const std::vector<const A2dpOffloadCodec*>& codecs;
+
+ static const A2dpOffloadCodecFactory* GetInstance();
+
+ const A2dpOffloadCodec* GetCodec(CodecId id) const;
+
+ bool GetConfiguration(const std::vector<A2dpRemoteCapabilities>&,
+ const A2dpConfigurationHint& hint,
+ A2dpConfiguration* configuration) const;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
new file mode 100644
index 0000000..36d8f72
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecSbc.h"
+
+#include <algorithm>
+
+#include "A2dpBits.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * SBC Local Capabilities
+ */
+
+enum : bool {
+ kEnableSamplingFrequency44100 = true,
+ kEnableSamplingFrequency48000 = true,
+};
+
+enum : bool {
+ kEnableChannelModeMono = true,
+ kEnableChannelModeDualChannel = true,
+ kEnableChannelModeStereo = true,
+ kEnableChannelModeJointStereo = true,
+};
+
+enum : bool {
+ kEnableBlockLength4 = true,
+ kEnableBlockLength8 = true,
+ kEnableBlockLength12 = true,
+ kEnableBlockLength16 = true,
+};
+
+enum : bool {
+ kEnableSubbands4 = true,
+ kEnableSubbands8 = true,
+};
+
+enum : bool {
+ kEnableAllocationMethodSnr = true,
+ kEnableAllocationMethodLoudness = true,
+};
+
+enum : uint8_t {
+ kDefaultMinimumBitpool = 2,
+ kDefaultMaximumBitpool = 250,
+};
+
+enum : int {
+ kBitdepth = 16,
+};
+
+/**
+ * SBC Signaling format [A2DP - 4.3]
+ */
+
+// clang-format off
+
+constexpr A2dpBits::Range kSamplingFrequency ( 0, 3 );
+constexpr A2dpBits::Range kChannelMode ( 4, 7 );
+constexpr A2dpBits::Range kBlockLength ( 8, 11 );
+constexpr A2dpBits::Range kSubbands ( 12, 13 );
+constexpr A2dpBits::Range kAllocationMethod ( 14, 15 );
+constexpr A2dpBits::Range kMinimumBitpool ( 16, 23 );
+constexpr A2dpBits::Range kMaximumBitpool ( 24, 31 );
+constexpr size_t kCapabilitiesSize = 32/8;
+
+// clang-format on
+
+enum {
+ kSamplingFrequency16000 = kSamplingFrequency.first,
+ kSamplingFrequency32000,
+ kSamplingFrequency44100,
+ kSamplingFrequency48000
+};
+
+enum {
+ kChannelModeMono = kChannelMode.first,
+ kChannelModeDualChannel,
+ kChannelModeStereo,
+ kChannelModeJointStereo
+};
+
+enum {
+ kBlockLength4 = kBlockLength.first,
+ kBlockLength8,
+ kBlockLength12,
+ kBlockLength16
+};
+
+enum { kSubbands8 = kSubbands.first, kSubbands4 };
+
+enum {
+ kAllocationMethodSnr = kAllocationMethod.first,
+ kAllocationMethodLoudness
+};
+
+/**
+ * SBC Conversion functions
+ */
+
+static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
+ switch (sampling_frequency) {
+ case 16000:
+ return kSamplingFrequency16000;
+ case 32000:
+ return kSamplingFrequency32000;
+ case 44100:
+ return kSamplingFrequency44100;
+ case 48000:
+ return kSamplingFrequency48000;
+ default:
+ return -1;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
+ switch (sampling_frequency) {
+ case kSamplingFrequency16000:
+ return 16000;
+ case kSamplingFrequency32000:
+ return 32000;
+ case kSamplingFrequency44100:
+ return 44100;
+ case kSamplingFrequency48000:
+ return 48000;
+ default:
+ return 0;
+ }
+}
+
+static int GetChannelModeBit(ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::STEREO:
+ return kChannelModeJointStereo | kChannelModeStereo;
+ case ChannelMode::DUALMONO:
+ return kChannelModeDualChannel;
+ case ChannelMode::MONO:
+ return kChannelModeMono;
+ default:
+ return -1;
+ }
+}
+
+static ChannelMode GetChannelModeEnum(int channel_mode) {
+ switch (channel_mode) {
+ case kChannelModeMono:
+ return ChannelMode::MONO;
+ case kChannelModeDualChannel:
+ return ChannelMode::DUALMONO;
+ case kChannelModeStereo:
+ case kChannelModeJointStereo:
+ return ChannelMode::STEREO;
+ default:
+ return ChannelMode::UNKNOWN;
+ }
+}
+
+static int32_t GetBlockLengthValue(int block_length) {
+ switch (block_length) {
+ case kBlockLength4:
+ return 4;
+ case kBlockLength8:
+ return 8;
+ case kBlockLength12:
+ return 12;
+ case kBlockLength16:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+static int32_t GetSubbandsValue(int subbands) {
+ switch (subbands) {
+ case kSubbands4:
+ return 4;
+ case kSubbands8:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+static SbcParameters::AllocationMethod GetAllocationMethodEnum(
+ int allocation_method) {
+ switch (allocation_method) {
+ case kAllocationMethodSnr:
+ return SbcParameters::AllocationMethod::SNR;
+ case kAllocationMethodLoudness:
+ default:
+ return SbcParameters::AllocationMethod::LOUDNESS;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(const A2dpBits& configuration) {
+ return GetSamplingFrequencyValue(
+ configuration.find_active_bit(kSamplingFrequency));
+}
+
+static int32_t GetBlockLengthValue(const A2dpBits& configuration) {
+ return GetBlockLengthValue(configuration.find_active_bit(kBlockLength));
+}
+
+static int32_t GetSubbandsValue(const A2dpBits& configuration) {
+ return GetSubbandsValue(configuration.find_active_bit(kSubbands));
+}
+
+static int GetFrameSize(const A2dpBits& configuration, int bitpool) {
+ const int kSbcHeaderSize = 4;
+ int subbands = GetSubbandsValue(configuration);
+ int blocks = GetBlockLengthValue(configuration);
+
+ unsigned bits =
+ ((4 * subbands) << !configuration.get(kChannelModeMono)) +
+ ((blocks * bitpool) << configuration.get(kChannelModeDualChannel)) +
+ ((configuration.get(kChannelModeJointStereo) ? subbands : 0));
+
+ return kSbcHeaderSize + ((bits + 7) >> 3);
+}
+
+static int GetBitrate(const A2dpBits& configuration, int bitpool) {
+ int sampling_frequency = GetSamplingFrequencyValue(configuration);
+ int subbands = GetSubbandsValue(configuration);
+ int blocks = GetBlockLengthValue(configuration);
+ int bits = 8 * GetFrameSize(configuration, bitpool);
+
+ return (bits * sampling_frequency) / (blocks * subbands);
+}
+
+static uint8_t GetBitpool(const A2dpBits& configuration, int bitrate) {
+ int bitpool = 0;
+
+ for (int i = 128; i; i >>= 1)
+ if (bitrate > GetBitrate(configuration, bitpool + i)) {
+ bitpool += i;
+ }
+
+ return std::clamp(bitpool, 2, 250);
+}
+
+/**
+ * SBC Class implementation
+ */
+
+const A2dpOffloadCodecSbc* A2dpOffloadCodecSbc::GetInstance() {
+ static A2dpOffloadCodecSbc instance;
+ return &instance;
+}
+
+A2dpOffloadCodecSbc::A2dpOffloadCodecSbc()
+ : A2dpOffloadCodec(info_),
+ info_({.id = CodecId(CodecId::A2dp::SBC), .name = "SBC"}) {
+ info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ /* --- Setup Capabilities --- */
+
+ a2dp_info.capabilities.resize(kCapabilitiesSize);
+ std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
+
+ auto capabilities = A2dpBits(a2dp_info.capabilities);
+
+ capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
+ capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
+
+ capabilities.set(kChannelModeMono, kEnableChannelModeMono);
+ capabilities.set(kChannelModeDualChannel, kEnableChannelModeDualChannel);
+ capabilities.set(kChannelModeStereo, kEnableChannelModeStereo);
+ capabilities.set(kChannelModeJointStereo, kEnableChannelModeJointStereo);
+
+ capabilities.set(kBlockLength4, kEnableBlockLength4);
+ capabilities.set(kBlockLength8, kEnableBlockLength8);
+ capabilities.set(kBlockLength12, kEnableBlockLength12);
+ capabilities.set(kBlockLength16, kEnableBlockLength16);
+
+ capabilities.set(kSubbands4, kEnableSubbands4);
+ capabilities.set(kSubbands8, kEnableSubbands8);
+
+ capabilities.set(kSubbands4, kEnableSubbands4);
+ capabilities.set(kSubbands8, kEnableSubbands8);
+
+ capabilities.set(kAllocationMethodSnr, kEnableAllocationMethodSnr);
+ capabilities.set(kAllocationMethodLoudness, kEnableAllocationMethodLoudness);
+
+ capabilities.set(kMinimumBitpool, kDefaultMinimumBitpool);
+ capabilities.set(kMaximumBitpool, kDefaultMaximumBitpool);
+
+ /* --- Setup Sampling Frequencies --- */
+
+ auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
+
+ for (auto v : {16000, 32000, 44100, 48000})
+ if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
+ sampling_frequency.push_back(v);
+
+ /* --- Setup Channel Modes --- */
+
+ auto& channel_modes = a2dp_info.channelMode;
+
+ for (auto v : {ChannelMode::MONO, ChannelMode::DUALMONO, ChannelMode::STEREO})
+ if (capabilities.get(GetChannelModeBit(v))) channel_modes.push_back(v);
+
+ /* --- Setup Bitdepth --- */
+
+ a2dp_info.bitdepth.push_back(kBitdepth);
+}
+
+A2dpStatus A2dpOffloadCodecSbc::ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, SbcParameters* sbc_parameters) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (configuration.size() != a2dp_info.capabilities.size())
+ return A2dpStatus::BAD_LENGTH;
+
+ auto config = A2dpBits(configuration);
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+
+ /* --- Check Sampling Frequency --- */
+
+ int sampling_frequency = config.find_active_bit(kSamplingFrequency);
+ if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
+ if (!lcaps.get(sampling_frequency))
+ return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
+
+ /* --- Check Channel Mode --- */
+
+ int channel_mode = config.find_active_bit(kChannelMode);
+ if (channel_mode < 0) return A2dpStatus::INVALID_CHANNEL_MODE;
+ if (!lcaps.get(channel_mode)) return A2dpStatus::NOT_SUPPORTED_CHANNEL_MODE;
+
+ /* --- Check Block Length --- */
+
+ int block_length = config.find_active_bit(kBlockLength);
+ if (block_length < 0) return A2dpStatus::INVALID_BLOCK_LENGTH;
+
+ /* --- Check Subbands --- */
+
+ int subbands = config.find_active_bit(kSubbands);
+ if (subbands < 0) return A2dpStatus::INVALID_SUBBANDS;
+ if (!lcaps.get(subbands)) return A2dpStatus::NOT_SUPPORTED_SUBBANDS;
+
+ /* --- Check Allocation Method --- */
+
+ int allocation_method = config.find_active_bit(kAllocationMethod);
+ if (allocation_method < 0) return A2dpStatus::INVALID_ALLOCATION_METHOD;
+ if (!lcaps.get(allocation_method))
+ return A2dpStatus::NOT_SUPPORTED_ALLOCATION_METHOD;
+
+ /* --- Check Bitpool --- */
+
+ uint8_t min_bitpool = config.get(kMinimumBitpool);
+ if (min_bitpool < 2 || min_bitpool > 250)
+ return A2dpStatus::INVALID_MINIMUM_BITPOOL_VALUE;
+ if (min_bitpool < lcaps.get(kMinimumBitpool))
+ return A2dpStatus::NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE;
+
+ uint8_t max_bitpool = config.get(kMaximumBitpool);
+ if (max_bitpool < 2 || max_bitpool > 250)
+ return A2dpStatus::INVALID_MAXIMUM_BITPOOL_VALUE;
+ if (max_bitpool > lcaps.get(kMaximumBitpool))
+ return A2dpStatus::NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE;
+
+ /* --- Return --- */
+
+ codec_parameters->channelMode = GetChannelModeEnum(channel_mode);
+ codec_parameters->samplingFrequencyHz =
+ GetSamplingFrequencyValue(sampling_frequency);
+ codec_parameters->bitdepth = kBitdepth;
+
+ codec_parameters->minBitrate = GetBitrate(config, min_bitpool);
+ codec_parameters->maxBitrate = GetBitrate(config, max_bitpool);
+
+ if (sbc_parameters) {
+ sbc_parameters->block_length = GetBlockLengthValue(block_length);
+ sbc_parameters->subbands = GetSubbandsValue(subbands);
+ sbc_parameters->allocation_method =
+ GetAllocationMethodEnum(allocation_method);
+ sbc_parameters->min_bitpool = min_bitpool;
+ sbc_parameters->max_bitpool = max_bitpool;
+ }
+
+ return A2dpStatus::OK;
+}
+
+bool A2dpOffloadCodecSbc::BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
+
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+ auto rcaps = A2dpBits(remote_capabilities);
+
+ configuration->resize(a2dp_info.capabilities.size());
+ std::fill(begin(*configuration), end(*configuration), 0);
+ auto config = A2dpBits(*configuration);
+
+ /* --- Select Sampling Frequency --- */
+
+ auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
+
+ if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
+ config.set(sf_hint);
+ else if (lcaps.get(kSamplingFrequency44100) &&
+ rcaps.get(kSamplingFrequency44100))
+ config.set(kSamplingFrequency44100);
+ else if (lcaps.get(kSamplingFrequency48000) &&
+ rcaps.get(kSamplingFrequency48000))
+ config.set(kSamplingFrequency48000);
+ else
+ return false;
+
+ /* --- Select Channel Mode --- */
+
+ auto cm_hint = hint ? GetChannelModeBit(hint->channelMode) : -1;
+
+ if (cm_hint >= 0 && lcaps.get(cm_hint) && rcaps.get(cm_hint))
+ config.set(cm_hint);
+ else if (lcaps.get(kChannelModeJointStereo) &&
+ rcaps.get(kChannelModeJointStereo))
+ config.set(kChannelModeJointStereo);
+ else if (lcaps.get(kChannelModeStereo) && rcaps.get(kChannelModeStereo))
+ config.set(kChannelModeStereo);
+ else if (lcaps.get(kChannelModeDualChannel) &&
+ rcaps.get(kChannelModeDualChannel))
+ config.set(kChannelModeDualChannel);
+ else if (lcaps.get(kChannelModeMono) && rcaps.get(kChannelModeMono))
+ config.set(kChannelModeMono);
+ else
+ return false;
+
+ /* --- Select Block Length --- */
+
+ if (lcaps.get(kBlockLength16) && rcaps.get(kBlockLength16))
+ config.set(kBlockLength16);
+ else if (lcaps.get(kBlockLength12) && rcaps.get(kBlockLength12))
+ config.set(kBlockLength12);
+ else if (lcaps.get(kBlockLength8) && rcaps.get(kBlockLength8))
+ config.set(kBlockLength8);
+ else if (lcaps.get(kBlockLength4) && rcaps.get(kBlockLength4))
+ config.set(kBlockLength4);
+ else
+ return false;
+
+ /* --- Select Subbands --- */
+
+ if (lcaps.get(kSubbands8) && rcaps.get(kSubbands8))
+ config.set(kSubbands8);
+ else if (lcaps.get(kSubbands4) && rcaps.get(kSubbands4))
+ config.set(kSubbands4);
+ else
+ return false;
+
+ /* --- Select Allocation method --- */
+
+ if (lcaps.get(kAllocationMethodLoudness) &&
+ rcaps.get(kAllocationMethodLoudness))
+ config.set(kAllocationMethodLoudness);
+ else if (lcaps.get(kAllocationMethodSnr) && rcaps.get(kAllocationMethodSnr))
+ config.set(kAllocationMethodSnr);
+ else
+ return false;
+
+ /* --- Select Bitpool --- */
+
+ uint8_t min_bitpool = rcaps.get(kMinimumBitpool);
+ uint8_t max_bitpool = rcaps.get(kMaximumBitpool);
+
+ if (min_bitpool < 2 || min_bitpool > 250 || max_bitpool < 2 ||
+ max_bitpool > 250 || min_bitpool > max_bitpool) {
+ min_bitpool = 2;
+ max_bitpool = 250;
+ }
+
+ min_bitpool = std::max(min_bitpool, uint8_t(lcaps.get(kMinimumBitpool)));
+ max_bitpool = std::max(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
+
+ if (hint) {
+ min_bitpool =
+ std::max(min_bitpool, GetBitpool(*configuration, hint->minBitrate));
+ if (hint->maxBitrate && hint->maxBitrate >= hint->minBitrate)
+ max_bitpool =
+ std::min(max_bitpool, GetBitpool(*configuration, hint->maxBitrate));
+ }
+
+ config.set(kMinimumBitpool, min_bitpool);
+ config.set(kMaximumBitpool, max_bitpool);
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h
new file mode 100644
index 0000000..c380850
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+struct SbcParameters : public CodecParameters {
+ enum class AllocationMethod { SNR, LOUDNESS };
+
+ AllocationMethod allocation_method;
+ int block_length;
+ int subbands;
+ int min_bitpool;
+ int max_bitpool;
+};
+
+class A2dpOffloadCodecSbc : public A2dpOffloadCodec {
+ CodecInfo info_;
+
+ A2dpOffloadCodecSbc();
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters,
+ SbcParameters* sbc_parameters) const;
+
+ public:
+ static const A2dpOffloadCodecSbc* GetInstance();
+
+ A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const override {
+ return ParseConfiguration(configuration, codec_parameters, nullptr);
+ }
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ SbcParameters* sbc_parameters) const {
+ return ParseConfiguration(configuration, sbc_parameters, sbc_parameters);
+ }
+
+ bool BuildConfiguration(const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index 40aea32..69db1b3 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -18,8 +18,13 @@
"BluetoothAudioProvider.cpp",
"BluetoothAudioProviderFactory.cpp",
"A2dpOffloadAudioProvider.cpp",
+ "A2dpOffloadCodecAac.cpp",
+ "A2dpOffloadCodecFactory.cpp",
+ "A2dpOffloadCodecSbc.cpp",
"A2dpSoftwareAudioProvider.cpp",
"HearingAidAudioProvider.cpp",
+ "HfpOffloadAudioProvider.cpp",
+ "HfpSoftwareAudioProvider.cpp",
"LeAudioOffloadAudioProvider.cpp",
"LeAudioSoftwareAudioProvider.cpp",
"service.cpp",
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index f9b18f8..b88e66a 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -21,6 +21,8 @@
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
+#include "A2dpOffloadCodecFactory.h"
+
namespace aidl {
namespace android {
namespace hardware {
@@ -164,6 +166,27 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioProvider::parseA2dpConfiguration(
+ [[maybe_unused]] const CodecId& codec_id,
+ [[maybe_unused]] const std::vector<uint8_t>& configuration,
+ [[maybe_unused]] CodecParameters* codec_parameters,
+ [[maybe_unused]] A2dpStatus* _aidl_return) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " is illegal";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::getA2dpConfiguration(
+ [[maybe_unused]] const std::vector<A2dpRemoteCapabilities>&
+ remote_a2dp_capabilities,
+ [[maybe_unused]] const A2dpConfigurationHint& hint,
+ [[maybe_unused]] std::optional<audio::A2dpConfiguration>* _aidl_return) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " is illegal";
+
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index b6e07a1..27ab13f 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -50,6 +50,14 @@
const AudioConfiguration& audio_config);
ndk::ScopedAStatus setLowLatencyModeAllowed(bool allowed);
+ ndk::ScopedAStatus parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return);
+ ndk::ScopedAStatus getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return);
+
virtual bool isValid(const SessionType& sessionType) = 0;
protected:
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 7e928e9..3a64c4d 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -22,9 +22,12 @@
#include <android-base/logging.h>
#include "A2dpOffloadAudioProvider.h"
+#include "A2dpOffloadCodecFactory.h"
#include "A2dpSoftwareAudioProvider.h"
#include "BluetoothAudioProvider.h"
#include "HearingAidAudioProvider.h"
+#include "HfpOffloadAudioProvider.h"
+#include "HfpSoftwareAudioProvider.h"
#include "LeAudioOffloadAudioProvider.h"
#include "LeAudioSoftwareAudioProvider.h"
@@ -78,6 +81,15 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
provider = ndk::SharedRefBase::make<A2dpOffloadDecodingAudioProvider>();
break;
+ case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpSoftwareOutputAudioProvider>();
+ break;
+ case SessionType::HFP_SOFTWARE_DECODING_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpSoftwareInputAudioProvider>();
+ break;
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpOffloadAudioProvider>();
+ break;
default:
provider = nullptr;
break;
@@ -139,7 +151,14 @@
SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
*_aidl_return = std::nullopt;
- (void)session_type;
+ if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ auto& provider_info = _aidl_return->emplace();
+
+ provider_info.name = A2dpOffloadCodecFactory::GetInstance()->name;
+ for (auto codec : A2dpOffloadCodecFactory::GetInstance()->codecs)
+ provider_info.codecInfos.push_back(codec->info);
+ }
return ndk::ScopedAStatus::ok();
}
diff --git a/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp
new file mode 100644
index 0000000..7196bb6
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHfpHW"
+
+#include "HfpOffloadAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+HfpOffloadAudioProvider::HfpOffloadAudioProvider() {
+ session_type_ = SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
+}
+
+bool HfpOffloadAudioProvider::isValid(const SessionType& session_type) {
+ return (session_type == session_type_);
+}
+
+ndk::ScopedAStatus HfpOffloadAudioProvider::startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
+}
+
+ndk::ScopedAStatus HfpOffloadAudioProvider::onSessionReady(
+ DataMQDesc* _aidl_return) {
+ *_aidl_return = DataMQDesc();
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h
new file mode 100644
index 0000000..5526b46
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HfpOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+ HfpOffloadAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+
+ ndk::ScopedAStatus startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+
+ private:
+ ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp
new file mode 100644
index 0000000..0f96046
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHfpSW"
+
+#include "HfpSoftwareAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static constexpr uint32_t kBufferCount = 2; // two frame buffer
+
+HfpSoftwareOutputAudioProvider::HfpSoftwareOutputAudioProvider()
+ : HfpSoftwareAudioProvider() {
+ session_type_ = SessionType::HFP_SOFTWARE_ENCODING_DATAPATH;
+}
+
+HfpSoftwareInputAudioProvider::HfpSoftwareInputAudioProvider()
+ : HfpSoftwareAudioProvider() {
+ session_type_ = SessionType::HFP_SOFTWARE_DECODING_DATAPATH;
+}
+
+HfpSoftwareAudioProvider::HfpSoftwareAudioProvider()
+ : BluetoothAudioProvider(), data_mq_(nullptr) {
+}
+
+bool HfpSoftwareAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_);
+}
+
+ndk::ScopedAStatus HfpSoftwareAudioProvider::startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ const PcmConfiguration& pcm_config =
+ audio_config.get<AudioConfiguration::pcmConfig>();
+ if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) {
+ LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+ << pcm_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ bool isValidConfig = true;
+
+ if (pcm_config.bitsPerSample != 16) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.sampleRateHz != 8000 && pcm_config.sampleRateHz != 16000 &&
+ pcm_config.sampleRateHz != 32000) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.channelMode != ChannelMode::MONO) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.dataIntervalUs != 7500) {
+ isValidConfig = false;
+ }
+
+ int bytes_per_sample = pcm_config.bitsPerSample / 8;
+
+ uint32_t data_mq_size = kBufferCount * bytes_per_sample *
+ (pcm_config.sampleRateHz / 1000) *
+ pcm_config.dataIntervalUs / 1000;
+ if (!isValidConfig) {
+ LOG(ERROR) << __func__ << "Unexpected audio buffer size: " << data_mq_size
+ << ", SampleRateHz: " << pcm_config.sampleRateHz
+ << ", ChannelMode: " << toString(pcm_config.channelMode)
+ << ", BitsPerSample: "
+ << static_cast<int>(pcm_config.bitsPerSample)
+ << ", BytesPerSample: " << bytes_per_sample
+ << ", DataIntervalUs: " << pcm_config.dataIntervalUs
+ << ", SessionType: " << toString(session_type_);
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size
+ << " byte(s)";
+
+ std::unique_ptr<DataMQ> temp_data_mq(
+ new DataMQ(data_mq_size, /* EventFlag */ true));
+ if (temp_data_mq == nullptr || !temp_data_mq->isValid()) {
+ ALOGE_IF(!temp_data_mq, "failed to allocate data MQ");
+ ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid");
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ data_mq_ = std::move(temp_data_mq);
+
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
+}
+
+ndk::ScopedAStatus HfpSoftwareAudioProvider::onSessionReady(
+ DataMQDesc* _aidl_return) {
+ if (data_mq_ == nullptr || !data_mq_->isValid()) {
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ *_aidl_return = data_mq_->dupeDesc();
+ auto desc = data_mq_->dupeDesc();
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, &desc, *audio_config_, latency_modes_);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h
new file mode 100644
index 0000000..ef51065
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HfpSoftwareAudioProvider : public BluetoothAudioProvider {
+ public:
+ HfpSoftwareAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+
+ ndk::ScopedAStatus startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+
+ private:
+ // audio data queue for software encoding
+ std::unique_ptr<DataMQ> data_mq_;
+
+ ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+class HfpSoftwareOutputAudioProvider : public HfpSoftwareAudioProvider {
+ public:
+ HfpSoftwareOutputAudioProvider();
+};
+
+class HfpSoftwareInputAudioProvider : public HfpSoftwareAudioProvider {
+ public:
+ HfpSoftwareInputAudioProvider();
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 40cd821..17be7be 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -33,6 +33,11 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::A2dpConfiguration;
+using aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint;
+using aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities;
+using aidl::android::hardware::bluetooth::audio::A2dpStatus;
+using aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration;
using aidl::android::hardware::bluetooth::audio::AacCapabilities;
using aidl::android::hardware::bluetooth::audio::AacConfiguration;
using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
@@ -48,7 +53,9 @@
using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
using aidl::android::hardware::bluetooth::audio::CodecId;
using aidl::android::hardware::bluetooth::audio::CodecInfo;
+using aidl::android::hardware::bluetooth::audio::CodecParameters;
using aidl::android::hardware::bluetooth::audio::CodecType;
+using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
@@ -92,6 +99,13 @@
static constexpr ChannelMode a2dp_channel_modes[] = {
ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
+
+// Some valid configs for HFP PCM configuration (software sessions)
+static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
+static constexpr int8_t hfp_bits_per_samples_[] = {16};
+static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
+static constexpr int32_t hfp_data_interval_us_[] = {7500};
+
// Helpers
template <typename T>
@@ -197,7 +211,8 @@
case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
- case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
+ case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
+ case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
// All software paths are mandatory and must have exact 1
// "PcmParameters"
ASSERT_EQ(temp_provider_capabilities_.size(), 1);
@@ -258,7 +273,8 @@
AudioCapabilities::leAudioCapabilities);
}
} break;
- case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: {
+ case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
+ case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
if (!temp_provider_capabilities_.empty()) {
ASSERT_EQ(temp_provider_capabilities_.size(), 1);
ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
@@ -298,7 +314,10 @@
LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type ==
SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
- session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
+ session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
+ session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
+ session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
ASSERT_EQ(audio_provider_, nullptr);
}
}
@@ -575,6 +594,8 @@
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
};
};
@@ -692,6 +713,701 @@
}
}
+class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
+ protected:
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ a2dp_encoding_provider_info_{};
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ a2dp_decoding_provider_info_{};
+ std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
+ std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
+
+ public:
+ void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
+
+ (void)provider_factory_->getProviderInfo(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ &a2dp_encoding_provider_info_);
+
+ (void)provider_factory_->getProviderInfo(
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ &a2dp_decoding_provider_info_);
+
+ (void)provider_factory_->openProvider(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ &a2dp_encoding_provider_);
+
+ (void)provider_factory_->openProvider(
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ &a2dp_decoding_provider_);
+ }
+};
+
+/**
+ * Calling parseA2dpConfiguration on a session of a different type than
+ * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
+ static constexpr SessionType kInvalidSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ // Open a BluetoothAudioProvider instance of the selected session type.
+ // Skip validation if the provider cannot be opened.
+ std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
+ (void)provider_factory_->openProvider(session_type, &provider);
+ if (provider == nullptr) {
+ continue;
+ }
+
+ // parseA2dpConfiguration must fail without returning an A2dpStatus.
+ CodecId codec_id(CodecId::A2dp::SBC);
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ auto aidl_retval = provider->parseA2dpConfiguration(
+ codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with an unknown codec must fail
+ * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ parseA2dpConfiguration_unsupportedCodecType) {
+ CodecId unsupported_core_id(CodecId::Core::CVSD);
+ CodecId unsupported_vendor_id(
+ CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
+
+ for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
+ if (provider == nullptr) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with two invalid codec identifiers: vendor or core.
+ aidl_retval = provider->parseA2dpConfiguration(
+ unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
+ &a2dp_status);
+ EXPECT_TRUE(!aidl_retval.isOk() ||
+ a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
+
+ aidl_retval = provider->parseA2dpConfiguration(
+ unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
+ &a2dp_status);
+ EXPECT_TRUE(!aidl_retval.isOk() ||
+ a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with a known codec and invalid configuration
+ * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
+ * NOT_SUPPORTED_CODEC_TYPE.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ parseA2dpConfiguration_invalidConfiguration) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with the first available codec in the provider info for testing.
+ // The test runs with an empty parameters array, anything more specific
+ // would need understanding the codec.
+ aidl_retval = provider->parseA2dpConfiguration(
+ provider_info->codecInfos[0].id, std::vector<uint8_t>{},
+ &codec_parameters, &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
+ a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
+ a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with a known codec and valid parameters
+ * must return with A2dpStatus OK.
+ */
+TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ transport.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ aidl_retval = provider->parseA2dpConfiguration(
+ configuration->id, configuration->configuration, &codec_parameters,
+ &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
+ EXPECT_EQ(codec_parameters, configuration->parameters);
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration on a session of a different type than
+ * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
+ static constexpr SessionType kInvalidSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ // Open a BluetoothAudioProvider instance of the selected session type.
+ // Skip validation if the provider cannot be opened.
+ std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
+ auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
+ if (provider == nullptr) {
+ continue;
+ }
+
+ // getA2dpConfiguration must fail without returning a configuration.
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval =
+ provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
+ A2dpConfigurationHint(), &configuration);
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with empty or unknown remote capabilities
+ * must return an empty configuration.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_unknownRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ std::optional<A2dpConfiguration> configuration;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with empty remote capabilities.
+ aidl_retval =
+ provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+
+ // Test with unknown remote capabilities.
+ A2dpRemoteCapabilities unknown_core_remote_capabilities(
+ /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
+ A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
+ /*seid*/ 1,
+ /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
+ std::vector<uint8_t>{1, 2, 3});
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ unknown_core_remote_capabilities,
+ unknown_vendor_remote_capabilities,
+ },
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with invalid remote capabilities
+ * must return an empty configuration.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_invalidRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ std::optional<A2dpConfiguration> configuration;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Use the first available codec in the provider info for testing.
+ // The capabilities are modified to make them invalid.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::vector<uint8_t> invalid_capabilities = transport.capabilities;
+ invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
+ std::vector<uint8_t>()),
+ A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
+ invalid_capabilities),
+ },
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * must return a valid configuration. The selected parameters must
+ * be contained in the original capabilities. The returned configuration
+ * must match the returned parameters. The returned SEID must match the
+ * input SEID.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_validRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ A2dpConfigurationHint(), &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Returned configuration must have the same codec id
+ // as the remote capability.
+ EXPECT_EQ(configuration->id, codec_info.id);
+
+ // Returned configuration must have the same SEID
+ // as the remote capability.
+ EXPECT_EQ(configuration->remoteSeid, 42);
+
+ // Returned codec parameters must be in the range of input
+ // parameters.
+ EXPECT_NE(
+ std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
+ configuration->parameters.channelMode),
+ a2dp_info.channelMode.end());
+ EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
+ a2dp_info.samplingFrequencyHz.end(),
+ configuration->parameters.samplingFrequencyHz),
+ a2dp_info.samplingFrequencyHz.end());
+ EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
+ configuration->parameters.bitdepth),
+ a2dp_info.bitdepth.end());
+ EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
+ EXPECT_TRUE(configuration->parameters.minBitrate <=
+ configuration->parameters.maxBitrate);
+
+ // Returned configuration must be parsable by parseA2dpParameters
+ // and match the codec parameters.
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ aidl_retval = provider->parseA2dpConfiguration(
+ configuration->id, configuration->configuration, &codec_parameters,
+ &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
+ EXPECT_EQ(codec_parameters, configuration->parameters);
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted codec ids.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Build the remote capabilities with all supported codecs.
+ std::vector<A2dpRemoteCapabilities> remote_capabilities;
+ for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
+ auto const& codec_info = provider_info->codecInfos[n];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ remote_capabilities.push_back(A2dpRemoteCapabilities(
+ /*seid*/ n, codec_info.id, a2dp_info.capabilities));
+ }
+
+ // Test with all supported codec identifiers,
+ for (auto const& codec_info : provider_info->codecInfos) {
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ A2dpConfigurationHint hint;
+ hint.codecId = codec_info.id;
+
+ aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
+ &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+ EXPECT_EQ(configuration->id, codec_info.id);
+ }
+
+ // Test with unknown codec identifiers: either core or vendor.
+ for (auto& codec_id :
+ {CodecId(CodecId::Core::CVSD),
+ CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ A2dpConfigurationHint hint;
+ hint.codecId = codec_id;
+
+ aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
+ &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+ EXPECT_NE(configuration->id, codec_id);
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted channel modes.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& channel_mode :
+ {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
+ // Add the hint for the channel mode.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.channelMode = channel_mode;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the channel mode is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
+ std::find(a2dp_info.channelMode.begin(),
+ a2dp_info.channelMode.end(),
+ channel_mode) != a2dp_info.channelMode.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted sampling frequencies.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_hintSamplingFrequencyHz) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& sampling_frequency_hz : {
+ 0,
+ 1,
+ 8000,
+ 16000,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+ }) {
+ // Add the hint for the sampling frequency.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the sampling frequency is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
+ sampling_frequency_hz,
+ std::find(a2dp_info.samplingFrequencyHz.begin(),
+ a2dp_info.samplingFrequencyHz.end(),
+ sampling_frequency_hz) !=
+ a2dp_info.samplingFrequencyHz.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted sampling bit-depths.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& bitdepth : {0, 1, 16, 24, 32}) {
+ // Add the hint for the bit depth.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.bitdepth = bitdepth;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the bitdepth is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(
+ configuration->parameters.bitdepth == bitdepth,
+ std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
+ bitdepth) != a2dp_info.bitdepth.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling startSession with an unknown codec id must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ for (auto& codec_id :
+ {CodecId(CodecId::Core::CVSD),
+ CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_id;
+ a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
+
+ auto aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+ }
+}
+
+/**
+ * Calling startSession with a known codec and a valid configuration
+ * must succeed.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Use the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ ::ndk::ScopedAStatus aidl_retval;
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ a2dp_info.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Build the stream configuration.
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_info.id;
+ a2dp_config.configuration = configuration->configuration;
+
+ aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_TRUE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling startSession with a known codec but an invalid configuration
+ * must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Use the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ ::ndk::ScopedAStatus aidl_retval;
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ a2dp_info.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Build the stream configuration but edit the configuration bytes
+ // to make it invalid.
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_info.id;
+ a2dp_config.configuration = configuration->configuration;
+ a2dp_config.configuration.push_back(42);
+
+ aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
/**
* openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
*/
@@ -751,6 +1467,137 @@
}
/**
+ * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderHfpSoftwareEncodingAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
+ ChannelMode channel_mode, int32_t data_interval_us) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample,
+ .dataIntervalUs = data_interval_us,
+ };
+ // Checking against provider capability from getProviderCapabilities
+ // For HFP software, it's
+ // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ if (!aidl_retval.isOk()) return false;
+ if (!data_mq.isValid()) return false;
+ return true;
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ OpenHfpSoftwareEncodingProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : hfp_sample_rates_) {
+ for (auto bits_per_sample : hfp_bits_per_samples_) {
+ for (auto channel_mode : hfp_channel_modes_) {
+ for (auto data_interval_us: hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
+ channel_mode, data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
+ * openProvider HFP_SOFTWARE_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderHfpSoftwareDecodingAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
+ OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
+ ChannelMode channel_mode, int32_t data_interval_us) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample,
+ .dataIntervalUs = data_interval_us,
+ };
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ if (!aidl_retval.isOk()) return false;
+ if (!data_mq.isValid()) return false;
+ return true;
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ OpenHfpSoftwareDecodingProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : hfp_sample_rates_) {
+ for (auto bits_per_sample : hfp_bits_per_samples_) {
+ for (auto channel_mode : hfp_channel_modes_) {
+ for (auto data_interval_us: hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
+ channel_mode, data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
* openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
*/
class BluetoothAudioProviderA2dpEncodingHardwareAidl
@@ -1003,6 +1850,62 @@
}
/**
+ * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
+ */
+class BluetoothAudioProviderHfpHardwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
+ // Can open or empty capability
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
+ bool controller_codec) {
+ // Check if can open session with a Hfp configuration
+ HfpConfiguration hfp_configuration{
+ .codecId = codec_id,
+ .connectionHandle = connection_handle,
+ .nrec = nrec,
+ .controllerCodec = controller_codec,
+ };
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
+ &mq_desc);
+
+ // Only check if aidl is ok to start session.
+ return aidl_retval.isOk();
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different HFP config
+ */
+TEST_P(BluetoothAudioProviderHfpHardwareAidl,
+ StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
+ // Try to open with a sample configuration
+ EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+}
+
+/**
* openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
*/
class BluetoothAudioProviderHearingAidSoftwareAidl
@@ -2191,6 +3094,12 @@
IBluetoothAudioProviderFactory::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
BluetoothAudioProviderA2dpEncodingSoftwareAidl);
INSTANTIATE_TEST_SUITE_P(PerInstance,
@@ -2279,6 +3188,29 @@
IBluetoothAudioProviderFactory::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpSoftwareDecodingAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpSoftwareEncodingAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index b4cba49..6e15b3b 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -41,7 +41,7 @@
namespace audio {
static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
- .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
+ .sampleRateHz = {8000, 16000, 24000, 32000, 44100, 48000, 88200, 96000},
.channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
.bitsPerSample = {16, 24, 32},
.dataIntervalUs = {},
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index c283148..3519ace 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -95,6 +95,8 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(CodecConfiguration{});
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ return AudioConfiguration(HfpConfiguration{});
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
@@ -154,6 +156,7 @@
session_type_ ==
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
(data_mq_ != nullptr && data_mq_->isValid()));
return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
}
@@ -275,6 +278,8 @@
bool is_software_session =
(session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
session_type_ ==
@@ -283,6 +288,8 @@
bool is_offload_a2dp_session =
(session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ bool is_offload_hfp_session =
+ session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
bool is_offload_le_audio_unicast_session =
(session_type_ ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
@@ -297,7 +304,11 @@
audio_config_tag == AudioConfiguration::pcmConfig);
bool is_a2dp_offload_audio_config =
(is_offload_a2dp_session &&
- audio_config_tag == AudioConfiguration::a2dpConfig);
+ (audio_config_tag == AudioConfiguration::a2dp ||
+ audio_config_tag == AudioConfiguration::a2dpConfig));
+ bool is_hfp_offload_audio_config =
+ (is_offload_hfp_session &&
+ audio_config_tag == AudioConfiguration::hfpConfig);
bool is_le_audio_offload_unicast_audio_config =
(is_offload_le_audio_unicast_session &&
audio_config_tag == AudioConfiguration::leAudioConfig);
@@ -305,6 +316,7 @@
(is_offload_le_audio_broadcast_session &&
audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
+ !is_hfp_offload_audio_config &&
!is_le_audio_offload_unicast_audio_config &&
!is_le_audio_offload_broadcast_audio_config) {
return false;
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
index 7ae0353..5263222 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -84,6 +84,8 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(CodecConfiguration{});
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ return AudioConfiguration(HfpConfiguration{});
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
index 3d92ee7..fd12a6e 100644
--- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
@@ -467,6 +467,8 @@
hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
audio_config.get<AudioConfiguration::a2dpConfig>()));
break;
+ case AudioConfiguration::a2dp:
+ break;
case AudioConfiguration::leAudioConfig:
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1(
audio_config.get<AudioConfiguration::leAudioConfig>()));
@@ -475,6 +477,8 @@
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_broadcast_config_2_1(
audio_config.get<AudioConfiguration::leAudioBroadcastConfig>()));
break;
+ default:
+ LOG(FATAL) << __func__ << ": unexpected AudioConfiguration";
}
return hidl_audio_config;
}
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
index fea07f0..64bbf09 100644
--- a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
@@ -1,4 +1,4 @@
-service vendor.bluetooth.finder-default /vendor/bin/hw/android.hardware.bluetooth.finder.default
+service vendor.bluetooth.finder-default /vendor/bin/hw/android.hardware.bluetooth.finder-service.default
class hal
capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
user bluetooth
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 72869cc..79d3e60 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -702,6 +702,59 @@
}
/**
+ * Test tuning with HD selector.
+ *
+ * Verifies that:
+ * - if AM/FM HD selector is not supported, the method returns NOT_SUPPORTED;
+ * - if it is supported, the method succeeds;
+ * - after a successful tune call, onCurrentProgramInfoChanged callback is
+ * invoked carrying a proper selector;
+ * - program changes to a program info with the program selector requested.
+ */
+TEST_P(BroadcastRadioHalTest, HdTune) {
+ LOG(DEBUG) << "HdTune Test";
+ auto programList = getProgramList();
+ if (!programList) {
+ printSkipped("Empty station list, tune cannot be performed");
+ return;
+ }
+ ProgramSelector hdSel = {};
+ ProgramIdentifier physicallyTunedToExpected = {};
+ bool hdStationPresent = false;
+ for (auto&& programInfo : *programList) {
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ continue;
+ }
+ hdSel = programInfo.selector;
+ hdStationPresent = true;
+ physicallyTunedToExpected = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ bcutils::getAmFmFrequency(hdSel));
+ break;
+ }
+ if (!hdStationPresent) {
+ printSkipped("No HD stations in the list, tune cannot be performed");
+ return;
+ }
+
+ // try tuning
+ auto result = mModule->tune(hdSel);
+
+ // expect a failure if it's not supported
+ if (!bcutils::isSupported(mProperties, hdSel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+ return;
+ }
+ // expect a callback if it succeeds
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
+ LOG(DEBUG) << "Current program info: " << infoCb.toString();
+ // it should tune exactly to what was requested
+ EXPECT_EQ(infoCb.selector, hdSel);
+ EXPECT_EQ(infoCb.physicallyTunedTo, physicallyTunedToExpected);
+}
+
+/**
* Test tuning with DAB selector.
*
* Verifies that:
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
index 903ef60..f73483a 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
@@ -45,4 +45,5 @@
int getTorchStrengthLevel();
android.hardware.camera.device.CameraMetadata constructDefaultRequestSettings(in android.hardware.camera.device.RequestTemplate type);
boolean isStreamCombinationWithSettingsSupported(in android.hardware.camera.device.StreamConfiguration streams);
+ android.hardware.camera.device.CameraMetadata getSessionCharacteristics(in android.hardware.camera.device.StreamConfiguration sessionConfig);
}
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index a2bdd59..3a1d762 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -435,4 +435,34 @@
*
*/
boolean isStreamCombinationWithSettingsSupported(in StreamConfiguration streams);
+
+ /**
+ * getSessionCharacteristics
+ *
+ * Gets the session characteristics associated with a particular session
+ * configuration by the CameraDevice.
+ *
+ * For Android 15, the characteristics which need to be set are:
+ * - ANDROID_CONTROL_ZOOM_RATIO_RANGE
+ *
+ * A service specific error will be returned on the following conditions
+ * INTERNAL_ERROR:
+ * The camera device cannot be opened due to an internal
+ * error.
+ * CAMERA_DISCONNECTED:
+ * An external camera device has been disconnected, and is no longer
+ * available. This camera device interface is now stale, and a new
+ * instance must be acquired if the device is reconnected. All
+ * subsequent calls on this interface must return
+ * CAMERA_DISCONNECTED.
+ * ILLEGAL_ARGUMENT:
+ * If the given session configuration is not supported.
+ *
+ * @param sessionConfig: The session configuration for which the
+ * characteristics are being fetched.
+ *
+ * @return The static metadata for this particular session config, or an
+ * empty metadata structure if a service specific error is returned.
+ */
+ CameraMetadata getSessionCharacteristics(in StreamConfiguration sessionConfig);
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index b04e486..542b296 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -98,6 +98,8 @@
ANDROID_CONTROL_AUTOFRAMING,
ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
ANDROID_CONTROL_AUTOFRAMING_STATE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
ANDROID_EDGE_STRENGTH,
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
index 5e1b871..c1423aa 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -44,4 +44,5 @@
ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
new file mode 100644
index 0000000..f8ae013
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlLowLightBoostState {
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 2fefce0..03cfba1 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -490,6 +490,18 @@
*/
ANDROID_CONTROL_AUTOFRAMING_STATE,
/**
+ * android.control.lowLightBoostInfoLuminanceRange [static, float[], public]
+ *
+ * <p>The operating luminance range of low light boost measured in lux (lx).</p>
+ */
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
+ /**
+ * android.control.lowLightBoostState [dynamic, enum, public]
+ *
+ * <p>Current state of the low light boost AE mode.</p>
+ */
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
+ /**
* android.demosaic.mode [controls, enum, system]
*
* <p>Controls the quality of the demosaicing
@@ -2331,7 +2343,8 @@
*
* <p>Whether this camera device can support identical set of stream combinations
* involving HEIC image format, compared to the
- * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#legacy-level-guaranteed-configurations">table of combinations</a> involving JPEG image format required for the device's hardware
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#legacy-level-guaranteed-configurations">table of combinations</a>
+ * involving JPEG image format required for the device's hardware
* level and capabilities.</p>
*/
ANDROID_HEIC_INFO_SUPPORTED = CameraMetadataSectionStart.ANDROID_HEIC_INFO_START,
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
index e2f5553..70174be 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -35,4 +35,5 @@
ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
new file mode 100644
index 0000000..67591c8
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.lowLightBoostState enumeration values
+ * @see ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlLowLightBoostState {
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE,
+}
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 33e5a7d..0b6f112 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -134,7 +134,7 @@
</hal>
<hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.biometrics.fingerprint</name>
- <version>3</version>
+ <version>3-4</version>
<interface>
<name>IFingerprint</name>
<instance>default</instance>
@@ -577,7 +577,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.thermal</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IThermal</name>
<instance>default</instance>
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
index d0099ff..4e99082 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
@@ -40,5 +40,6 @@
void handleTransactionResult(in int transactionId, in boolean success);
void handleNanSessionRequest(in android.hardware.contexthub.NanSessionRequest request);
byte[16] getUuid();
+ String getName();
const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
}
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
index 41fb266..ebfc4d8 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
@@ -92,13 +92,21 @@
/**
* This callback is passed to the HAL implementation to allow the HAL to request a UUID that
- * uniquely identifies an IContextHubCallback.
+ * uniquely identifies a client.
*
* @return a byte array representating the UUID
*/
byte[16] getUuid();
/**
+ * This callback gets the name of a client implementing this IContextHubCallback interface,
+ * which must be a hard-coded string and does not change at runtime.
+ *
+ * <p>The name provides a human-readable way to identify a client for troubleshooting purpose.
+ */
+ String getName();
+
+ /**
* Amount of time, in milliseconds, that a handleNanSessionRequest can be pending before the
* Contexthub service must respond.
*/
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index e780857..76b25b6 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -49,8 +49,9 @@
using ::android::hardware::contexthub::vts_utils::waitForCallback;
// 6612b522-b717-41c8-b48d-c0b1cc64e142
-const std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
- 0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+constexpr std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
+ 0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+const String16 kName{"VtsAidlHalContextHubTargetTest"};
class ContextHubAidl : public testing::TestWithParam<std::tuple<std::string, int32_t>> {
public:
@@ -135,6 +136,11 @@
*out_uuid = kUuid;
return Status::ok();
}
+
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
};
TEST_P(ContextHubAidl, TestRegisterCallback) {
@@ -171,6 +177,11 @@
return Status::ok();
}
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
+
std::promise<std::vector<NanoappInfo>> promise;
};
@@ -242,6 +253,11 @@
return Status::ok();
}
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
+
uint32_t expectedTransactionId = 0;
std::promise<bool> promise;
};
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
index 3161322..eedb8ed 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
@@ -35,18 +35,16 @@
/* @hide */
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ConnectionEvent {
- CS_SERVICE_GSM = 0,
- SIGNALLING_GSM = 1,
- PS_SERVICE_GPRS = 2,
- SIGNALLING_GPRS = 3,
- PS_SERVICE_3G = 4,
- SIGNALLING_3G = 5,
- NAS_SIGNALLING_LTE = 6,
- AS_SIGNALLING_LTE = 7,
- VOLTE_SIP = 8,
- VOLTE_RTP = 9,
- NAS_SIGNALLING_5G = 10,
- AS_SIGNALLING_5G = 11,
- VONR_SIP = 12,
- VONR_RTP = 13,
+ CS_SIGNALLING_GSM = 0,
+ PS_SIGNALLING_GPRS = 1,
+ CS_SIGNALLING_3G = 2,
+ PS_SIGNALLING_3G = 3,
+ NAS_SIGNALLING_LTE = 4,
+ AS_SIGNALLING_LTE = 5,
+ VOLTE_SIP = 6,
+ VOLTE_RTP = 7,
+ NAS_SIGNALLING_5G = 8,
+ AS_SIGNALLING_5G = 9,
+ VONR_SIP = 10,
+ VONR_RTP = 11,
}
diff --git a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
index 639ba89..2e39ebf 100644
--- a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
@@ -25,31 +25,31 @@
@Backing(type="int")
@JavaDerive(toString=true)
enum ConnectionEvent {
- // 2G GSM
- CS_SERVICE_GSM = 0,
- SIGNALLING_GSM = 1,
+ // 2G GSM circuit switched
+ CS_SIGNALLING_GSM = 0,
// 2G GPRS packet services
- PS_SERVICE_GPRS = 2,
- SIGNALLING_GPRS = 3,
+ PS_SIGNALLING_GPRS = 1,
- // 3G packet services
- PS_SERVICE_3G = 4,
- SIGNALLING_3G = 5,
+ // 3G circuit switched
+ CS_SIGNALLING_3G = 2,
+
+ // 3G packet switched
+ PS_SIGNALLING_3G = 3,
// 4G LTE packet services
- NAS_SIGNALLING_LTE = 6,
- AS_SIGNALLING_LTE = 7,
+ NAS_SIGNALLING_LTE = 4,
+ AS_SIGNALLING_LTE = 5,
// VoLTE
- VOLTE_SIP = 8,
- VOLTE_RTP = 9,
+ VOLTE_SIP = 6,
+ VOLTE_RTP = 7,
// 5G packet services
- NAS_SIGNALLING_5G = 10,
- AS_SIGNALLING_5G = 11,
+ NAS_SIGNALLING_5G = 8,
+ AS_SIGNALLING_5G = 9,
// VoNR
- VONR_SIP = 12,
- VONR_RTP = 13,
+ VONR_SIP = 10,
+ VONR_RTP = 11,
}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index a6ee2a6..32b246a 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -90,6 +90,11 @@
serial = GetRandomSerialNumber();
+ // get aidl version
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+
// save current value
radio_network->getAllowedNetworkTypesBitmap(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -125,6 +130,11 @@
RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ if (aidl_version < 2) {
+ radioRsp_network->networkTypeBitmapResponse
+ &= ~static_cast<int32_t>(RadioAccessFamily::LTE_CA);
+ }
+
// verify we get the value we set
EXPECT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
}
diff --git a/security/authgraph/aidl/Android.bp b/security/authgraph/aidl/Android.bp
index d94f640..f3d1281 100644
--- a/security/authgraph/aidl/Android.bp
+++ b/security/authgraph/aidl/Android.bp
@@ -34,7 +34,7 @@
platform_apis: true,
},
ndk: {
- apps_enabled: false,
+ enabled: true,
},
rust: {
enabled: true,
diff --git a/security/authgraph/aidl/vts/functional/lib.rs b/security/authgraph/aidl/vts/functional/lib.rs
index da3fa1c..f4c1da9 100644
--- a/security/authgraph/aidl/vts/functional/lib.rs
+++ b/security/authgraph/aidl/vts/functional/lib.rs
@@ -26,6 +26,7 @@
use authgraph_boringssl as boring;
use authgraph_core::{error::Error as AgError, keyexchange as ke};
use coset::CborSerializable;
+use std::{cell::RefCell, rc::Rc};
pub mod sink;
pub mod source;
@@ -34,7 +35,7 @@
pub fn test_ag_participant() -> Result<ke::AuthGraphParticipant, AgError> {
Ok(ke::AuthGraphParticipant::new(
boring::crypto_trait_impls(),
- Box::<boring::test_device::AgDevice>::default(),
+ Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
ke::MAX_OPENED_SESSIONS,
)?)
}
diff --git a/security/authgraph/default/src/fuzzer.rs b/security/authgraph/default/src/fuzzer.rs
index d401777..387d72f 100644
--- a/security/authgraph/default/src/fuzzer.rs
+++ b/security/authgraph/default/src/fuzzer.rs
@@ -22,10 +22,9 @@
use authgraph_nonsecure::LocalTa;
use binder_random_parcel_rs::fuzz_service;
use libfuzzer_sys::fuzz_target;
-use std::sync::{Arc, Mutex};
fuzz_target!(|data: &[u8]| {
let local_ta = LocalTa::new().expect("Failed to create an AuthGraph local TA.");
- let service = AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+ let service = AuthGraphService::new_as_binder(local_ta);
fuzz_service(&mut service.as_binder(), data);
});
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
index 14741aa..1f851b2 100644
--- a/security/authgraph/default/src/lib.rs
+++ b/security/authgraph/default/src/lib.rs
@@ -22,36 +22,62 @@
ta::{AuthGraphTa, Role},
};
use authgraph_hal::channel::SerializedChannel;
-use std::sync::{Arc, Mutex};
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::{mpsc, Mutex};
/// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore
/// insecure).
pub struct LocalTa {
- ta: Arc<Mutex<AuthGraphTa>>,
+ channels: Mutex<Channels>,
+}
+
+struct Channels {
+ in_tx: mpsc::Sender<Vec<u8>>,
+ out_rx: mpsc::Receiver<Vec<u8>>,
}
impl LocalTa {
/// Create a new instance.
pub fn new() -> Result<Self, error::Error> {
- Ok(Self {
- ta: Arc::new(Mutex::new(AuthGraphTa::new(
+ // Create a pair of channels to communicate with the TA thread.
+ let (in_tx, in_rx) = mpsc::channel();
+ let (out_tx, out_rx) = mpsc::channel();
+
+ // The TA code expects to run single threaded, so spawn a thread to run it in.
+ std::thread::spawn(move || {
+ let mut ta = AuthGraphTa::new(
keyexchange::AuthGraphParticipant::new(
boring::crypto_trait_impls(),
- Box::<boring::test_device::AgDevice>::default(),
+ Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
keyexchange::MAX_OPENED_SESSIONS,
- )?,
+ )
+ .expect("failed to create AG participant"),
Role::Both,
- ))),
+ );
+ // Loop forever processing request messages.
+ loop {
+ let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+ let rsp_data = ta.process(&req_data);
+ out_tx.send(rsp_data).expect("failed to send out rsp");
+ }
+ });
+ Ok(Self {
+ channels: Mutex::new(Channels { in_tx, out_rx }),
})
}
}
-/// Pretend to be a serialized channel to the TA, but actually just directly invoke the TA with
-/// incoming requests.
impl SerializedChannel for LocalTa {
const MAX_SIZE: usize = usize::MAX;
- fn execute(&mut self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
- Ok(self.ta.lock().unwrap().process(req_data))
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ // Serialize across both request and response.
+ let channels = self.channels.lock().unwrap();
+ channels
+ .in_tx
+ .send(req_data.to_vec())
+ .expect("failed to send in request");
+ Ok(channels.out_rx.recv().expect("failed to receive response"))
}
}
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index 81f2dd6..ced7567 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -25,7 +25,6 @@
use authgraph_hal::service;
use authgraph_nonsecure::LocalTa;
use log::{error, info};
-use std::sync::{Arc, Mutex};
static SERVICE_NAME: &str = "android.hardware.security.authgraph.IAuthGraphKeyExchange";
static SERVICE_INSTANCE: &str = "nonsecure";
@@ -65,9 +64,8 @@
binder::ProcessState::start_thread_pool();
// Register the service
- let local_ta =
- LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
- let service = service::AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+ let local_ta = LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
+ let service = service::AuthGraphService::new_as_binder(local_ta);
let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE);
binder::add_service(&service_name, service.as_binder()).map_err(|e| {
format!(
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 79189a1..3b02fad 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -130,7 +130,7 @@
* }
*/
JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name,
- const cppbor::Array& csr);
+ const cppbor::Array& csr, const std::string serialno_prop);
/**
* Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 6edbfc1..ecfdfd2 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -337,9 +337,9 @@
return result;
}
-JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name, const cppbor::Array& csr) {
+JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name, const cppbor::Array& csr,
+ const std::string serialno_prop) {
const std::string kFingerprintProp = "ro.build.fingerprint";
- const std::string kSerialNoProp = "ro.serialno";
if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
return JsonOutput::Error("Unable to read build fingerprint");
@@ -364,7 +364,7 @@
Json::Value json(Json::objectValue);
json["name"] = instance_name;
json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
- json["serialno"] = ::android::base::GetProperty(kSerialNoProp, /*default=*/"");
+ json["serialno"] = ::android::base::GetProperty(serialno_prop, /*default=*/"");
json["csr"] = base64.data(); // Boring writes a NUL-terminated c-string
Json::StreamWriterBuilder factory;
@@ -978,7 +978,7 @@
return hwtrust::DiceChain::Kind::kVsr13;
case __ANDROID_API_U__:
return hwtrust::DiceChain::Kind::kVsr14;
- case __ANDROID_API_V__:
+ case 202404: /* TODO(b/315056516) Use a version macro for vendor API 24Q2 */
return hwtrust::DiceChain::Kind::kVsr15;
default:
return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index eaaba45..630f7bb 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -182,10 +182,11 @@
}
TEST(RemoteProvUtilsTest, JsonEncodeCsr) {
+ const std::string kSerialNoProp = "ro.serialno";
cppbor::Array array;
array.add(1);
- auto [json, error] = jsonEncodeCsrWithBuild(std::string("test"), array);
+ auto [json, error] = jsonEncodeCsrWithBuild(std::string("test"), array, kSerialNoProp);
ASSERT_TRUE(error.empty()) << error;
diff --git a/security/secretkeeper/OWNERS b/security/secretkeeper/OWNERS
new file mode 100644
index 0000000..acf4c6c
--- /dev/null
+++ b/security/secretkeeper/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 867125
+
+alanstokes@google.com
+drysdale@google.com
+hasinitg@google.com
+shikhapanwar@google.com
diff --git a/security/secretkeeper/aidl/Android.bp b/security/secretkeeper/aidl/Android.bp
index c77d299..ac923ca 100644
--- a/security/secretkeeper/aidl/Android.bp
+++ b/security/secretkeeper/aidl/Android.bp
@@ -20,8 +20,15 @@
name: "android.hardware.security.secretkeeper",
vendor_available: true,
srcs: ["android/hardware/security/secretkeeper/*.aidl"],
+ imports: [
+ "android.hardware.security.authgraph-V1",
+ ],
stability: "vintf",
+ frozen: false,
backend: {
+ java: {
+ enabled: false,
+ },
ndk: {
enabled: true,
},
@@ -34,3 +41,44 @@
},
},
}
+
+// cc_defaults that includes the latest Secretkeeper AIDL library.
+// Modules that depend on Secretkeeper directly can include this cc_defaults to avoid
+// managing dependency versions explicitly.
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_ndk_static",
+ static_libs: [
+ "android.hardware.security.secretkeeper-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_ndk_shared",
+ shared_libs: [
+ "android.hardware.security.secretkeeper-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_cpp_static",
+ static_libs: [
+ "android.hardware.security.secretkeeper-V1-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_cpp_shared",
+ shared_libs: [
+ "android.hardware.security.secretkeeper-V1-cpp",
+ ],
+}
+
+// A rust_defaults that includes the latest Secretkeeper AIDL library.
+// Modules that depend on Secretkeeper directly can include this rust_defaults to avoid
+// managing dependency versions explicitly.
+rust_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_rust",
+ rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ ],
+}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index 2eb33c5..023fc8f 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -34,5 +34,6 @@
package android.hardware.security.secretkeeper;
@VintfStability
interface ISecretkeeper {
+ android.hardware.security.authgraph.IAuthGraphKeyExchange getAuthGraphKe();
byte[] processSecretManagementRequest(in byte[] request);
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index af715a9..1f4768a 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -16,6 +16,8 @@
package android.hardware.security.secretkeeper;
+import android.hardware.security.authgraph.IAuthGraphKeyExchange;
+
@VintfStability
/**
* Secretkeeper service definition.
@@ -29,17 +31,22 @@
* - A completely separate, purpose-built and certified secure CPU.
*
* TODO(b/291224769): Extend the HAL interface to include:
- * 1. Session setup api: This is used to perform cryptographic operations that allow shared keys to
- * be exchanged between session participants, typically (but not necessarily) a pVM instance and
- * Secretkeeper. This session setup is based on public key cryptography.
- * 2. Dice policy operation - These allow sealing of the secrets with a class of Dice chains.
+ * 1. Dice policy operation - These allow sealing of the secrets with a class of Dice chains.
* Typical operations are (securely) updating the dice policy sealing the Secrets above. These
* operations are core to AntiRollback protected secrets - ie, ensuring secrets of a pVM are only
* accessible to same or higher versions of the images.
- * 3. Maintenance api: This is required for removing the Secretkeeper entries for obsolete pvMs.
+ * 2. Maintenance api: This is required for removing the Secretkeeper entries for obsolete pvMs.
*/
interface ISecretkeeper {
/**
+ * Retrieve the instance of the `IAuthGraphKeyExchange` HAL that should be used for shared
+ * session key establishment. These keys are used to perform encryption of messages as
+ * described in SecretManagement.cddl, allowing the client and Secretkeeper to have a
+ * cryptographically secure channel.
+ */
+ IAuthGraphKeyExchange getAuthGraphKe();
+
+ /**
* processSecretManagementRequest method is used for interacting with the Secret Management API
*
* Secret Management API: The clients can use this API to store (& get) 32 bytes of data.
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index 6818298..93192e9 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -28,6 +28,9 @@
rustlibs: [
"libsecretkeeper_comm_nostd",
"android.hardware.security.secretkeeper-V1-rust",
+ "libauthgraph_core",
+ "libcoset",
+ "libauthgraph_vts_test",
"libbinder_rs",
"liblog_rust",
],
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 28923f7..8c6b4fe 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -16,6 +16,7 @@
#[cfg(test)]
use binder::StatusCode;
+use coset::CborSerializable;
use log::warn;
use secretkeeper_comm::data_types::error::SecretkeeperError;
use secretkeeper_comm::data_types::request::Request;
@@ -25,6 +26,8 @@
use secretkeeper_comm::data_types::response::Response;
use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
+use authgraph_vts_test as ag_vts;
+use authgraph_core::key;
const SECRETKEEPER_IDENTIFIER: &str =
"android.hardware.security.secretkeeper.ISecretkeeper/nonsecure";
@@ -42,6 +45,57 @@
}
}
}
+fn authgraph_key_exchange(sk: binder::Strong<dyn ISecretkeeper>) -> [key::AesKey; 2] {
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_mainline(&mut source, sink)
+}
+
+/// Test that the AuthGraph instance returned by SecretKeeper correctly performs
+/// mainline key exchange against a local source implementation.
+#[test]
+fn authgraph_mainline() {
+ let sk = match get_connection() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+ let _aes_keys = authgraph_key_exchange(sk);
+}
+
+/// Test that the AuthGraph instance returned by SecretKeeper correctly rejects
+/// a corrupted session ID signature.
+#[test]
+fn authgraph_corrupt_sig() {
+ let sk = match get_connection() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_corrupt_sig(&mut source, sink);
+}
+
+/// Test that the AuthGraph instance returned by SecretKeeper correctly detects
+/// when corrupted keys are returned to it.
+#[test]
+fn authgraph_corrupt_keys() {
+ let sk = match get_connection() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_corrupt_keys(&mut source, sink);
+}
// TODO(b/2797757): Add tests that match different HAL defined objects (like request/response)
// with expected bytes.
@@ -57,7 +111,7 @@
};
let request = GetVersionRequest {};
let request_packet = request.serialize_to_packet();
- let request_bytes = request_packet.into_bytes().unwrap();
+ let request_bytes = request_packet.to_vec().unwrap();
// TODO(b/291224769) The request will need to be encrypted & response need to be decrypted
// with key & related artifacts pre-shared via Authgraph Key Exchange HAL.
@@ -66,14 +120,14 @@
.processSecretManagementRequest(&request_bytes)
.unwrap();
- let response_packet = ResponsePacket::from_bytes(&response_bytes).unwrap();
+ let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
assert_eq!(
response_packet.response_type().unwrap(),
ResponseType::Success
);
let get_version_response =
*GetVersionResponse::deserialize_from_packet(response_packet).unwrap();
- assert_eq!(get_version_response.version(), CURRENT_VERSION);
+ assert_eq!(get_version_response.version, CURRENT_VERSION);
}
#[test]
@@ -87,7 +141,7 @@
};
let request = GetVersionRequest {};
let request_packet = request.serialize_to_packet();
- let mut request_bytes = request_packet.into_bytes().unwrap();
+ let mut request_bytes = request_packet.to_vec().unwrap();
// Deform the request
request_bytes[0] = !request_bytes[0];
@@ -99,7 +153,7 @@
.processSecretManagementRequest(&request_bytes)
.unwrap();
- let response_packet = ResponsePacket::from_bytes(&response_bytes).unwrap();
+ let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
assert_eq!(
response_packet.response_type().unwrap(),
ResponseType::Error
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
index 8240b89..6612ea2 100644
--- a/security/secretkeeper/default/Android.bp
+++ b/security/secretkeeper/default/Android.bp
@@ -24,12 +24,19 @@
vendor: true,
installable: false, // install APEX
prefer_rlib: true,
+ defaults: [
+ "authgraph_use_latest_hal_aidl_rust",
+ ],
rustlibs: [
"android.hardware.security.secretkeeper-V1-rust",
"libandroid_logger",
+ "libauthgraph_boringssl",
+ "libauthgraph_core",
+ "libauthgraph_hal",
"libbinder_rs",
"liblog_rust",
- "libsecretkeeper_comm_nostd",
+ "libsecretkeeper_core_nostd",
+ "libsecretkeeper_hal",
],
srcs: [
"src/main.rs",
diff --git a/security/secretkeeper/default/src/main.rs b/security/secretkeeper/default/src/main.rs
index 2d367c5..a291017 100644
--- a/security/secretkeeper/default/src/main.rs
+++ b/security/secretkeeper/default/src/main.rs
@@ -14,80 +14,106 @@
* limitations under the License.
*/
-use binder::{BinderFeatures, Interface};
+//! Non-secure implementation of the Secretkeeper HAL.
+
use log::{error, info, Level};
-use secretkeeper_comm::data_types::error::SecretkeeperError;
-use secretkeeper_comm::data_types::packet::{RequestPacket, ResponsePacket};
-use secretkeeper_comm::data_types::request::Request;
-use secretkeeper_comm::data_types::request_response_impl::{
- GetVersionRequest, GetVersionResponse, Opcode,
-};
-use secretkeeper_comm::data_types::response::Response;
-
+use std::sync::{Arc, Mutex};
+use authgraph_boringssl as boring;
+use authgraph_core::ta::{Role, AuthGraphTa};
+use authgraph_core::keyexchange::{MAX_OPENED_SESSIONS, AuthGraphParticipant};
+use secretkeeper_core::ta::SecretkeeperTa;
+use secretkeeper_hal::SecretkeeperService;
+use authgraph_hal::channel::SerializedChannel;
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
- BnSecretkeeper, BpSecretkeeper, ISecretkeeper,
+ ISecretkeeper, BpSecretkeeper,
};
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::mpsc;
-const CURRENT_VERSION: u64 = 1;
+/// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
+/// insecure).
+pub struct LocalTa {
+ in_tx: mpsc::Sender<Vec<u8>>,
+ out_rx: mpsc::Receiver<Vec<u8>>,
+}
-#[derive(Debug, Default)]
-pub struct NonSecureSecretkeeper;
+/// Prefix byte for messages intended for the AuthGraph TA.
+const AG_MESSAGE_PREFIX: u8 = 0x00;
+/// Prefix byte for messages intended for the Secretkeeper TA.
+const SK_MESSAGE_PREFIX: u8 = 0x01;
-impl Interface for NonSecureSecretkeeper {}
+impl LocalTa {
+ /// Create a new instance.
+ pub fn new() -> Self {
+ // Create a pair of channels to communicate with the TA thread.
+ let (in_tx, in_rx) = mpsc::channel();
+ let (out_tx, out_rx) = mpsc::channel();
-impl ISecretkeeper for NonSecureSecretkeeper {
- fn processSecretManagementRequest(&self, request: &[u8]) -> binder::Result<Vec<u8>> {
- Ok(self.process_opaque_request(request))
+ // The TA code expects to run single threaded, so spawn a thread to run it in.
+ std::thread::spawn(move || {
+ let mut crypto_impls = boring::crypto_trait_impls();
+ let sk_ta = Rc::new(RefCell::new(
+ SecretkeeperTa::new(&mut crypto_impls)
+ .expect("Failed to create local Secretkeeper TA"),
+ ));
+ let mut ag_ta = AuthGraphTa::new(
+ AuthGraphParticipant::new(crypto_impls, sk_ta.clone(), MAX_OPENED_SESSIONS)
+ .expect("Failed to create local AuthGraph TA"),
+ Role::Sink,
+ );
+
+ // Loop forever processing request messages.
+ loop {
+ let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+ let rsp_data = match req_data[0] {
+ AG_MESSAGE_PREFIX => ag_ta.process(&req_data[1..]),
+ SK_MESSAGE_PREFIX => {
+ // It's safe to `borrow_mut()` because this code is not a callback
+ // from AuthGraph (the only other holder of an `Rc`), and so there
+ // can be no live `borrow()`s in this (single) thread.
+ sk_ta.borrow_mut().process(&req_data[1..])
+ }
+ prefix => panic!("unexpected messageprefix {prefix}!"),
+ };
+ out_tx.send(rsp_data).expect("failed to send out rsp");
+ }
+ });
+ Self { in_tx, out_rx }
+ }
+
+ fn execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8> {
+ let mut prefixed_req = Vec::with_capacity(req_data.len() + 1);
+ prefixed_req.push(prefix);
+ prefixed_req.extend_from_slice(req_data);
+ self.in_tx
+ .send(prefixed_req)
+ .expect("failed to send in request");
+ self.out_rx.recv().expect("failed to receive response")
}
}
-impl NonSecureSecretkeeper {
- // A set of requests to Secretkeeper are 'opaque' - encrypted bytes with inner structure
- // described by CDDL. They need to be decrypted, deserialized and processed accordingly.
- fn process_opaque_request(&self, request: &[u8]) -> Vec<u8> {
- // TODO(b/291224769) The request will need to be decrypted & response need to be encrypted
- // with key & related artifacts pre-shared via Authgraph Key Exchange HAL.
- self.process_opaque_request_unhandled_error(request)
- .unwrap_or_else(
- // SecretkeeperError is also a valid 'Response', serialize to a response packet.
- |sk_err| {
- Response::serialize_to_packet(&sk_err)
- .into_bytes()
- .expect("Panicking due to serialization failing")
- },
- )
+pub struct AuthGraphChannel(Arc<Mutex<LocalTa>>);
+impl SerializedChannel for AuthGraphChannel {
+ const MAX_SIZE: usize = usize::MAX;
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ Ok(self
+ .0
+ .lock()
+ .unwrap()
+ .execute_for(AG_MESSAGE_PREFIX, req_data))
}
+}
- fn process_opaque_request_unhandled_error(
- &self,
- request: &[u8],
- ) -> Result<Vec<u8>, SecretkeeperError> {
- let request_packet = RequestPacket::from_bytes(request).map_err(|e| {
- error!("Failed to get Request packet from bytes: {:?}", e);
- SecretkeeperError::RequestMalformed
- })?;
- let response_packet = match request_packet
- .opcode()
- .map_err(|_| SecretkeeperError::RequestMalformed)?
- {
- Opcode::GetVersion => Self::process_get_version_request(request_packet)?,
- _ => todo!("TODO(b/291224769): Unimplemented operations"),
- };
-
- response_packet
- .into_bytes()
- .map_err(|_| SecretkeeperError::UnexpectedServerError)
- }
-
- fn process_get_version_request(
- request: RequestPacket,
- ) -> Result<ResponsePacket, SecretkeeperError> {
- // Deserialization really just verifies the structural integrity of the request such
- // as args being empty.
- let _request = GetVersionRequest::deserialize_from_packet(request)
- .map_err(|_| SecretkeeperError::RequestMalformed)?;
- let response = GetVersionResponse::new(CURRENT_VERSION);
- Ok(response.serialize_to_packet())
+pub struct SecretkeeperChannel(Arc<Mutex<LocalTa>>);
+impl SerializedChannel for SecretkeeperChannel {
+ const MAX_SIZE: usize = usize::MAX;
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ Ok(self
+ .0
+ .lock()
+ .unwrap()
+ .execute_for(SK_MESSAGE_PREFIX, req_data))
}
}
@@ -104,17 +130,17 @@
error!("{}", panic_info);
}));
- let service = NonSecureSecretkeeper::default();
- let service_binder = BnSecretkeeper::new_binder(service, BinderFeatures::default());
+ let ta = Arc::new(Mutex::new(LocalTa::new()));
+ let ag_channel = AuthGraphChannel(ta.clone());
+ let sk_channel = SecretkeeperChannel(ta.clone());
+
+ let service = SecretkeeperService::new_as_binder(sk_channel, ag_channel);
let service_name = format!(
"{}/nonsecure",
<BpSecretkeeper as ISecretkeeper>::get_descriptor()
);
- binder::add_service(&service_name, service_binder.as_binder()).unwrap_or_else(|e| {
- panic!(
- "Failed to register service {} because of {:?}.",
- service_name, e
- );
+ binder::add_service(&service_name, service.as_binder()).unwrap_or_else(|e| {
+ panic!("Failed to register service {service_name} because of {e:?}.",);
});
info!("Registered Binder service, joining threadpool.");
binder::ProcessState::join_thread_pool();
diff --git a/thermal/aidl/Android.bp b/thermal/aidl/Android.bp
index 9382b94..734aab7 100644
--- a/thermal/aidl/Android.bp
+++ b/thermal/aidl/Android.bp
@@ -45,6 +45,6 @@
imports: [],
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
index 1f87cf2..5e88aa0 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
@@ -46,4 +46,8 @@
POWER_AMPLIFIER,
DISPLAY,
SPEAKER,
+ WIFI,
+ CAMERA,
+ FLASHLIGHT,
+ USB_PORT,
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
index e9710a7..665a36e 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
@@ -35,7 +35,7 @@
/* @hide */
@Backing(type="int") @VintfStability
enum TemperatureType {
- UNKNOWN = (-1),
+ UNKNOWN = (-1) /* -1 */,
CPU = 0,
GPU = 1,
BATTERY = 2,
@@ -50,4 +50,10 @@
DISPLAY = 11,
MODEM = 12,
SOC = 13,
+ WIFI = 14,
+ CAMERA = 15,
+ FLASHLIGHT = 16,
+ SPEAKER = 17,
+ AMBIENT = 18,
+ POGO = 19,
}
diff --git a/thermal/aidl/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
index 08beb55..c00028d 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingType.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
@@ -34,4 +34,8 @@
POWER_AMPLIFIER,
DISPLAY,
SPEAKER,
+ WIFI,
+ CAMERA,
+ FLASHLIGHT,
+ USB_PORT,
}
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
index 467d096..ce2a9fc 100644
--- a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
+++ b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
@@ -44,4 +44,10 @@
DISPLAY = 11,
MODEM = 12,
SOC = 13,
+ WIFI = 14,
+ CAMERA = 15,
+ FLASHLIGHT = 16,
+ SPEAKER = 17,
+ AMBIENT = 18,
+ POGO = 19,
}
diff --git a/thermal/aidl/default/Android.bp b/thermal/aidl/default/Android.bp
index 451e1e2..9fe62ce 100644
--- a/thermal/aidl/default/Android.bp
+++ b/thermal/aidl/default/Android.bp
@@ -27,7 +27,7 @@
vendor: true,
stl: "c++_static",
static_libs: [
- "android.hardware.thermal-V1-ndk",
+ "android.hardware.thermal-V2-ndk",
"libbase",
],
shared_libs: [
diff --git a/thermal/aidl/default/thermal-example.xml b/thermal/aidl/default/thermal-example.xml
index bdee744..08dc68c 100644
--- a/thermal/aidl/default/thermal-example.xml
+++ b/thermal/aidl/default/thermal-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.thermal</name>
- <version>1</version>
+ <version>2</version>
<fqname>IThermal/default</fqname>
</hal>
</manifest>
diff --git a/thermal/aidl/vts/Android.bp b/thermal/aidl/vts/Android.bp
index b00eb33..0812811 100644
--- a/thermal/aidl/vts/Android.bp
+++ b/thermal/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.thermal-V1-ndk",
+ "android.hardware.thermal-V2-ndk",
],
test_suites: [
"vts",
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index 2b8e481..efb2454 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -14,7 +14,6 @@
use std::fs::{File, OpenOptions};
use std::io::{self, Read, Write};
-use std::os::fd::AsRawFd;
use std::os::unix::fs::OpenOptionsExt;
enum State {
@@ -61,13 +60,11 @@
}
pub fn makeraw(file: File) -> io::Result<File> {
- let fd = file.as_raw_fd();
-
- // Configure the file descritpro as raw fd.
+ // Configure the file descriptor as raw fd.
use nix::sys::termios::*;
- let mut attrs = tcgetattr(fd)?;
+ let mut attrs = tcgetattr(&file)?;
cfmakeraw(&mut attrs);
- tcsetattr(fd, SetArg::TCSANOW, &attrs)?;
+ tcsetattr(&file, SetArg::TCSANOW, &attrs)?;
Ok(file)
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl
new file mode 100644
index 0000000..cd4a456
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable CachedScanData {
+ int[] scannedFrequenciesMhz;
+ android.hardware.wifi.CachedScanResult[] cachedScanResults;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl
new file mode 100644
index 0000000..1806b0f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable CachedScanResult {
+ long timeStampInUs;
+ byte[] ssid;
+ byte[6] bssid;
+ int rssiDbm;
+ int frequencyMhz;
+ android.hardware.wifi.WifiChannelWidthInMhz channelWidthMhz;
+ android.hardware.wifi.WifiRatePreamble preambleType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
index 2d7fe03..5ed7517 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -84,6 +84,7 @@
void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
@PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApOrBridgedApIface(in android.hardware.wifi.IfaceConcurrencyType iface, in android.hardware.wifi.common.OuiKeyedData[] vendorData);
+ void setVoipMode(in android.hardware.wifi.IWifiChip.VoipMode mode);
const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
@Backing(type="int") @VintfStability
enum FeatureSetMask {
@@ -96,6 +97,7 @@
WIGIG = (1 << 6) /* 64 */,
SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
T2LM_NEGOTIATION = (1 << 8) /* 256 */,
+ SET_VOIP_MODE = (1 << 9) /* 512 */,
}
@VintfStability
parcelable ChipConcurrencyCombinationLimit {
@@ -162,6 +164,11 @@
NAN_INSTANT_MODE = (1 << 2) /* 4 */,
}
@Backing(type="int") @VintfStability
+ enum VoipMode {
+ OFF = 0,
+ VOICE = 1,
+ }
+ @Backing(type="int") @VintfStability
enum ChannelCategoryMask {
INDOOR_CHANNEL = (1 << 0) /* 1 */,
DFS_CHANNEL = (1 << 1) /* 2 */,
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
index 923deff..f838413 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
@@ -61,6 +61,7 @@
void stopRssiMonitoring(in int cmdId);
void stopSendingKeepAlivePackets(in int cmdId);
void setDtimMultiplier(in int multiplier);
+ android.hardware.wifi.CachedScanData getCachedScanData();
@Backing(type="int") @VintfStability
enum FeatureSetMask {
APF = (1 << 0) /* 1 */,
@@ -77,5 +78,6 @@
TDLS_OFFCHANNEL = (1 << 11) /* 2048 */,
ND_OFFLOAD = (1 << 12) /* 4096 */,
KEEP_ALIVE = (1 << 13) /* 8192 */,
+ ROAMING_MODE_CONTROL = (1 << 14) /* 16384 */,
}
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
index dd0a5ed..b5f78b0 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -38,4 +38,6 @@
byte[6] peerDiscMacAddr;
android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
byte[] cookie;
+ boolean isComeback;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
index 6dd9b26..7b17493 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -36,4 +36,5 @@
parcelable NanBootstrappingResponse {
int bootstrappingInstanceId;
boolean acceptRequest;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/CachedScanData.aidl b/wifi/aidl/android/hardware/wifi/CachedScanData.aidl
new file mode 100644
index 0000000..feda079
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CachedScanData.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.CachedScanResult;
+
+/**
+ * Scan data cached in Wifi firmware
+ */
+@VintfStability
+parcelable CachedScanData {
+ /**
+ * List of scanned frequencies in MHz.
+ */
+ int[] scannedFrequenciesMhz;
+
+ /**
+ * List of scan results.
+ */
+ CachedScanResult[] cachedScanResults;
+}
diff --git a/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl b/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl
new file mode 100644
index 0000000..9c9dbc7
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiRatePreamble;
+
+/**
+ * Scan result cached in Wifi firmware
+ */
+@VintfStability
+parcelable CachedScanResult {
+ /**
+ * Time in micro seconds since boot when the scan was done
+ */
+ long timeStampInUs;
+ /**
+ * SSID of beacon excluding null.
+ */
+ byte[] ssid;
+ /**
+ * BSSID of beacon
+ */
+ byte[6] bssid;
+ /**
+ * Beacon received signal stength indicatior (RSSI), in dbm
+ */
+ int rssiDbm;
+ /**
+ * Frequency of beacon, in MHz
+ */
+ int frequencyMhz;
+ /**
+ * Channel bandwidth of found network
+ */
+ WifiChannelWidthInMhz channelWidthMhz;
+ /**
+ * Supported rate and preamble type
+ */
+ WifiRatePreamble preambleType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index 733ff62..d12d26c 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -83,6 +83,10 @@
* Chip supports Tid-To-Link mapping negotiation.
*/
T2LM_NEGOTIATION = 1 << 8,
+ /**
+ * Chip supports voip mode setting.
+ */
+ SET_VOIP_MODE = 1 << 9,
}
/**
@@ -385,6 +389,16 @@
}
/**
+ * This enum represents the different VoIP mode that can be set through |setVoipMode|.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum VoipMode {
+ OFF = 0,
+ VOICE = 1,
+ }
+
+ /**
* Configure the Chip.
* This may NOT be called to reconfigure a chip due to an internal
* limitation. Calling this when chip is already configured in a different
@@ -1173,4 +1187,23 @@
@PropagateAllowBlocking
IWifiApIface createApOrBridgedApIface(
in IfaceConcurrencyType iface, in OuiKeyedData[] vendorData);
+
+ /**
+ * API to set the wifi VoIP mode.
+ *
+ * The VoIP mode is a hint to the HAL to enable or disable Wi-Fi VoIP
+ * optimization. The optimization should be enabled if the mode is NOT set to |OFF|.
+ * Furthermore, HAL should implement relevant optimization techniques based on the
+ * current operational mode.
+ *
+ * Note: Wi-Fi VoIP optimization may trade-off power against Wi-Fi
+ * performance but it provides better voice quility.
+ *
+ * @param mode Voip mode as defined by the enum |VoipMode|
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void setVoipMode(in VoipMode mode);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
index 6d6afaf..3c8b55f 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi;
+import android.hardware.wifi.CachedScanData;
import android.hardware.wifi.IWifiStaIfaceEventCallback;
import android.hardware.wifi.StaApfPacketFilterCapabilities;
import android.hardware.wifi.StaBackgroundScanCapabilities;
@@ -99,6 +100,10 @@
* Support for keep alive packet offload.
*/
KEEP_ALIVE = 1 << 13,
+ /**
+ * Support for configuring roaming mode.
+ */
+ ROAMING_MODE_CONTROL = 1 << 14,
}
/**
@@ -552,4 +557,16 @@
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void setDtimMultiplier(in int multiplier);
+
+ /**
+ * Get the cached scan data.
+ *
+ * @return Instance of |CachedScanData|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ CachedScanData getCachedScanData();
}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
index 4b74cd9..e23bd23 100644
--- a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -45,4 +45,16 @@
* Cookie received from previous |NanBootstrappingConfirmInd| for comeback request.
*/
byte[] cookie;
+
+ /**
+ * Identify if it is a request for come back response
+ */
+ boolean isComeback;
+
+ /**
+ * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+ * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+ * ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
index dbe8923..a2ee0e6 100644
--- a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -29,4 +29,11 @@
* True if accept the request, false otherwise.
*/
boolean acceptRequest;
+
+ /**
+ * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+ * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+ * ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 99420bd..cd2ae11 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -59,6 +59,8 @@
return IWifiChip::FeatureSetMask::P2P_RAND_MAC;
case WIFI_FEATURE_AFC_CHANNEL:
return IWifiChip::FeatureSetMask::SET_AFC_CHANNEL_ALLOWANCE;
+ case WIFI_FEATURE_SET_VOIP_MODE:
+ return IWifiChip::FeatureSetMask::SET_VOIP_MODE;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -92,6 +94,8 @@
return IWifiStaIface::FeatureSetMask::ND_OFFLOAD;
case WIFI_FEATURE_MKEEP_ALIVE:
return IWifiStaIface::FeatureSetMask::KEEP_ALIVE;
+ case WIFI_FEATURE_ROAMING_MODE_CONTROL:
+ return IWifiStaIface::FeatureSetMask::ROAMING_MODE_CONTROL;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -109,7 +113,8 @@
WIFI_FEATURE_INFRA_60G,
WIFI_FEATURE_SET_LATENCY_MODE,
WIFI_FEATURE_P2P_RAND_MAC,
- WIFI_FEATURE_AFC_CHANNEL};
+ WIFI_FEATURE_AFC_CHANNEL,
+ WIFI_FEATURE_SET_VOIP_MODE};
for (const auto feature : features) {
if (feature & legacy_feature_set) {
*aidl_feature_set |= static_cast<uint32_t>(convertLegacyChipFeatureToAidl(feature));
@@ -457,7 +462,8 @@
{WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
- WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+ WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE,
+ WIFI_FEATURE_ROAMING_MODE_CONTROL}) {
if (feature & legacy_feature_set) {
*aidl_feature_set |= static_cast<uint32_t>(convertLegacyStaIfaceFeatureToAidl(feature));
}
@@ -3202,6 +3208,8 @@
legacy_request->cookie_length = aidl_request.cookie.size();
memcpy(legacy_request->cookie, aidl_request.cookie.data(), legacy_request->cookie_length);
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->comeback = aidl_request.isComeback ? 0x1 : 0x0;
return true;
}
@@ -3219,6 +3227,7 @@
legacy_request->service_instance_id = aidl_request.bootstrappingInstanceId;
legacy_request->rsp_code = aidl_request.acceptRequest ? NAN_BOOTSTRAPPING_REQUEST_ACCEPT
: NAN_BOOTSTRAPPING_REQUEST_REJECT;
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
return true;
}
@@ -3386,6 +3395,69 @@
return true;
}
+bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
+ CachedScanData* aidl_scan_data) {
+ if (!aidl_scan_data) {
+ return false;
+ }
+ *aidl_scan_data = {};
+
+ std::vector<CachedScanResult> aidl_scan_results;
+ for (const auto& result : report.results) {
+ CachedScanResult aidl_scan_result;
+ if (!convertCachedScanResultToAidl(result, report.ts, &aidl_scan_result)) {
+ return false;
+ }
+ aidl_scan_results.push_back(aidl_scan_result);
+ }
+ aidl_scan_data->cachedScanResults = aidl_scan_results;
+
+ aidl_scan_data->scannedFrequenciesMhz = report.scanned_freqs;
+ return true;
+}
+
+bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
+ uint64_t ts_us, CachedScanResult* aidl_scan_result) {
+ if (!aidl_scan_result) {
+ return false;
+ }
+ *aidl_scan_result = {};
+ aidl_scan_result->timeStampInUs = ts_us - legacy_scan_result.age_ms * 1000;
+ if (aidl_scan_result->timeStampInUs < 0) {
+ aidl_scan_result->timeStampInUs = 0;
+ return false;
+ }
+ size_t max_len_excluding_null = sizeof(legacy_scan_result.ssid) - 1;
+ size_t ssid_len = strnlen((const char*)legacy_scan_result.ssid, max_len_excluding_null);
+ aidl_scan_result->ssid =
+ std::vector<uint8_t>(legacy_scan_result.ssid, legacy_scan_result.ssid + ssid_len);
+ aidl_scan_result->bssid = std::array<uint8_t, 6>();
+ std::copy(legacy_scan_result.bssid, legacy_scan_result.bssid + 6,
+ std::begin(aidl_scan_result->bssid));
+ aidl_scan_result->frequencyMhz = legacy_scan_result.chanspec.primary_frequency;
+ aidl_scan_result->channelWidthMhz =
+ convertLegacyWifiChannelWidthToAidl(legacy_scan_result.chanspec.width);
+ aidl_scan_result->rssiDbm = legacy_scan_result.rssi;
+ aidl_scan_result->preambleType = convertScanResultFlagsToPreambleType(legacy_scan_result.flags);
+ return true;
+}
+
+WifiRatePreamble convertScanResultFlagsToPreambleType(int flags) {
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::EHT;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::HE;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::VHT;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::HT;
+ }
+ return WifiRatePreamble::OFDM;
+}
+
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index e4ff963..b59c453 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -202,6 +202,11 @@
const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
NanBootstrappingConfirmInd* aidl_ind);
uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask);
+bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
+ CachedScanData* aidl_scan_data);
+bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
+ uint64_t ts_us, CachedScanResult* aidl_scan_result);
+WifiRatePreamble convertScanResultFlagsToPreambleType(int flags);
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
index 995a13d..2a030ee 100644
--- a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -35,6 +35,12 @@
0x2c, 0x00, 0x00, 0x41, 0x06, 0x03, 0x06, 0x00, 0x80};
byte LCR[] = {0x27, 0xE, 0x1, 0x00, 0xB, 0x01, 0x00, 0x0b, 0x00, 0x09,
0x55, 0x53, 0x18, 0x05, 0x39, 0x34, 0x30, 0x34, 0x33};
+
+constexpr int kNumScanResult = 2;
+constexpr int kRssi[] = {-60, -70};
+constexpr uint8_t kBssid[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0};
+constexpr uint8_t kSsidLen = 6;
+constexpr char kSsid[] = {'a', 'b', 'c', 'd', 'e', '\0'};
} // namespace
namespace aidl {
@@ -883,6 +889,51 @@
}
}
+TEST_F(AidlStructUtilTest, convertCachedScanReportToAidl) {
+ legacy_hal::WifiCachedScanReport hw_report;
+
+ hw_report.ts = 10000000;
+ std::vector<int> scanned_freqs{5260, 2437, 5200};
+ std::vector<wifi_cached_scan_result> results;
+ hw_report.scanned_freqs = scanned_freqs;
+
+ for (int i = 0; i < kNumScanResult; i++) {
+ wifi_cached_scan_result result;
+ result.age_ms = i * 1000;
+ result.capability = i;
+ memcpy(result.ssid, kSsid, kSsidLen);
+ result.ssid_len = kSsidLen;
+ memcpy(result.bssid, kBssid, 6);
+ result.flags = WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT;
+ result.rssi = kRssi[i];
+ result.chanspec = {legacy_hal::WIFI_CHAN_WIDTH_40, 0, 0, i};
+ results.push_back(result);
+ }
+ hw_report.results = results;
+
+ CachedScanData aidl_data;
+ aidl_struct_util::convertCachedScanReportToAidl(hw_report, &aidl_data);
+
+ EXPECT_EQ(scanned_freqs.size(), aidl_data.scannedFrequenciesMhz.size());
+ EXPECT_EQ(scanned_freqs[2], aidl_data.scannedFrequenciesMhz[2]);
+ EXPECT_EQ(5260, aidl_data.scannedFrequenciesMhz[0]);
+ EXPECT_EQ(kNumScanResult, (int)aidl_data.cachedScanResults.size());
+ for (int i = 0; i < kNumScanResult; i++) {
+ EXPECT_EQ(hw_report.results[i].rssi, aidl_data.cachedScanResults[i].rssiDbm);
+ EXPECT_EQ(i, aidl_data.cachedScanResults[i].frequencyMhz);
+ int64_t expected_ts = 10000000 - i * 1000 * 1000;
+ EXPECT_EQ(expected_ts, aidl_data.cachedScanResults[i].timeStampInUs);
+ EXPECT_EQ(WifiRatePreamble::HE, aidl_data.cachedScanResults[i].preambleType);
+ EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_40, aidl_data.cachedScanResults[i].channelWidthMhz);
+ for (int k = 0; k < 6; k++) {
+ EXPECT_EQ(kBssid[k], aidl_data.cachedScanResults[i].bssid[k]);
+ }
+ for (int k = 0; k < kSsidLen; k++) {
+ EXPECT_EQ(kSsid[k], aidl_data.cachedScanResults[i].ssid[k]);
+ }
+ }
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index d72775c..9b9c565 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
#include <fcntl.h>
+#include <hardware_legacy/wifi_hal.h>
#include <net/if.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
@@ -605,6 +606,11 @@
&WifiChip::setMloModeInternal, in_mode);
}
+ndk::ScopedAStatus WifiChip::setVoipMode(const VoipMode in_mode) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setVoipModeInternal, in_mode);
+}
+
void WifiChip::invalidateAndRemoveAllIfaces() {
invalidateAndClearBridgedApAll();
invalidateAndClearAll(ap_ifaces_);
@@ -1913,6 +1919,23 @@
return createWifiStatusFromLegacyError(legacy_hal_.lock()->setMloMode(mode));
}
+ndk::ScopedAStatus WifiChip::setVoipModeInternal(const WifiChip::VoipMode in_mode) {
+ const auto ifname = getFirstActiveWlanIfaceName();
+ wifi_voip_mode mode;
+ switch (in_mode) {
+ case WifiChip::VoipMode::VOICE:
+ mode = wifi_voip_mode::WIFI_VOIP_MODE_VOICE;
+ break;
+ case WifiChip::VoipMode::OFF:
+ mode = wifi_voip_mode::WIFI_VOIP_MODE_OFF;
+ break;
+ default:
+ PLOG(ERROR) << "Error: invalid mode: " << toString(in_mode);
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ return createWifiStatusFromLegacyError(legacy_hal_.lock()->setVoipMode(ifname, mode));
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index c6517db..ffd507f 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -158,6 +158,7 @@
int32_t in_channelCategoryEnableFlag) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
ndk::ScopedAStatus setMloMode(const ChipMloMode in_mode) override;
+ ndk::ScopedAStatus setVoipMode(const VoipMode in_mode) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -269,6 +270,7 @@
getSupportedRadioCombinationsInternal();
std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+ ndk::ScopedAStatus setVoipModeInternal(const VoipMode in_mode);
void retrieveDynamicIfaceCombination();
void setWeakPtr(std::weak_ptr<WifiChip> ptr);
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index 209670b..5f3e313 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -439,6 +439,7 @@
// Callback to report cached scan results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
if (on_cached_scan_results_internal_callback) {
on_cached_scan_results_internal_callback(cache_report);
}
@@ -1858,13 +1859,16 @@
return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
}
-wifi_error WifiLegacyHal::getWifiCachedScanResults(
- const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
- on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
-
+wifi_error WifiLegacyHal::getWifiCachedScanResults(const std::string& iface_name,
+ WifiCachedScanReport& report) {
+ on_cached_scan_results_internal_callback = [&report](wifi_cached_scan_report* report_ptr) {
+ report.results.assign(report_ptr->results, report_ptr->results + report_ptr->result_cnt);
+ report.scanned_freqs.assign(report_ptr->scanned_freq_list,
+ report_ptr->scanned_freq_list + report_ptr->scanned_freq_num);
+ report.ts = report_ptr->ts;
+ };
wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
{onSyncCachedScanResults});
-
on_cached_scan_results_internal_callback = nullptr;
return status;
}
@@ -1934,6 +1938,7 @@
on_twt_event_info_frame_received_callback = nullptr;
on_twt_event_device_notify_callback = nullptr;
on_chre_nan_rtt_internal_callback = nullptr;
+ on_cached_scan_results_internal_callback = nullptr;
}
} // namespace legacy_hal
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 6f012ec..4dd0d62 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -257,6 +257,7 @@
using ::WIFI_BAND_BG;
using ::WIFI_BAND_UNSPECIFIED;
using ::wifi_cached_scan_report;
+using ::wifi_cached_scan_result;
using ::wifi_cached_scan_results;
using ::WIFI_CHAN_WIDTH_10;
using ::WIFI_CHAN_WIDTH_160;
@@ -423,6 +424,12 @@
bool valid;
};
+struct WifiCachedScanReport {
+ uint64_t ts;
+ std::vector<int> scanned_freqs;
+ std::vector<wifi_cached_scan_result> results;
+};
+
#pragma GCC diagnostic pop
// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
@@ -533,8 +540,9 @@
std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
};
-// Cached Scan Results response and event callbacks struct.
-struct CachedScanResultsCallbackHandlers {
+using on_cached_scan_results_callback = std::function<void(wifi_cached_scan_report*)>;
+
+struct CachedScanResultsCallbfackHandlers {
// Callback for Cached Scan Results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
};
@@ -777,7 +785,7 @@
wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
wifi_error getWifiCachedScanResults(const std::string& iface_name,
- const CachedScanResultsCallbackHandlers& handler);
+ WifiCachedScanReport& report);
std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
wifi_error setMloMode(wifi_mlo_mode mode);
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
index 800813f..0ae428f 100644
--- a/wifi/aidl/default/wifi_sta_iface.cpp
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -219,6 +219,11 @@
&WifiStaIface::setDtimMultiplierInternal, in_multiplier);
}
+ndk::ScopedAStatus WifiStaIface::getCachedScanData(CachedScanData* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getCachedScanDataInternal, _aidl_return);
+}
+
std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
return {ifname_, ndk::ScopedAStatus::ok()};
}
@@ -540,6 +545,21 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+std::pair<CachedScanData, ndk::ScopedAStatus> WifiStaIface::getCachedScanDataInternal() {
+ legacy_hal::WifiCachedScanReport cached_scan_report;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->getWifiCachedScanResults(ifname_, cached_scan_report);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {CachedScanData{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ CachedScanData aidl_scan_data;
+ if (!aidl_struct_util::convertCachedScanReportToAidl(cached_scan_report, &aidl_scan_data)) {
+ return {CachedScanData{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+
+ return {aidl_scan_data, ndk::ScopedAStatus::ok()};
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_sta_iface.h b/wifi/aidl/default/wifi_sta_iface.h
index 3d7ec4d..fe05c21 100644
--- a/wifi/aidl/default/wifi_sta_iface.h
+++ b/wifi/aidl/default/wifi_sta_iface.h
@@ -90,6 +90,7 @@
ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
ndk::ScopedAStatus setScanMode(bool in_enable) override;
ndk::ScopedAStatus setDtimMultiplier(int32_t in_multiplier) override;
+ ndk::ScopedAStatus getCachedScanData(CachedScanData* _aidl_return) override;
private:
// Corresponding worker functions for the AIDL methods.
@@ -130,6 +131,7 @@
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
ndk::ScopedAStatus setScanModeInternal(bool enable);
ndk::ScopedAStatus setDtimMultiplierInternal(const int multiplier);
+ std::pair<CachedScanData, ndk::ScopedAStatus> getCachedScanDataInternal();
void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 8aa593f..851e851 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -34,6 +34,9 @@
package android.hardware.wifi.supplicant;
@VintfStability
interface ISupplicantP2pIfaceCallback {
+ /**
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onDeviceFoundWithParams.
+ */
oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo);
oneway void onDeviceLost(in byte[] p2pDeviceAddress);
oneway void onFindStopped();
@@ -60,9 +63,13 @@
*/
oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
+ /**
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call onDeviceFoundWithParams.
+ */
oneway void onDeviceFoundWithVendorElements(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
oneway void onGroupStartedWithParams(in android.hardware.wifi.supplicant.P2pGroupStartedEventParams groupStartedEventParams);
oneway void onPeerClientJoined(in android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams clientJoinedEventParams);
oneway void onPeerClientDisconnected(in android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams clientDisconnectedEventParams);
oneway void onProvisionDiscoveryCompletedEvent(in android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
+ oneway void onDeviceFoundWithParams(in android.hardware.wifi.supplicant.P2pDeviceFoundEventParams deviceFoundEventParams);
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
new file mode 100644
index 0000000..792e08d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable MsduDeliveryInfo {
+ android.hardware.wifi.supplicant.MsduDeliveryInfo.DeliveryRatio deliveryRatio;
+ byte countExponent;
+ @Backing(type="byte") @VintfStability
+ enum DeliveryRatio {
+ RATIO_95 = 1,
+ RATIO_96 = 2,
+ RATIO_97 = 3,
+ RATIO_98 = 4,
+ RATIO_99 = 5,
+ RATIO_99_9 = 6,
+ RATIO_99_99 = 7,
+ RATIO_99_999 = 8,
+ RATIO_99_9999 = 9,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
new file mode 100644
index 0000000..ee8e6dc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pDeviceFoundEventParams {
+ byte[6] srcAddress;
+ byte[6] p2pDeviceAddress;
+ byte[] primaryDeviceType;
+ String deviceName;
+ int configMethods;
+ byte deviceCapabilities;
+ int groupCapabilities;
+ byte[] wfdDeviceInfo;
+ byte[] wfdR2DeviceInfo;
+ byte[] vendorElemBytes;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl
new file mode 100644
index 0000000..dacac8c
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosCharacteristics {
+ int minServiceIntervalUs;
+ int maxServiceIntervalUs;
+ int minDataRateKbps;
+ int delayBoundUs;
+ int optionalFieldMask;
+ char maxMsduSizeOctets;
+ int serviceStartTimeUs;
+ byte serviceStartTimeLinkId;
+ int meanDataRateKbps;
+ int burstSizeOctets;
+ char msduLifetimeMs;
+ android.hardware.wifi.supplicant.MsduDeliveryInfo msduDeliveryInfo;
+ @Backing(type="int") @VintfStability
+ enum QosCharacteristicsMask {
+ MAX_MSDU_SIZE = (1 << 0) /* 1 */,
+ SERVICE_START_TIME = (1 << 1) /* 2 */,
+ SERVICE_START_TIME_LINK_ID = (1 << 2) /* 4 */,
+ MEAN_DATA_RATE = (1 << 3) /* 8 */,
+ BURST_SIZE = (1 << 4) /* 16 */,
+ MSDU_LIFETIME = (1 << 5) /* 32 */,
+ MSDU_DELIVERY_INFO = (1 << 6) /* 64 */,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
index 4e5e8ae..20be616 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -22,4 +22,11 @@
byte policyId;
byte userPriority;
android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+ android.hardware.wifi.supplicant.QosPolicyScsData.LinkDirection direction;
+ @nullable android.hardware.wifi.supplicant.QosCharacteristics QosCharacteristics;
+ @Backing(type="byte") @VintfStability
+ enum LinkDirection {
+ DOWNLINK,
+ UPLINK,
+ }
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 8befc0d..11cd867 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.supplicant.P2pDeviceFoundEventParams;
import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
import android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams;
@@ -38,6 +39,9 @@
oneway interface ISupplicantP2pIfaceCallback {
/**
* Used to indicate that a P2P device has been found.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+ * onDeviceFoundWithParams.
*
* @param srcAddress MAC address of the device found. This must either
* be the P2P device address or the P2P interface address.
@@ -228,6 +232,9 @@
/**
* Used to indicate that a P2P device has been found.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call
+ * onDeviceFoundWithParams.
*
* @param srcAddress MAC address of the device found. This must either
* be the P2P device address for a peer which is not in a group,
@@ -288,4 +295,11 @@
*/
void onProvisionDiscoveryCompletedEvent(
in P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
+
+ /**
+ * Used to indicate that a P2P device has been found.
+ *
+ * @param deviceFoundEventParams Parameters associated with the device found event.
+ */
+ void onDeviceFoundWithParams(in P2pDeviceFoundEventParams deviceFoundEventParams);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
new file mode 100644
index 0000000..8065f63
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * MSDU delivery information.
+ * See Section 9.4.2.316 of the IEEE P802.11be/D4.0 Standard.
+ */
+@VintfStability
+parcelable MsduDeliveryInfo {
+ /**
+ * Enums for the |deliveryRatio| field.
+ * See Table 9-404t of the IEEE P802.11be/D4.0 Standard.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum DeliveryRatio {
+ RATIO_95 = 1, // 95%
+ RATIO_96 = 2, // 96%
+ RATIO_97 = 3, // 97%
+ RATIO_98 = 4, // 98%
+ RATIO_99 = 5, // 99%
+ RATIO_99_9 = 6, // 99.9%
+ RATIO_99_99 = 7, // 99.99%
+ RATIO_99_999 = 8, // 99.999%
+ RATIO_99_9999 = 9, // 99.9999%
+ }
+
+ /**
+ * Percentage of the MSDUs that are expected to be delivered successfully.
+ */
+ DeliveryRatio deliveryRatio;
+
+ /**
+ * Exponent from which the number of incoming MSDUs is computed. The number of incoming
+ * MSDUs is 10^countExponent, and is used to determine the MSDU delivery ratio.
+ * Must be a number between 0 and 15 (inclusive).
+ */
+ byte countExponent;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
new file mode 100644
index 0000000..15917b6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters passed as a part of a P2P Device found event.
+ */
+@VintfStability
+parcelable P2pDeviceFoundEventParams {
+ /**
+ * MAC address of the device found. This must either be the P2P device address
+ * for a peer which is not in a group, or the P2P interface address for
+ * a peer which is a Group Owner.
+ */
+ byte[6] srcAddress;
+
+ /**
+ * P2P device address.
+ */
+ byte[6] p2pDeviceAddress;
+
+ /**
+ * Type of device. Refer to section B.1 of the Wifi P2P Technical
+ * specification v1.2.
+ */
+ byte[] primaryDeviceType;
+
+ /**
+ * Name of the device.
+ */
+ String deviceName;
+
+ /**
+ * Mask of |WpsConfigMethods| indicating the WPS configuration methods
+ * supported by the device.
+ */
+ int configMethods;
+
+ /**
+ * Refer to section 4.1.4 of the Wifi P2P Technical specification v1.2.
+ */
+ byte deviceCapabilities;
+
+ /**
+ * Mask of |P2pGroupCapabilityMask| indicating the group capabilities.
+ * Refer to section 4.1.4 of the Wifi P2P Technical specification v1.2.
+ */
+ int groupCapabilities;
+
+ /**
+ * WFD device info as described in section 5.1.2 of the WFD technical
+ * specification v1.0.0.
+ */
+ byte[] wfdDeviceInfo;
+
+ /**
+ * WFD R2 device info as described in section 5.1.12 of WFD technical
+ * specification v2.1.
+ */
+ byte[] wfdR2DeviceInfo;
+
+ /**
+ * Vendor-specific information element bytes. The format of an
+ * information element is EID (1 byte) + Length (1 Byte) + Payload which is
+ * defined in Section 9.4.4 TLV encodings of 802.11-2016 IEEE Standard for
+ * Information technology. The length indicates the size of the payload.
+ * Multiple information elements may be appended within the byte array.
+ */
+ byte[] vendorElemBytes;
+
+ /**
+ * Optional vendor-specific data.
+ * Null value indicates that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl
new file mode 100644
index 0000000..be5ef91
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.MsduDeliveryInfo;
+
+/**
+ * Additional QoS parameters as defined in Section 9.4.2.316
+ * of the IEEE P802.11be/D4.0 Standard.
+ */
+@VintfStability
+parcelable QosCharacteristics {
+ /**
+ * Unsigned integer specifying the minimum interval (in microseconds) between the start of
+ * two consecutive service periods (SPs) that are allocated for frame exchanges.
+ * The value must be non-zero.
+ */
+ int minServiceIntervalUs;
+
+ /**
+ * Unsigned integer specifying the maximum interval (in microseconds) between the start of two
+ * consecutive SPs that are allocated for frame exchanges. The value must be non-zero.
+ */
+ int maxServiceIntervalUs;
+
+ /**
+ * Unsigned integer specifying the lowest data rate (in kilobits/sec)
+ * for the transport of MSDUs or A-MSDUs belonging to the traffic flow.
+ * The value must be non-zero.
+ */
+ int minDataRateKbps;
+
+ /**
+ * Unsigned integer specifying the maximum amount of time (in microseconds)
+ * targeted to transport an MSDU or A-MSDU belonging to the traffic flow.
+ * The value must be non-zero.
+ */
+ int delayBoundUs;
+
+ /**
+ * Enum values indicating which optional fields are provided.
+ * See Figure 9-1001au of the IEEE P802.11be/D4.0 Standard.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum QosCharacteristicsMask {
+ MAX_MSDU_SIZE = 1 << 0,
+ SERVICE_START_TIME = 1 << 1,
+ SERVICE_START_TIME_LINK_ID = 1 << 2,
+ MEAN_DATA_RATE = 1 << 3,
+ BURST_SIZE = 1 << 4,
+ MSDU_LIFETIME = 1 << 5,
+ MSDU_DELIVERY_INFO = 1 << 6,
+ }
+
+ /**
+ * Mask of |QosCharacteristicsMask| indicating which optional fields are provided.
+ */
+ int optionalFieldMask;
+
+ /**
+ * Unsigned 16-bit value specifying the maximum size (in octets) of an MSDU
+ * belonging to the traffic flow. The value must be non-zero if provided.
+ */
+ char maxMsduSizeOctets;
+
+ /**
+ * Unsigned integer specifying the anticipated time (in microseconds) when
+ * the traffic starts for the associated TID.
+ */
+ int serviceStartTimeUs;
+
+ /**
+ * The four LSBs indicate the link identifier that corresponds to the link for which the
+ * TSF timer is used to indicate the Service Start Time. The four MSBs should not be used.
+ * This field is present if |serviceStartTimeUs| is included and is not present otherwise.
+ */
+ byte serviceStartTimeLinkId;
+
+ /**
+ * Unsigned integer indicating the data rate specified (in kilobits/sec) for transport of MSDUs
+ * or A-MSDUs belonging to the traffic flow. The value must be non-zero if provided.
+ */
+ int meanDataRateKbps;
+
+ /**
+ * Unsigned integer specififying the maximum burst (in octets) of the MSDUs or A-MSDUs
+ * belonging to the traffic flow that arrive at the MAC SAP within any time duration equal
+ * to the value specified in the |delayBound| field. The value must be non-zero if provided.
+ */
+ int burstSizeOctets;
+
+ /**
+ * Unsigned 16-bit integer specifying the maximum amount of time (in milliseconds) since the
+ * arrival of the MSDU at the MAC data service interface beyond which the MSDU is not useful
+ * even if received by the receiver. The amount of time specified in this field is larger than
+ * or equal to the amount of time specified in the |delayBound| field, if present. The value
+ * must be non-zero if provided.
+ */
+ char msduLifetimeMs;
+
+ /**
+ * MSDU delivery information. See |MsduDeliveryInfo| for more details.
+ */
+ MsduDeliveryInfo msduDeliveryInfo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
index 86a4dac..76f5a9a 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -1,5 +1,6 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.supplicant.QosCharacteristics;
import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
/**
@@ -21,4 +22,24 @@
* QoS policy SCS classifier type information.
*/
QosPolicyClassifierParams classifierParams;
+
+ /**
+ * Enum values for the |direction| field.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum LinkDirection {
+ DOWNLINK,
+ UPLINK, // Only applies to trigger-based traffic (Wi-Fi 6+)
+ }
+
+ /**
+ * Direction of data described by this element.
+ */
+ LinkDirection direction;
+
+ /**
+ * Additional parameters available in QoS R3.
+ */
+ @nullable QosCharacteristics QosCharacteristics;
}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index 0db1653..3f96414 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -35,6 +35,7 @@
using aidl::android::hardware::wifi::supplicant::ISupplicant;
using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::MiracastMode;
+using aidl::android::hardware::wifi::supplicant::P2pDeviceFoundEventParams;
using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
@@ -199,6 +200,10 @@
/* provisionDiscoveryCompletedEventParams */) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onDeviceFoundWithParams(
+ const P2pDeviceFoundEventParams& /* deviceFoundEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
};
class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {