libaudiohal: Implement retrieval of APM configuration
Add the following interface methods:
- DevicesFactoryHalInterface::getDeviceNames
- DevicesFactoryHalInterface::getSurroundSoundConfig
- DevicesFactoryHalInterface::getEngineConfig
- DeviceHalInterface::getAudioPorts
- DeviceHalInterface::getAudioRoutes
These methods are implemented for the AIDL adapter.
The HIDL adapter does not implement them, and this is
how the framework will know that it needs to fall back
to use the XML config.
Bug: 205884982
Test: m
Change-Id: Iaab5dfa00587b5db6c9cb472dcec6a8e3f6417e0
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 0ae1a1f..ebffaff 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -95,8 +95,35 @@
portConfig->format = config.base.format;
}
+// Note: these converters are for types defined in different AIDL files. Although these
+// AIDL files are copies of each other, however formally these are different types
+// thus we don't use a conversion via a parcelable.
+ConversionResult<media::AudioRoute> ndk2cpp_AudioRoute(const AudioRoute& ndk) {
+ media::AudioRoute cpp;
+ cpp.sourcePortIds.insert(
+ cpp.sourcePortIds.end(), ndk.sourcePortIds.begin(), ndk.sourcePortIds.end());
+ cpp.sinkPortId = ndk.sinkPortId;
+ cpp.isExclusive = ndk.isExclusive;
+ return cpp;
+}
+
} // namespace
+status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
+ auto convertAudioPortFromMap = [](const Ports::value_type& pair) {
+ return ndk2cpp_AudioPort(pair.second);
+ };
+ return ::aidl::android::convertRange(mPorts.begin(), mPorts.end(), ports->begin(),
+ convertAudioPortFromMap);
+}
+
+status_t DeviceHalAidl::getAudioRoutes(std::vector<media::AudioRoute> *routes) {
+ *routes = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::convertContainer<std::vector<media::AudioRoute>>(
+ mRoutes, ndk2cpp_AudioRoute));
+ return OK;
+}
+
status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
@@ -106,8 +133,7 @@
TIME_CHECK();
if (mModule == nullptr) return NO_INIT;
std::vector<AudioPort> ports;
- RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
__func__, mInstance.c_str());
std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
@@ -1273,13 +1299,12 @@
status_t DeviceHalAidl::updateRoutes() {
TIME_CHECK();
- std::vector<AudioRoute> routes;
RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(mModule->getAudioRoutes(&routes)));
- ALOGW_IF(routes.empty(), "%s: module %s returned an empty list of audio routes",
+ statusTFromBinderStatus(mModule->getAudioRoutes(&mRoutes)));
+ ALOGW_IF(mRoutes.empty(), "%s: module %s returned an empty list of audio routes",
__func__, mInstance.c_str());
mRoutingMatrix.clear();
- for (const auto& r : routes) {
+ for (const auto& r : mRoutes) {
for (auto portId : r.sourcePortIds) {
mRoutingMatrix.emplace(r.sinkPortId, portId);
mRoutingMatrix.emplace(portId, r.sinkPortId);
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 7b90744..d5d89f3 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -68,6 +68,10 @@
class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
public CallbackBroker, public MicrophoneInfoProvider {
public:
+ status_t getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) override;
+
+ status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;
+
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
status_t getSupportedDevices(uint32_t *devices) override;
@@ -181,6 +185,7 @@
using PortConfigs = std::map<int32_t /*port config ID*/,
::aidl::android::media::audio::common::AudioPortConfig>;
using Ports = std::map<int32_t /*port ID*/, ::aidl::android::media::audio::common::AudioPort>;
+ using Routes = std::vector<::aidl::android::hardware::audio::core::AudioRoute>;
// Answers the question "whether portID 'first' is reachable from portID 'second'?"
// It's not a map because both portIDs are known. The matrix is symmetric.
using RoutingMatrix = std::set<std::pair<int32_t, int32_t>>;
@@ -279,6 +284,7 @@
int32_t mDefaultOutputPortId = -1;
PortConfigs mPortConfigs;
Patches mPatches;
+ Routes mRoutes;
RoutingMatrix mRoutingMatrix;
Streams mStreams;
Microphones mMicrophones;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 12acebd..a028e3b 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -79,6 +79,15 @@
}
}
+status_t DeviceHalHidl::getAudioPorts(
+ std::vector<media::audio::common::AudioPort> *ports __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalHidl::getAudioRoutes(std::vector<media::AudioRoute> *routes __unused) {
+ return INVALID_OPERATION;
+}
+
status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
@@ -405,6 +414,7 @@
template <typename HalPort>
status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
+ using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
if (mDevice == 0) return NO_INIT;
AudioPort hidlPort;
HidlUtils::audioPortFromHal(*port, &hidlPort);
@@ -447,6 +457,7 @@
}
status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
+ using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPortConfig;
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
AudioPortConfig hidlConfig;
@@ -511,6 +522,7 @@
#endif
status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 132aad7..5f8b376 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -29,6 +29,10 @@
class DeviceHalHidl : public DeviceHalInterface, public CoreConversionHelperHidl
{
public:
+ status_t getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) override;
+
+ status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;
+
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
status_t getSupportedDevices(uint32_t *devices) override;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index 2eaaf5d..8345cd2 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -14,26 +14,67 @@
* limitations under the License.
*/
+#include <memory>
+
#define LOG_TAG "DevicesFactoryHalAidl"
//#define LOG_NDEBUG 0
#include <aidl/android/hardware/audio/core/IModule.h>
#include <android/binder_manager.h>
#include <binder/IServiceManager.h>
-#include <memory>
+#include <media/AidlConversionNdkCpp.h>
+#include <media/AidlConversionUtil.h>
#include <utils/Log.h>
#include "DeviceHalAidl.h"
#include "DevicesFactoryHalAidl.h"
-using namespace ::aidl::android::hardware::audio::core;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::hardware::audio::core::IConfig;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::SurroundSoundConfig;
+using aidl::android::media::audio::common::AudioHalEngineConfig;
using ::android::detail::AudioHalVersionInfo;
namespace android {
-DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig)
- : mIConfig(std::move(iconfig)) {
- ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
+namespace {
+
+ConversionResult<media::SurroundSoundConfig::SurroundFormatFamily>
+ndk2cpp_SurroundSoundConfigFormatFamily(const SurroundSoundConfig::SurroundFormatFamily& ndk) {
+ media::SurroundSoundConfig::SurroundFormatFamily cpp;
+ cpp.primaryFormat = VALUE_OR_RETURN(ndk2cpp_AudioFormatDescription(ndk.primaryFormat));
+ cpp.subFormats = VALUE_OR_RETURN(::aidl::android::convertContainer<std::vector<
+ media::audio::common::AudioFormatDescription>>(ndk.subFormats,
+ ndk2cpp_AudioFormatDescription));
+ return cpp;
+}
+
+ConversionResult<media::SurroundSoundConfig>
+ndk2cpp_SurroundSoundConfig(const SurroundSoundConfig& ndk) {
+ media::SurroundSoundConfig cpp;
+ cpp.formatFamilies = VALUE_OR_RETURN(::aidl::android::convertContainer<std::vector<
+ media::SurroundSoundConfig::SurroundFormatFamily>>(ndk.formatFamilies,
+ ndk2cpp_SurroundSoundConfigFormatFamily));
+ return cpp;
+}
+
+} // namespace
+
+DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> config)
+ : mConfig(std::move(config)) {
+}
+
+status_t DevicesFactoryHalAidl::getDeviceNames(std::vector<std::string> *names) {
+ if (names == nullptr) {
+ return BAD_VALUE;
+ }
+ AServiceManager_forEachDeclaredInstance(IModule::descriptor, static_cast<void*>(names),
+ [](const char* instance, void* context) {
+ if (strcmp(instance, "default") == 0) instance = "primary";
+ static_cast<decltype(names)>(context)->push_back(instance);
+ });
+ return OK;
}
// Opens a device with the specified name. To close the device, it is
@@ -43,19 +84,22 @@
return BAD_VALUE;
}
+ // FIXME: Remove this call and the check for the supported module names
+ // after implementing retrieval of module names on the framework side.
+ // Currently it is still using the legacy XML config.
+ std::vector<std::string> deviceNames;
+ if (status_t status = getDeviceNames(&deviceNames); status != OK) {
+ return status;
+ }
std::shared_ptr<IModule> service;
- // FIXME: Normally we will list available HAL modules and connect to them,
- // however currently we still get the list of module names from the config.
- // Since the example service does not have all modules, the SM will wait
- // for the missing ones forever.
- if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0 || strcmp(name, "usb") == 0) {
+ if (std::find(deviceNames.begin(), deviceNames.end(), name) != deviceNames.end()) {
if (strcmp(name, "primary") == 0) name = "default";
auto serviceName = std::string(IModule::descriptor) + "/" + name;
service = IModule::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
}
- // If the service is a nullptr, the device will not be really functional,
+ // If the service is a nullptr, the device object will not be really functional,
// but will not crash either.
*device = sp<DeviceHalAidl>::make(name, service);
return OK;
@@ -97,18 +141,28 @@
AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
int32_t versionNumber = 0;
- if (mIConfig != 0) {
- if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
- !status.isOk()) {
- ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
- }
- } else {
- ALOGW("%s no IConfig instance", __func__);
+ if (ndk::ScopedAStatus status = mConfig->getInterfaceVersion(&versionNumber); !status.isOk()) {
+ ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
}
// AIDL does not have minor version, fill 0 for all versions
return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
}
+status_t DevicesFactoryHalAidl::getSurroundSoundConfig(media::SurroundSoundConfig *config) {
+ SurroundSoundConfig ndkConfig;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mConfig->getSurroundSoundConfig(&ndkConfig)));
+ *config = VALUE_OR_RETURN_STATUS(ndk2cpp_SurroundSoundConfig(ndkConfig));
+ return OK;
+}
+
+status_t DevicesFactoryHalAidl::getEngineConfig(
+ media::audio::common::AudioHalEngineConfig *config) {
+ AudioHalEngineConfig ndkConfig;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mConfig->getEngineConfig(&ndkConfig)));
+ *config = VALUE_OR_RETURN_STATUS(ndk2cpp_AudioHalEngineConfig(ndkConfig));
+ return OK;
+}
+
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto serviceName = std::string(IConfig::descriptor) + "/default";
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index cb627bc..21957bc 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -26,7 +26,9 @@
{
public:
explicit DevicesFactoryHalAidl(
- std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> iConfig);
+ std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> config);
+
+ status_t getDeviceNames(std::vector<std::string> *names) override;
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
@@ -38,8 +40,12 @@
android::detail::AudioHalVersionInfo getHalVersion() const override;
+ status_t getSurroundSoundConfig(media::SurroundSoundConfig *config) override;
+
+ status_t getEngineConfig(media::audio::common::AudioHalEngineConfig *config) override;
+
private:
- const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mIConfig;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mConfig;
~DevicesFactoryHalAidl() = default;
};
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 9f06f83..eef60b5 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -106,6 +106,10 @@
}
#endif
+status_t DevicesFactoryHalHidl::getDeviceNames(std::vector<std::string> *names __unused) {
+ return INVALID_OPERATION;
+}
+
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
auto factories = copyDeviceFactories();
if (factories.empty()) return NO_INIT;
@@ -232,6 +236,16 @@
return AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, MAJOR_VERSION, MINOR_VERSION);
}
+status_t DevicesFactoryHalHidl::getSurroundSoundConfig(
+ media::SurroundSoundConfig *config __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t DevicesFactoryHalHidl::getEngineConfig(
+ media::audio::common::AudioHalEngineConfig *config __unused) {
+ return INVALID_OPERATION;
+}
+
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index 5294728..3285af7 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -37,6 +37,8 @@
explicit DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory);
void onFirstRef() override;
+ status_t getDeviceNames(std::vector<std::string> *names) override;
+
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
status_t openDevice(const char *name, sp<DeviceHalInterface> *device) override;
@@ -47,6 +49,10 @@
android::detail::AudioHalVersionInfo getHalVersion() const override;
+ status_t getSurroundSoundConfig(media::SurroundSoundConfig *config) override;
+
+ status_t getEngineConfig(media::audio::common::AudioHalEngineConfig *config) override;
+
private:
friend class ServiceNotificationListener;
void addDeviceFactory(sp<IDevicesFactory> factory, bool needToNotify);