Add interfaces to query aaudio hardware information. am: b76981e2a7 am: cfc2866173

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2389657

Change-Id: I7608c1ec23c43f74ccfa843699d95e4253e154a1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
jiabin
2023-01-19 21:16:04 +00:00
committed by Automerger Merge Worker
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 {