Plumb APM configuration retrieval from HAL
Add 'AudioHwModule' and 'AudioPolicyConfig' AIDL types
to represent the APM configuration. Add 'getAudioPolicyConfig'
method to 'IAudioFlinger' interface. Implement it for
the AIDL HAL case. Add missing method to 'DeviceHalInterface'.
Remove 'isSpeakerDrcEnabled' from 'AudioPolicyConfig'
as it is not used anywhere in the framework.
Bug: 205884982
Test: atest audiopolicy_tests
Test: atest audiosystem_tests
Test: atest audio_health_tests
Test: m audiopolicy_fuzzer
Change-Id: Icaf043085373ec661be37d4a7a5ed4356aeb4bbe
diff --git a/media/audioaidlconversion/AidlConversionNdkCpp.cpp b/media/audioaidlconversion/AidlConversionNdkCpp.cpp
index 36f6128..c64a074 100644
--- a/media/audioaidlconversion/AidlConversionNdkCpp.cpp
+++ b/media/audioaidlconversion/AidlConversionNdkCpp.cpp
@@ -123,6 +123,7 @@
GENERATE_CONVERTERS(android::media::audio::common, AudioHalEngineConfig);
GENERATE_CONVERTERS(android::media::audio::common, AudioMMapPolicyInfo);
GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMMapPolicyType);
+GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMode);
GENERATE_CONVERTERS(android::media::audio::common, AudioPort);
} // namespace android
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h b/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h
index 09f1c22..f4822aa 100644
--- a/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h
+++ b/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h
@@ -23,11 +23,13 @@
#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
#include <aidl/android/media/audio/common/AudioMMapPolicyInfo.h>
#include <aidl/android/media/audio/common/AudioMMapPolicyType.h>
+#include <aidl/android/media/audio/common/AudioMode.h>
#include <aidl/android/media/audio/common/AudioPort.h>
#include <android/media/audio/common/AudioFormatDescription.h>
#include <android/media/audio/common/AudioHalEngineConfig.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
+#include <android/media/audio/common/AudioMode.h>
#include <android/media/audio/common/AudioPort.h>
#include <media/AidlConversionUtil.h>
@@ -43,6 +45,7 @@
DECLARE_CONVERTERS(android::media::audio::common, AudioHalEngineConfig);
DECLARE_CONVERTERS(android::media::audio::common, AudioMMapPolicyInfo);
DECLARE_CONVERTERS(android::media::audio::common, AudioMMapPolicyType);
+DECLARE_CONVERTERS(android::media::audio::common, AudioMode);
DECLARE_CONVERTERS(android::media::audio::common, AudioPort);
#undef DECLARE_CONVERTERS
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index d5bbb52..7122af1 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -287,9 +287,11 @@
"aidl/android/media/AudioFlag.aidl",
"aidl/android/media/AudioGainSys.aidl",
"aidl/android/media/AudioHalVersion.aidl",
+ "aidl/android/media/AudioHwModule.aidl",
"aidl/android/media/AudioIoConfigEvent.aidl",
"aidl/android/media/AudioIoDescriptor.aidl",
"aidl/android/media/AudioPatchFw.aidl",
+ "aidl/android/media/AudioPolicyConfig.aidl",
"aidl/android/media/AudioPortFw.aidl",
"aidl/android/media/AudioPortSys.aidl",
"aidl/android/media/AudioPortConfigFw.aidl",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index b731702..4527e0f 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -2529,6 +2529,14 @@
return af->supportsBluetoothVariableLatency(support);
}
+status_t AudioSystem::getAudioPolicyConfig(media::AudioPolicyConfig *config) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+ return af->getAudioPolicyConfig(config);
+}
+
class CaptureStateListenerImpl : public media::BnCaptureStateListener,
public IBinder::DeathRecipient {
public:
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 4384f97..7b33a00 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -887,6 +887,16 @@
return statusTFromBinderStatus(mDelegate->invalidateTracks(portIdsAidl));
}
+status_t AudioFlingerClientAdapter::getAudioPolicyConfig(media::AudioPolicyConfig *config) {
+ if (config == nullptr) {
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mDelegate->getAudioPolicyConfig(config)));
+
+ return NO_ERROR;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
AudioFlingerServerAdapter::AudioFlingerServerAdapter(
@@ -1429,4 +1439,8 @@
return Status::ok();
}
+Status AudioFlingerServerAdapter::getAudioPolicyConfig(media::AudioPolicyConfig* _aidl_return) {
+ return Status::fromStatusT(mDelegate->getAudioPolicyConfig(_aidl_return));
+}
+
} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/AudioHwModule.aidl b/media/libaudioclient/aidl/android/media/AudioHwModule.aidl
new file mode 100644
index 0000000..9251400
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioHwModule.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.media;
+
+import android.media.audio.common.AudioPort;
+import android.media.AudioRoute;
+
+/*
+ * A representation of a HAL module configuration.
+ * {@hide}
+ */
+parcelable AudioHwModule {
+ int /* audio_module_handle_t */ handle;
+ @utf8InCpp String name;
+ AudioPort[] ports;
+ AudioRoute[] routes;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPolicyConfig.aidl b/media/libaudioclient/aidl/android/media/AudioPolicyConfig.aidl
new file mode 100644
index 0000000..87767c2
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPolicyConfig.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.media;
+
+import android.media.AudioHwModule;
+import android.media.SurroundSoundConfig;
+import android.media.audio.common.AudioHalEngineConfig;
+import android.media.audio.common.AudioMode;
+
+/*
+ * Audio policy configuration. Functionally replaces the APM XML file.
+ * {@hide}
+ */
+parcelable AudioPolicyConfig {
+ AudioHwModule[] modules;
+ AudioMode[] supportedModes;
+ SurroundSoundConfig surroundSoundConfig;
+ AudioHalEngineConfig engineConfig;
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 884cd30..6412810 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -17,6 +17,7 @@
package android.media;
import android.media.AudioPatchFw;
+import android.media.AudioPolicyConfig;
import android.media.AudioPortFw;
import android.media.AudioPortConfigFw;
import android.media.AudioUniqueIdUse;
@@ -281,6 +282,12 @@
*/
void invalidateTracks(in int[] /* audio_port_handle_t[] */ portIds);
+ /**
+ * Only implemented for AIDL. Provides the APM configuration which
+ * used to be in the XML file.
+ */
+ AudioPolicyConfig getAudioPolicyConfig();
+
// When adding a new method, please review and update
// IAudioFlinger.h AudioFlingerServerAdapter::Delegate::TransactionCode
// AudioFlinger.cpp AudioFlinger::onTransactWrapper()
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 1bfe34d..8f8c9dd 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -23,6 +23,7 @@
#include <vector>
#include <android/content/AttributionSourceState.h>
+#include <android/media/AudioPolicyConfig.h>
#include <android/media/AudioPortFw.h>
#include <android/media/AudioVibratorInfo.h>
#include <android/media/BnAudioFlingerClient.h>
@@ -663,6 +664,8 @@
audio_port_handle_t portId,
uid_t uid);
+ static status_t getAudioPolicyConfig(media::AudioPolicyConfig *config);
+
// A listener for capture state changes.
class CaptureStateListener : public virtual RefBase {
public:
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 6e28d51..2e2ef65 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -382,6 +382,8 @@
virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled) = 0;
virtual status_t supportsBluetoothVariableLatency(bool* support) = 0;
+
+ virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) = 0;
};
/**
@@ -495,6 +497,7 @@
status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose) override;
status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
+ status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -594,6 +597,8 @@
media::BnAudioFlingerService::TRANSACTION_supportsBluetoothVariableLatency,
GET_SOUND_DOSE_INTERFACE = media::BnAudioFlingerService::TRANSACTION_getSoundDoseInterface,
INVALIDATE_TRACKS = media::BnAudioFlingerService::TRANSACTION_invalidateTracks,
+ GET_AUDIO_POLICY_CONFIG =
+ media::BnAudioFlingerService::TRANSACTION_getAudioPolicyConfig,
};
protected:
@@ -726,6 +731,7 @@
Status getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* _aidl_return) override;
Status invalidateTracks(const std::vector<int32_t>& portIds) override;
+ Status getAudioPolicyConfig(media::AudioPolicyConfig* _aidl_return) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
};
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index f993907..865d1d6 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -107,8 +107,26 @@
return cpp;
}
+template<typename T>
+std::shared_ptr<T> retrieveSubInterface(const std::shared_ptr<IModule>& module,
+ ::ndk::ScopedAStatus (IModule::*getT)(std::shared_ptr<T>*)) {
+ if (module != nullptr) {
+ std::shared_ptr<T> instance;
+ if (auto status = (module.get()->*getT)(&instance); status.isOk()) {
+ return instance;
+ }
+ }
+ return nullptr;
+}
+
} // namespace
+DeviceHalAidl::DeviceHalAidl(const std::string& instance, const std::shared_ptr<IModule>& module)
+ : ConversionHelperAidl("DeviceHalAidl"),
+ mInstance(instance), mModule(module),
+ mTelephony(retrieveSubInterface<ITelephony>(module, &IModule::getTelephony)) {
+}
+
status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
auto convertAudioPortFromMap = [](const Ports::value_type& pair) {
return ndk2cpp_AudioPort(pair.second);
@@ -124,6 +142,22 @@
return OK;
}
+status_t DeviceHalAidl::getSupportedModes(std::vector<media::audio::common::AudioMode> *modes) {
+ TIME_CHECK();
+ if (modes == nullptr) {
+ return BAD_VALUE;
+ }
+ if (mModule == nullptr) return NO_INIT;
+ if (mTelephony == nullptr) return INVALID_OPERATION;
+ std::vector<AudioMode> aidlModes;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(mTelephony->getSupportedAudioModes(&aidlModes)));
+ *modes = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::convertContainer<std::vector<media::audio::common::AudioMode>>(
+ aidlModes, ndk2cpp_AudioMode));
+ return OK;
+}
+
status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
@@ -175,17 +209,14 @@
status_t DeviceHalAidl::setVoiceVolume(float volume) {
TIME_CHECK();
if (!mModule) return NO_INIT;
- std::shared_ptr<ITelephony> telephony;
- if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
- status.isOk() && telephony != nullptr) {
- ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
- RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(telephony->setTelecomConfig(inConfig, &outConfig)));
- ALOGW_IF(outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
- "%s: the resulting voice volume %f is not the same as requested %f",
- __func__, outConfig.voiceVolume.value().value, volume);
- }
- return INVALID_OPERATION;
+ if (mTelephony == nullptr) return INVALID_OPERATION;
+ ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(mTelephony->setTelecomConfig(inConfig, &outConfig)));
+ ALOGW_IF(outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
+ "%s: the resulting voice volume %f is not the same as requested %f",
+ __func__, outConfig.voiceVolume.value().value, volume);
+ return OK;
}
status_t DeviceHalAidl::setMasterVolume(float volume) {
@@ -204,10 +235,8 @@
TIME_CHECK();
if (!mModule) return NO_INIT;
AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
- std::shared_ptr<ITelephony> telephony;
- if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
- status.isOk() && telephony != nullptr) {
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(telephony->switchAudioMode(audioMode)));
+ if (mTelephony != nullptr) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mTelephony->switchAudioMode(audioMode)));
}
return statusTFromBinderStatus(mModule->updateAudioMode(audioMode));
}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index f2c64de..5c9950b 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -73,6 +73,8 @@
status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;
+ status_t getSupportedModes(std::vector<media::audio::common::AudioMode> *modes) 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;
@@ -201,8 +203,7 @@
// Must not be constructed directly by clients.
DeviceHalAidl(
const std::string& instance,
- const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
- : ConversionHelperAidl("DeviceHalAidl"), mInstance(instance), mModule(module) {}
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module);
~DeviceHalAidl() override = default;
@@ -286,6 +287,7 @@
const std::string mInstance;
const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::ITelephony> mTelephony;
std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>
mSoundDose = nullptr;
Ports mPorts;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index d67cbdc..826461f 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -113,6 +113,11 @@
return INVALID_OPERATION;
}
+status_t DeviceHalHidl::getSupportedModes(
+ std::vector<media::audio::common::AudioMode> *modes __unused) {
+ return INVALID_OPERATION;
+}
+
status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 7222f03..c5addde 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -33,6 +33,8 @@
status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;
+ status_t getSupportedModes(std::vector<media::audio::common::AudioMode> *modes) 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/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 45f2922..71e5e7a 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -19,6 +19,7 @@
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
+#include <android/media/audio/common/AudioMode.h>
#include <android/media/audio/common/AudioPort.h>
#include <android/media/AudioRoute.h>
#include <error/Result.h>
@@ -44,6 +45,8 @@
virtual status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) = 0;
+ virtual status_t getSupportedModes(std::vector<media::audio::common::AudioMode> *modes) = 0;
+
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
virtual status_t getSupportedDevices(uint32_t *devices) = 0;