libaudiohal@aidl: Implement microphone info retrieval
Implement DeviceHalAidl::getMicrophones and
StreamInHalAidl::getActiveMicrophones.
Bug: 205884982
Test: atest android.media.audio.cts.AudioRecordTest
Test: atest android.media.audio.cts.AudioManagerTest
(both w/AIDL enabled)
Change-Id: I4f07cd9b2273ab93d9d0cda1349a50730c30b528
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 7d5c3b8..cf4d670 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -54,6 +54,8 @@
using aidl::android::hardware::audio::common::getFrameSizeInBytes;
using aidl::android::hardware::audio::common::isBitPositionFlagSet;
using aidl::android::hardware::audio::common::makeBitPositionFlagMask;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
using aidl::android::hardware::audio::common::RecordTrackMetadata;
using aidl::android::hardware::audio::core::AudioPatch;
using aidl::android::hardware::audio::core::IModule;
@@ -531,7 +533,7 @@
return NO_INIT;
}
*inStream = sp<StreamInHalAidl>::make(*config, std::move(context), nominalLatency,
- std::move(ret.stream));
+ std::move(ret.stream), this /*micInfoProvider*/);
cleanups.disarmAll();
return OK;
}
@@ -666,11 +668,45 @@
return OK;
}
+MicrophoneInfoProvider::Info const* DeviceHalAidl::getMicrophoneInfo() {
+ if (mMicrophones.status == Microphones::Status::UNKNOWN) {
+ TIME_CHECK();
+ std::vector<MicrophoneInfo> aidlInfo;
+ status_t status = statusTFromBinderStatus(mModule->getMicrophones(&aidlInfo));
+ if (status == OK) {
+ mMicrophones.status = Microphones::Status::QUERIED;
+ mMicrophones.info = std::move(aidlInfo);
+ } else if (status == INVALID_OPERATION) {
+ mMicrophones.status = Microphones::Status::NOT_SUPPORTED;
+ } else {
+ ALOGE("%s: Unexpected status from 'IModule.getMicrophones': %d", __func__, status);
+ return {};
+ }
+ }
+ if (mMicrophones.status == Microphones::Status::QUERIED) {
+ return &mMicrophones.info;
+ }
+ return {}; // NOT_SUPPORTED
+}
+
status_t DeviceHalAidl::getMicrophones(
- std::vector<audio_microphone_characteristic_t>* microphones __unused) {
+ std::vector<audio_microphone_characteristic_t>* microphones) {
+ if (!microphones) {
+ return BAD_VALUE;
+ }
TIME_CHECK();
if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+ auto staticInfo = getMicrophoneInfo();
+ if (!staticInfo) return INVALID_OPERATION;
+ std::vector<MicrophoneDynamicInfo> emptyDynamicInfo;
+ emptyDynamicInfo.reserve(staticInfo->size());
+ std::transform(staticInfo->begin(), staticInfo->end(), std::back_inserter(emptyDynamicInfo),
+ [](const auto& info) { return MicrophoneDynamicInfo{ .id = info.id }; });
+ *microphones = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::convertContainers<std::vector<audio_microphone_characteristic_t>>(
+ *staticInfo, emptyDynamicInfo,
+ ::aidl::android::aidl2legacy_MicrophoneInfos_audio_microphone_characteristic_t)
+ );
return OK;
}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 04afa68..0a86ddc 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -56,8 +56,16 @@
void* cookie, const sp<StreamOutHalInterfaceLatencyModeCallback>&) = 0;
};
+class MicrophoneInfoProvider : public virtual RefBase {
+ public:
+ using Info = std::vector<::aidl::android::media::audio::common::MicrophoneInfo>;
+ virtual ~MicrophoneInfoProvider() = default;
+ // Returns a nullptr if the HAL does not support microphone info retrieval.
+ virtual Info const* getMicrophoneInfo() = 0;
+};
+
class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
- public CallbackBroker {
+ public CallbackBroker, public MicrophoneInfoProvider {
public:
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
status_t getSupportedDevices(uint32_t *devices) override;
@@ -158,6 +166,11 @@
wp<StreamOutHalInterfaceEventCallback> event;
wp<StreamOutHalInterfaceLatencyModeCallback> latency;
};
+ struct Microphones {
+ enum Status { UNKNOWN, NOT_SUPPORTED, QUERIED };
+ Status status = Status::UNKNOWN;
+ MicrophoneInfoProvider::Info info;
+ };
using Patches = std::map<int32_t /*patch ID*/,
::aidl::android::hardware::audio::core::AudioPatch>;
using PortConfigs = std::map<int32_t /*port config ID*/,
@@ -243,6 +256,9 @@
template<class C> sp<C> getCallbackImpl(void* cookie, wp<C> Callbacks::* field);
template<class C> void setCallbackImpl(void* cookie, wp<C> Callbacks::* field, const sp<C>& cb);
+ // MicrophoneInfoProvider implementation
+ MicrophoneInfoProvider::Info const* getMicrophoneInfo() override;
+
const std::string mInstance;
const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
Ports mPorts;
@@ -250,6 +266,7 @@
int32_t mDefaultOutputPortId = -1;
PortConfigs mPortConfigs;
Patches mPatches;
+ Microphones mMicrophones;
std::mutex mLock;
std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
};
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 5f62ad8..e55fb3f 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -21,6 +21,7 @@
#include <cstdint>
#include <audio_utils/clock.h>
+#include <media/AidlConversion.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionNdk.h>
#include <media/AidlConversionUtil.h>
@@ -39,7 +40,7 @@
using ::aidl::android::hardware::audio::core::IStreamIn;
using ::aidl::android::hardware::audio::core::IStreamOut;
using ::aidl::android::hardware::audio::core::StreamDescriptor;
-using ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout;
+using ::aidl::android::media::audio::common::MicrophoneDynamicInfo;
namespace android {
@@ -818,10 +819,10 @@
StreamInHalAidl::StreamInHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
- const std::shared_ptr<IStreamIn>& stream)
+ const std::shared_ptr<IStreamIn>& stream, const sp<MicrophoneInfoProvider>& micInfoProvider)
: StreamHalAidl("StreamInHalAidl", true /*isInput*/, config, nominalLatency,
std::move(context), getStreamCommon(stream)),
- mStream(stream) {}
+ mStream(stream), mMicInfoProvider(micInfoProvider) {}
status_t StreamInHalAidl::setGain(float gain __unused) {
TIME_CHECK();
@@ -856,11 +857,38 @@
return getObservablePosition(frames, time);
}
-status_t StreamInHalAidl::getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw> *microphones __unused) {
+status_t StreamInHalAidl::getActiveMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) {
+ if (!microphones) {
+ return BAD_VALUE;
+ }
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+ sp<MicrophoneInfoProvider> micInfoProvider = mMicInfoProvider.promote();
+ if (!micInfoProvider) return NO_INIT;
+ auto staticInfo = micInfoProvider->getMicrophoneInfo();
+ if (!staticInfo) return INVALID_OPERATION;
+ std::vector<MicrophoneDynamicInfo> dynamicInfo;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mStream->getActiveMicrophones(&dynamicInfo)));
+ std::vector<media::MicrophoneInfoFw> result;
+ result.reserve(dynamicInfo.size());
+ for (const auto& d : dynamicInfo) {
+ const auto staticInfoIt = std::find_if(staticInfo->begin(), staticInfo->end(),
+ [&](const auto& s) { return s.id == d.id; });
+ if (staticInfoIt != staticInfo->end()) {
+ // Convert into the c++ backend type from the ndk backend type via the legacy structure.
+ audio_microphone_characteristic_t legacy = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_MicrophoneInfos_audio_microphone_characteristic_t(
+ *staticInfoIt, d));
+ media::MicrophoneInfoFw info = VALUE_OR_RETURN_STATUS(
+ ::android::legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(
+ legacy));
+ // Note: info.portId is not filled because it's a bit of framework info.
+ result.push_back(std::move(info));
+ } else {
+ ALOGE("%s: no static info for active microphone with id '%s'", __func__, d.id.c_str());
+ }
+ }
+ *microphones = std::move(result);
return OK;
}
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 85efb35..157e8bb 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -334,6 +334,8 @@
status_t filterAndUpdateOffloadMetadata(AudioParameter ¶meters);
};
+class MicrophoneInfoProvider;
+
class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
public:
// Set the input gain for the audio driver.
@@ -369,11 +371,13 @@
legacy2aidl_SinkMetadata(const StreamInHalInterface::SinkMetadata& legacy);
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn> mStream;
+ const wp<MicrophoneInfoProvider> mMicInfoProvider;
// Can not be constructed directly by clients.
StreamInHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
- const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream);
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream,
+ const sp<MicrophoneInfoProvider>& micInfoProvider);
~StreamInHalAidl() override = default;
};