Add interfaces to query aaudio hardware information.

Add interfaces to query aaudio hardware information. The new interfaces
are supposed to replace the system properties. The information includes
aaudio mixer burst count and aaudio hardware burst minimum usec.

Bug: 193275465
Test: atest VtsHalAudioCoreTargetTest
Change-Id: Id3442dae15937baba84f053f2e244bc294f4d718
This commit is contained in:
jiabin
2023-01-18 00:58:30 +00:00
parent ed2054123f
commit b76981e2a7
7 changed files with 111 additions and 6 deletions

View File

@@ -70,6 +70,10 @@ interface IModule {
void removeDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
android.media.audio.common.AudioMMapPolicyInfo[] getMmapPolicyInfos(android.media.audio.common.AudioMMapPolicyType mmapPolicyType);
boolean supportsVariableLatency();
int getAAudioMixerBurstCount();
int getAAudioHardwareBurstMinUsec();
const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
@VintfStability
parcelable OpenInputStreamArguments {
int portConfigId;

View File

@@ -833,4 +833,31 @@ interface IModule {
* @return Whether the module supports variable latency control.
*/
boolean supportsVariableLatency();
/**
* Default value for number of bursts per aaudio mixer cycle. This is a suggested value
* to return for the HAL module, unless it is known that a better option exists.
*/
const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
/**
* Get the number of bursts per aaudio mixer cycle.
*
* @return The number of burst per aaudio mixer cycle.
* @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP.
*/
int getAAudioMixerBurstCount();
/**
* Default value for minimum duration in microseconds for a MMAP hardware burst. This
* is a suggested value to return for the HAL module, unless it is known that a better
* option exists.
*/
const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
/**
* Get the minimum duration in microseconds for a MMAP hardware burst.
*
* @return The minimum number of microseconds for a MMAP hardware burst.
* @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP.
*/
int getAAudioHardwareBurstMinUsec();
}

View File

@@ -1151,4 +1151,41 @@ ndk::ScopedAStatus Module::supportsVariableLatency(bool* _aidl_return) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Module::getAAudioMixerBurstCount(int32_t* _aidl_return) {
if (!isMmapSupported()) {
LOG(DEBUG) << __func__ << ": mmap is not supported ";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = DEFAULT_AAUDIO_MIXER_BURST_COUNT;
LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Module::getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) {
if (!isMmapSupported()) {
LOG(DEBUG) << __func__ << ": mmap is not supported ";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US;
LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
return ndk::ScopedAStatus::ok();
}
bool Module::isMmapSupported() {
if (mIsMmapSupported.has_value()) {
return mIsMmapSupported.value();
}
std::vector<AudioMMapPolicyInfo> mmapPolicyInfos;
if (!getMmapPolicyInfos(AudioMMapPolicyType::DEFAULT, &mmapPolicyInfos).isOk()) {
mIsMmapSupported = false;
} else {
mIsMmapSupported =
std::find_if(mmapPolicyInfos.begin(), mmapPolicyInfos.end(), [](const auto& info) {
return info.mmapPolicy == AudioMMapPolicy::AUTO ||
info.mmapPolicy == AudioMMapPolicy::ALWAYS;
}) != mmapPolicyInfos.end();
}
return mIsMmapSupported.value();
}
} // namespace aidl::android::hardware::audio::core

View File

@@ -115,6 +115,8 @@ class Module : public BnModule {
std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>* _aidl_return)
override;
ndk::ScopedAStatus supportsVariableLatency(bool* _aidl_return) override;
ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t* _aidl_return) override;
ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
void cleanUpPatch(int32_t patchId);
ndk::ScopedAStatus createStreamContext(
@@ -132,6 +134,7 @@ class Module : public BnModule {
std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds);
void registerPatch(const AudioPatch& patch);
void updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch);
bool isMmapSupported();
// This value is used for all AudioPatches.
static constexpr int32_t kMinimumStreamBufferSizeFrames = 16;
@@ -159,6 +162,7 @@ class Module : public BnModule {
bool mMicMute = false;
std::shared_ptr<sounddose::ISoundDose> mSoundDose;
ndk::SpAIBinder mSoundDoseBinder;
std::optional<bool> mIsMmapSupported;
};
} // namespace aidl::android::hardware::audio::core

View File

@@ -438,3 +438,11 @@ std::vector<AudioPortConfig> ModuleConfig::generateAudioDevicePortConfigs(
}
return result;
}
bool ModuleConfig::isMmapSupported() const {
const std::vector<AudioPort> mmapOutMixPorts =
getMmapOutMixPorts(false /*attachedOnly*/, false /*singlePort*/);
const std::vector<AudioPort> mmapInMixPorts =
getMmapInMixPorts(false /*attachedOnly*/, false /*singlePort*/);
return !mmapOutMixPorts.empty() || !mmapInMixPorts.empty();
}

View File

@@ -139,6 +139,8 @@ class ModuleConfig {
return *config.begin();
}
bool isMmapSupported() const;
std::string toString() const;
private:

View File

@@ -1893,17 +1893,13 @@ TEST_P(AudioCoreModule, AddRemoveEffectInvalidArguments) {
TEST_P(AudioCoreModule, GetMmapPolicyInfos) {
ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
const std::vector<AudioPort> mmapOutMixPorts =
moduleConfig->getMmapOutMixPorts(true /*attachedOnly*/, false /*singlePort*/);
const std::vector<AudioPort> mmapInMixPorts =
moduleConfig->getMmapInMixPorts(true /*attachedOnly*/, false /*singlePort*/);
const bool mmapSupported = (!mmapOutMixPorts.empty() || !mmapInMixPorts.empty());
const bool isMmapSupported = moduleConfig->isMmapSupported();
for (const auto mmapPolicyType :
{AudioMMapPolicyType::DEFAULT, AudioMMapPolicyType::EXCLUSIVE}) {
std::vector<AudioMMapPolicyInfo> policyInfos;
EXPECT_IS_OK(module->getMmapPolicyInfos(mmapPolicyType, &policyInfos))
<< toString(mmapPolicyType);
EXPECT_EQ(mmapSupported, !policyInfos.empty());
EXPECT_EQ(isMmapSupported, !policyInfos.empty());
}
}
@@ -1913,6 +1909,33 @@ TEST_P(AudioCoreModule, BluetoothVariableLatency) {
LOG(INFO) << "supportsVariableLatency: " << isSupported;
}
TEST_P(AudioCoreModule, GetAAudioMixerBurstCount) {
ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
const bool isMmapSupported = moduleConfig->isMmapSupported();
int32_t mixerBursts = 0;
ndk::ScopedAStatus status = module->getAAudioMixerBurstCount(&mixerBursts);
EXPECT_EQ(isMmapSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION)
<< "Support for AAudio MMAP and getting AAudio mixer burst count must be consistent";
if (!isMmapSupported) {
GTEST_SKIP() << "AAudio MMAP is not supported";
}
EXPECT_GE(mixerBursts, 0);
}
TEST_P(AudioCoreModule, GetAAudioHardwareBurstMinUsec) {
ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
const bool isMmapSupported = moduleConfig->isMmapSupported();
int32_t aaudioHardwareBurstMinUsec = 0;
ndk::ScopedAStatus status = module->getAAudioHardwareBurstMinUsec(&aaudioHardwareBurstMinUsec);
EXPECT_EQ(isMmapSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION)
<< "Support for AAudio MMAP and getting AAudio hardware burst minimum usec "
<< "must be consistent";
if (!isMmapSupported) {
GTEST_SKIP() << "AAudio MMAP is not supported";
}
EXPECT_GE(aaudioHardwareBurstMinUsec, 0);
}
class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
public:
void SetUp() override {