Decouple the configuration from the AudioPolicyManager
Promote AudioPolicyConfig to a full class, not just a "view"
on the APM data. This allows separating initialization of
the APM config from the initialization of the APM itself.
Thus, the APM receives a fully initialized config upon
its creation, regardless of the way the config data has been
obtained.
Bug: 205884982
Test: atest audiopolicy_tests
Test: atest audiosystem_tests
Test: atest audio_health_tests
Test: m audiopolicy_fuzzer
(cherry picked from https://android-review.googlesource.com/q/commit:b0fbc1b40ddebb274b7a0bea811440507c357d82)
Merged-In: I334d16e762499a0292540e6abae4e177480d6235
Change-Id: I334d16e762499a0292540e6abae4e177480d6235
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index 92a5628..1d570b7 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -15,6 +15,7 @@
"src/AudioInputDescriptor.cpp",
"src/AudioOutputDescriptor.cpp",
"src/AudioPatch.cpp",
+ "src/AudioPolicyConfig.cpp",
"src/AudioPolicyMix.cpp",
"src/AudioProfileVectorHelper.cpp",
"src/AudioRoute.cpp",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index a62d3f0..b24fce8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -16,62 +16,56 @@
#pragma once
+#include <string>
#include <unordered_map>
#include <unordered_set>
+#include <vector>
-#include <AudioPatch.h>
#include <DeviceDescriptor.h>
-#include <IOProfile.h>
#include <HwModule.h>
-#include <PolicyAudioPort.h>
-#include <AudioInputDescriptor.h>
-#include <AudioOutputDescriptor.h>
-#include <AudioPolicyMix.h>
-#include <EffectDescriptor.h>
-#include <SoundTriggerSession.h>
-#include <media/AudioProfile.h>
+#include <error/Result.h>
+#include <utils/StrongPointer.h>
+#include <utils/RefBase.h>
namespace android {
-// This class gathers together various bits of AudioPolicyManager
-// configuration, which are usually filled out as a result of parsing
-// the audio_policy_configuration.xml file.
+// This class gathers together various bits of AudioPolicyManager configuration. It can be filled
+// out either as a result of parsing the audio_policy_configuration.xml file, from the HAL data, or
+// to default fallback data.
//
-// Note that AudioPolicyConfig doesn't own some of the data,
-// it simply proxies access to the fields of AudioPolicyManager
-// class. Be careful about the fields that are references,
-// e.g. 'mOutputDevices'. This also means that it's impossible
-// to implement "deep copying" of this class without re-designing it.
-class AudioPolicyConfig
+// The data in this class is immutable once loaded, this is why a pointer to a const is returned
+// from the factory methods. However, this does not prevent modifications of data bits that
+// are held inside collections, for example, individual modules, devices, etc.
+class AudioPolicyConfig : public RefBase
{
public:
- AudioPolicyConfig(HwModuleCollection &hwModules,
- DeviceVector &outputDevices,
- DeviceVector &inputDevices,
- sp<DeviceDescriptor> &defaultOutputDevice)
- : mHwModules(hwModules),
- mOutputDevices(outputDevices),
- mInputDevices(inputDevices),
- mDefaultOutputDevice(defaultOutputDevice) {
- clear();
- }
+ // Surround formats, with an optional list of subformats that are equivalent from users' POV.
+ using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;
- void clear() {
- mSource = {};
- mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
- mHwModules.clear();
- mOutputDevices.clear();
- mInputDevices.clear();
- mDefaultOutputDevice.clear();
- mIsSpeakerDrcEnabled = false;
- mIsCallScreenModeSupported = false;
- mSurroundFormats.clear();
- }
+ // The source used to indicate the default fallback configuration.
+ static const constexpr char* const kDefaultConfigSource = "AudioPolicyConfig::setDefault";
+
+ // Creates the default (fallback) configuration.
+ static sp<const AudioPolicyConfig> createDefault();
+ // Attempts to load the configuration from the XML file, falls back to default on failure.
+ // If the XML file path is not provided, uses `audio_get_audio_policy_config_file` function.
+ static sp<const AudioPolicyConfig> loadFromApmXmlConfigWithFallback(
+ const std::string& xmlFilePath = "");
+ // The factory method to use in APM tests which craft the configuration manually.
+ static sp<AudioPolicyConfig> createWritableForTests();
+ // The factory method to use in APM tests which use a custom XML file.
+ static error::Result<sp<AudioPolicyConfig>> loadFromCustomXmlConfigForTests(
+ const std::string& xmlFilePath);
+ // The factory method to use in VTS tests. If the 'configPath' is empty,
+ // it is determined automatically from the list of known config paths.
+ static error::Result<sp<AudioPolicyConfig>> loadFromCustomXmlConfigForVtsTests(
+ const std::string& configPath, const std::string& xmlFileName);
+
+ ~AudioPolicyConfig() = default;
const std::string& getSource() const {
return mSource;
}
-
void setSource(const std::string& file) {
mSource = file;
}
@@ -79,16 +73,24 @@
const std::string& getEngineLibraryNameSuffix() const {
return mEngineLibraryNameSuffix;
}
-
void setEngineLibraryNameSuffix(const std::string& suffix) {
mEngineLibraryNameSuffix = suffix;
}
+ const HwModuleCollection& getHwModules() const { return mHwModules; }
void setHwModules(const HwModuleCollection &hwModules)
{
mHwModules = hwModules;
}
+ const DeviceVector& getInputDevices() const
+ {
+ return mInputDevices;
+ }
+ const DeviceVector& getOutputDevices() const
+ {
+ return mOutputDevices;
+ }
void addDevice(const sp<DeviceDescriptor> &device)
{
if (audio_is_output_device(device->type())) {
@@ -97,128 +99,70 @@
mInputDevices.add(device);
}
}
-
void addInputDevices(const DeviceVector &inputDevices)
{
mInputDevices.add(inputDevices);
}
-
void addOutputDevices(const DeviceVector &outputDevices)
{
mOutputDevices.add(outputDevices);
}
- bool isSpeakerDrcEnabled() const { return mIsSpeakerDrcEnabled; }
+ const sp<DeviceDescriptor>& getDefaultOutputDevice() const { return mDefaultOutputDevice; }
+ void setDefaultOutputDevice(const sp<DeviceDescriptor> &defaultDevice)
+ {
+ mDefaultOutputDevice = defaultDevice;
+ }
+ bool isSpeakerDrcEnabled() const { return mIsSpeakerDrcEnabled; }
void setSpeakerDrcEnabled(bool isSpeakerDrcEnabled)
{
mIsSpeakerDrcEnabled = isSpeakerDrcEnabled;
}
bool isCallScreenModeSupported() const { return mIsCallScreenModeSupported; }
-
void setCallScreenModeSupported(bool isCallScreenModeSupported)
{
mIsCallScreenModeSupported = isCallScreenModeSupported;
}
-
- const HwModuleCollection getHwModules() const { return mHwModules; }
-
- const DeviceVector &getInputDevices() const
- {
- return mInputDevices;
- }
-
- const DeviceVector &getOutputDevices() const
- {
- return mOutputDevices;
- }
-
- void setDefaultOutputDevice(const sp<DeviceDescriptor> &defaultDevice)
- {
- mDefaultOutputDevice = defaultDevice;
- }
-
- const sp<DeviceDescriptor> &getDefaultOutputDevice() const { return mDefaultOutputDevice; }
-
- void setDefault(void)
- {
- mSource = "AudioPolicyConfig::setDefault";
- mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
- mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
- mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
- sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
- defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
- sp<AudioProfile> micProfile = new AudioProfile(
- AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000);
- defaultInputDevice->addAudioProfile(micProfile);
- mOutputDevices.add(mDefaultOutputDevice);
- mInputDevices.add(defaultInputDevice);
-
- sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
- mHwModules.add(module);
-
- sp<OutputProfile> outProfile = new OutputProfile("primary");
- outProfile->addAudioProfile(
- new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
- outProfile->addSupportedDevice(mDefaultOutputDevice);
- outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
- module->addOutputProfile(outProfile);
-
- sp<InputProfile> inProfile = new InputProfile("primary");
- inProfile->addAudioProfile(micProfile);
- inProfile->addSupportedDevice(defaultInputDevice);
- module->addInputProfile(inProfile);
-
- setDefaultSurroundFormats();
- }
-
- // Surround formats, with an optional list of subformats that are equivalent from users' POV.
- using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;
-
const SurroundFormats &getSurroundFormats() const
{
return mSurroundFormats;
}
-
+ void setDefaultSurroundFormats();
void setSurroundFormats(const SurroundFormats &surroundFormats)
{
mSurroundFormats = surroundFormats;
}
-
- void setDefaultSurroundFormats()
+ void setSurroundFormats(SurroundFormats &&surroundFormats)
{
- mSurroundFormats = {
- {AUDIO_FORMAT_AC3, {}},
- {AUDIO_FORMAT_E_AC3, {}},
- {AUDIO_FORMAT_DTS, {}},
- {AUDIO_FORMAT_DTS_HD, {}},
- {AUDIO_FORMAT_DTS_HD_MA, {}},
- {AUDIO_FORMAT_DTS_UHD, {}},
- {AUDIO_FORMAT_DTS_UHD_P2, {}},
- {AUDIO_FORMAT_AAC_LC, {
- AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
- AUDIO_FORMAT_AAC_XHE}},
- {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
- {AUDIO_FORMAT_E_AC3_JOC, {}},
- {AUDIO_FORMAT_AC4, {}}};
+ mSurroundFormats = std::move(surroundFormats);
}
+ void setDefault();
+
private:
+ friend class sp<AudioPolicyConfig>;
+
static const constexpr char* const kDefaultEngineLibraryNameSuffix = "default";
- std::string mSource;
- std::string mEngineLibraryNameSuffix;
- HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
- DeviceVector &mOutputDevices;
- DeviceVector &mInputDevices;
- sp<DeviceDescriptor> &mDefaultOutputDevice;
+ AudioPolicyConfig() = default;
+
+ void augmentData();
+ status_t loadFromXml(const std::string& xmlFilePath, bool forVts);
+
+ std::string mSource; // Not kDefaultConfigSource. Empty source means an empty config.
+ std::string mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
+ HwModuleCollection mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
+ DeviceVector mOutputDevices;
+ DeviceVector mInputDevices;
+ sp<DeviceDescriptor> mDefaultOutputDevice;
// TODO: remove when legacy conf file is removed. true on devices that use DRC on the
// DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
// Note: remove also speaker_drc_enabled from global configuration of XML config file.
- bool mIsSpeakerDrcEnabled;
- bool mIsCallScreenModeSupported;
+ bool mIsSpeakerDrcEnabled = false;
+ bool mIsCallScreenModeSupported = false;
SurroundFormats mSurroundFormats;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
new file mode 100644
index 0000000..575a6c5
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#define LOG_TAG "APM_Config"
+
+#include <AudioPolicyConfig.h>
+#include <IOProfile.h>
+#include <Serializer.h>
+#include <media/AudioProfile.h>
+#include <system/audio.h>
+#include <system/audio_config.h>
+#include <utils/Log.h>
+
+namespace android {
+
+// static
+sp<const AudioPolicyConfig> AudioPolicyConfig::createDefault() {
+ auto config = sp<AudioPolicyConfig>::make();
+ config->setDefault();
+ return config;
+}
+
+// static
+sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
+ const std::string& xmlFilePath) {
+ const std::string filePath =
+ xmlFilePath.empty() ? audio_get_audio_policy_config_file() : xmlFilePath;
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromXml(filePath, false /*forVts*/); status == NO_ERROR) {
+ return config;
+ } else {
+ return createDefault();
+ }
+}
+
+// static
+sp<AudioPolicyConfig> AudioPolicyConfig::createWritableForTests() {
+ return sp<AudioPolicyConfig>::make();
+}
+
+// static
+error::Result<sp<AudioPolicyConfig>> AudioPolicyConfig::loadFromCustomXmlConfigForTests(
+ const std::string& xmlFilePath) {
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromXml(xmlFilePath, false /*forVts*/); status == NO_ERROR) {
+ return config;
+ } else {
+ return base::unexpected(status);
+ }
+}
+
+// static
+error::Result<sp<AudioPolicyConfig>> AudioPolicyConfig::loadFromCustomXmlConfigForVtsTests(
+ const std::string& configPath, const std::string& xmlFileName) {
+ auto filePath = configPath;
+ if (filePath.empty()) {
+ for (const auto& location : audio_get_configuration_paths()) {
+ std::string path = location + '/' + xmlFileName;
+ if (access(path.c_str(), F_OK) == 0) {
+ filePath = location;
+ break;
+ }
+ }
+ }
+ if (filePath.empty()) {
+ ALOGE("Did not find a config file \"%s\" among known config paths", xmlFileName.c_str());
+ return base::unexpected(BAD_VALUE);
+ }
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromXml(filePath + "/" + xmlFileName, true /*forVts*/);
+ status == NO_ERROR) {
+ return config;
+ } else {
+ return base::unexpected(status);
+ }
+}
+
+void AudioPolicyConfig::augmentData() {
+ // If microphones address is empty, set it according to device type
+ for (size_t i = 0; i < mInputDevices.size(); i++) {
+ if (mInputDevices[i]->address().empty()) {
+ if (mInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ mInputDevices[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+ } else if (mInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
+ mInputDevices[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
+ }
+ }
+ }
+}
+
+status_t AudioPolicyConfig::loadFromXml(const std::string& xmlFilePath, bool forVts) {
+ if (xmlFilePath.empty()) {
+ ALOGE("Audio policy configuration file name is empty");
+ return BAD_VALUE;
+ }
+ status_t status = forVts ? deserializeAudioPolicyFileForVts(xmlFilePath.c_str(), this)
+ : deserializeAudioPolicyFile(xmlFilePath.c_str(), this);
+ if (status == NO_ERROR) {
+ mSource = xmlFilePath;
+ augmentData();
+ } else {
+ ALOGE("Could not load audio policy from the configuration file \"%s\": %d",
+ xmlFilePath.c_str(), status);
+ }
+ return status;
+}
+
+void AudioPolicyConfig::setDefault() {
+ mSource = kDefaultConfigSource;
+ mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
+
+ mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
+ mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
+ sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
+ defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
+ sp<AudioProfile> micProfile = new AudioProfile(
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000);
+ defaultInputDevice->addAudioProfile(micProfile);
+ mOutputDevices.add(mDefaultOutputDevice);
+ mInputDevices.add(defaultInputDevice);
+
+ sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
+ mHwModules.add(module);
+
+ sp<OutputProfile> outProfile = new OutputProfile("primary");
+ outProfile->addAudioProfile(
+ new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
+ outProfile->addSupportedDevice(mDefaultOutputDevice);
+ outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
+ module->addOutputProfile(outProfile);
+
+ sp<InputProfile> inProfile = new InputProfile("primary");
+ inProfile->addAudioProfile(micProfile);
+ inProfile->addSupportedDevice(defaultInputDevice);
+ module->addInputProfile(inProfile);
+
+ setDefaultSurroundFormats();
+ augmentData();
+}
+
+void AudioPolicyConfig::setDefaultSurroundFormats() {
+ mSurroundFormats = {
+ {AUDIO_FORMAT_AC3, {}},
+ {AUDIO_FORMAT_E_AC3, {}},
+ {AUDIO_FORMAT_DTS, {}},
+ {AUDIO_FORMAT_DTS_HD, {}},
+ {AUDIO_FORMAT_DTS_HD_MA, {}},
+ {AUDIO_FORMAT_DTS_UHD, {}},
+ {AUDIO_FORMAT_DTS_UHD_P2, {}},
+ {AUDIO_FORMAT_AAC_LC, {
+ AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
+ AUDIO_FORMAT_AAC_XHE}},
+ {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
+ {AUDIO_FORMAT_E_AC3_JOC, {}},
+ {AUDIO_FORMAT_AC4, {}}};
+}
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index d446e96..1b48dc3 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -29,6 +29,7 @@
#include <utils/StrongPointer.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include "IOProfile.h"
#include "Serializer.h"
#include "TypeConverter.h"
@@ -907,7 +908,6 @@
{
PolicySerializer serializer;
status_t status = serializer.deserialize(fileName, config);
- if (status != OK) config->clear();
return status;
}
@@ -915,7 +915,6 @@
{
PolicySerializer serializer;
status_t status = serializer.deserialize(fileName, config, true /*ignoreVendorExtensions*/);
- if (status != OK) config->clear();
return status;
}
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 14f565b..8793085 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -216,8 +216,9 @@
virtual void process();
protected:
+ sp<AudioPolicyConfig> mConfig{AudioPolicyConfig::createWritableForTests()};
std::unique_ptr<AudioPolicyManagerTestClient> mClient{new AudioPolicyManagerTestClient};
- std::unique_ptr<AudioPolicyTestManager> mManager{new AudioPolicyTestManager(mClient.get())};
+ std::unique_ptr<AudioPolicyTestManager> mManager;
FuzzedDataProvider *mFdp;
};
@@ -230,7 +231,10 @@
}
// init code
SetUpManagerConfig();
-
+ if (mConfig == nullptr) {
+ return false;
+ }
+ mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get()));
if (mManager->initialize() != NO_ERROR) {
return false;
}
@@ -240,7 +244,7 @@
return true;
}
-void AudioPolicyManagerFuzzer::SetUpManagerConfig() { mManager->getConfig().setDefault(); }
+void AudioPolicyManagerFuzzer::SetUpManagerConfig() { mConfig->setDefault(); }
bool AudioPolicyManagerFuzzer::getOutputForAttr(
audio_port_handle_t *selectedDeviceId, audio_format_t format, audio_channel_mask_t channelMask,
@@ -408,7 +412,11 @@
}
void AudioPolicyManagerFuzzerWithConfigurationFile::SetUpManagerConfig() {
- deserializeAudioPolicyFile(getConfigFile().c_str(), &mManager->getConfig());
+ const std::string configFilePath = getConfigFile();
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(configFilePath);
+ mConfig = result.ok() ? mConfig = result.value() : nullptr;
+ ALOGE_IF(!result.ok(), "%s: Failed to deserialize \"%s\": %d",
+ __func__, configFilePath.c_str(), result.error());
}
void AudioPolicyManagerFuzzerWithConfigurationFile::traverseAndFuzzXML(xmlDocPtr pDoc,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b678662..b558fed 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1330,7 +1330,7 @@
*selectedDeviceId = getFirstDeviceId(outputDevices);
for (auto &outputDevice : outputDevices) {
- if (outputDevice->getId() == getConfig().getDefaultOutputDevice()->getId()) {
+ if (outputDevice->getId() == mConfig->getDefaultOutputDevice()->getId()) {
*selectedDeviceId = outputDevice->getId();
break;
}
@@ -1915,7 +1915,8 @@
}
bool AudioPolicyManager::msdHasPatchesToAllDevices(const AudioDeviceTypeAddrVector& devices) {
- DeviceVector devicesToCheck = mOutputDevicesAll.getDevicesFromDeviceTypeAddrVec(devices);
+ DeviceVector devicesToCheck =
+ mConfig->getOutputDevices().getDevicesFromDeviceTypeAddrVec(devices);
AudioPatchCollection msdPatches = getMsdOutputPatches();
for (size_t i = 0; i < msdPatches.size(); i++) {
const auto& patch = msdPatches[i];
@@ -4106,13 +4107,13 @@
dst->appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
dst->appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
dst->appendFormat(" Communication Strategy id: %d\n", mCommunnicationStrategy);
- dst->appendFormat(" Config source: %s\n", mConfig.getSource().c_str()); // getConfig not const
+ dst->appendFormat(" Config source: %s\n", mConfig->getSource().c_str());
dst->append("\n");
mAvailableOutputDevices.dump(dst, String8("Available output"), 1);
dst->append("\n");
mAvailableInputDevices.dump(dst, String8("Available input"), 1);
- mHwModulesAll.dump(dst);
+ mHwModules.dump(dst);
mOutputs.dump(dst);
mInputs.dump(dst);
mEffects.dump(dst, 1);
@@ -4619,7 +4620,7 @@
return OK;
};
- for (const auto& module : mHwModulesAll) {
+ for (const auto& module : mHwModules) {
for (const auto& dev : module->getDeclaredDevices()) {
if (role == media::AudioPortRole::NONE ||
((role == media::AudioPortRole::SOURCE)
@@ -5526,10 +5527,10 @@
size_t formatsWritten = 0;
size_t formatsMax = *numSurroundFormats;
- *numSurroundFormats = mConfig.getSurroundFormats().size();
+ *numSurroundFormats = mConfig->getSurroundFormats().size();
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
- for (const auto& format: mConfig.getSurroundFormats()) {
+ for (const auto& format: mConfig->getSurroundFormats()) {
if (formatsWritten < formatsMax) {
surroundFormats[formatsWritten] = format.first;
bool formatEnabled = true;
@@ -5582,10 +5583,10 @@
formatset.insert(encodedFormats.begin(), encodedFormats.end());
// Filter the formats which are supported by the vendor hardware.
for (auto it = formatset.begin(); it != formatset.end(); ++it) {
- if (mConfig.getSurroundFormats().count(*it) != 0) {
+ if (mConfig->getSurroundFormats().count(*it) != 0) {
formats.insert(*it);
} else {
- for (const auto& pair : mConfig.getSurroundFormats()) {
+ for (const auto& pair : mConfig->getSurroundFormats()) {
if (pair.second.count(*it) != 0) {
formats.insert(pair.first);
break;
@@ -5606,8 +5607,8 @@
status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
ALOGV("%s() format 0x%X enabled %d", __func__, audioFormat, enabled);
- const auto& formatIter = mConfig.getSurroundFormats().find(audioFormat);
- if (formatIter == mConfig.getSurroundFormats().end()) {
+ const auto& formatIter = mConfig->getSurroundFormats().find(audioFormat);
+ if (formatIter == mConfig->getSurroundFormats().end()) {
ALOGW("%s() format 0x%X is not a known surround format", __func__, audioFormat);
return BAD_VALUE;
}
@@ -5762,7 +5763,7 @@
bool AudioPolicyManager::isCallScreenModeSupported()
{
- return getConfig().isCallScreenModeSupported();
+ return mConfig->isCallScreenModeSupported();
}
@@ -5995,26 +5996,14 @@
return mAudioPortGeneration++;
}
-static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
- if (std::string audioPolicyXmlConfigFile = audio_get_audio_policy_config_file();
- !audioPolicyXmlConfigFile.empty()) {
- status_t ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile.c_str(), &config);
- if (ret == NO_ERROR) {
- config.setSource(audioPolicyXmlConfigFile);
- }
- return ret;
- }
- return BAD_VALUE;
-}
-
-AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
- bool /*forTesting*/)
+AudioPolicyManager::AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
+ AudioPolicyClientInterface *clientInterface)
:
mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
+ mConfig(config),
mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
- mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice),
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
@@ -6025,23 +6014,10 @@
{
}
-AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
- : AudioPolicyManager(clientInterface, false /*forTesting*/)
-{
- loadConfig();
-}
-
-void AudioPolicyManager::loadConfig() {
- if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
- ALOGE("could not load audio policy configuration file, setting defaults");
- getConfig().setDefault();
- }
-}
-
status_t AudioPolicyManager::initialize() {
{
auto engLib = EngineLibrary::load(
- "libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");
+ "libaudiopolicyengine" + mConfig->getEngineLibraryNameSuffix() + ".so");
if (!engLib) {
ALOGE("%s: Failed to load the engine library", __FUNCTION__);
return NO_INIT;
@@ -6059,31 +6035,22 @@
return status;
}
- // If microphones address is empty, set it according to device type
- for (size_t i = 0; i < mInputDevicesAll.size(); i++) {
- if (mInputDevicesAll[i]->address().empty()) {
- if (mInputDevicesAll[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
- mInputDevicesAll[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
- } else if (mInputDevicesAll[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
- mInputDevicesAll[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
- }
- }
- }
-
// The actual device selection cache will be updated when calling `updateDevicesAndOutputs`
// at the end of this function.
mEngine->initializeDeviceSelectionCache();
mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
- // after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
+ // after parsing the config, mConfig contain all known devices;
// open all output streams needed to access attached devices
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
// make sure default device is reachable
- if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
- ALOGE_IF(mDefaultOutputDevice != 0, "Default device %s is unreachable",
- mDefaultOutputDevice->toString().c_str());
+ if (const auto defaultOutputDevice = mConfig->getDefaultOutputDevice();
+ defaultOutputDevice == nullptr ||
+ !mAvailableOutputDevices.contains(defaultOutputDevice)) {
+ ALOGE_IF(defaultOutputDevice != nullptr, "Default device %s is unreachable",
+ defaultOutputDevice->toString().c_str());
status = NO_INIT;
}
ALOGW_IF(mPrimaryOutput == nullptr, "The policy configuration does not declare a primary output");
@@ -6108,8 +6075,8 @@
mOutputs.clear();
mInputs.clear();
mHwModules.clear();
- mHwModulesAll.clear();
mManualSurroundFormats.clear();
+ mConfig.clear();
}
status_t AudioPolicyManager::initCheck()
@@ -6131,7 +6098,7 @@
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
- for (const auto& hwModule : mHwModulesAll) {
+ for (const auto& hwModule : mConfig->getHwModules()) {
if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
continue;
}
@@ -6160,10 +6127,10 @@
}
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
- DeviceVector availProfileDevices = supportedDevices.filter(mOutputDevicesAll);
+ DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
sp<DeviceDescriptor> supportedDevice = 0;
- if (supportedDevices.contains(mDefaultOutputDevice)) {
- supportedDevice = mDefaultOutputDevice;
+ if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
+ supportedDevice = mConfig->getDefaultOutputDevice();
} else {
// choose first device present in profile's SupportedDevices also part of
// mAvailableOutputDevices.
@@ -6172,7 +6139,7 @@
}
supportedDevice = availProfileDevices.itemAt(0);
}
- if (!mOutputDevicesAll.contains(supportedDevice)) {
+ if (!mConfig->getOutputDevices().contains(supportedDevice)) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
@@ -6227,7 +6194,7 @@
// chose first device present in profile's SupportedDevices also part of
// available input devices
const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
- DeviceVector availProfileDevices = supportedDevices.filter(mInputDevicesAll);
+ DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getInputDevices());
if (availProfileDevices.isEmpty()) {
ALOGV("%s: Input device list is empty! for profile %s",
__func__, inProfile->getTagName().c_str());
@@ -7987,7 +7954,7 @@
std::unordered_set<audio_format_t> enforcedSurround(
devDesc->encodedFormats().begin(), devDesc->encodedFormats().end());
std::unordered_set<audio_format_t> allSurround; // A flat set of all known surround formats
- for (const auto& pair : mConfig.getSurroundFormats()) {
+ for (const auto& pair : mConfig->getSurroundFormats()) {
allSurround.insert(pair.first);
for (const auto& subformat : pair.second) allSurround.insert(subformat);
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index dc82d54..b2ac181 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -94,7 +94,8 @@
{
public:
- explicit AudioPolicyManager(AudioPolicyClientInterface *clientInterface);
+ AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
+ AudioPolicyClientInterface *clientInterface);
virtual ~AudioPolicyManager();
// AudioPolicyInterface
@@ -427,19 +428,7 @@
status_t initialize();
protected:
- // A constructor that allows more fine-grained control over initialization process,
- // used in automatic tests.
- AudioPolicyManager(AudioPolicyClientInterface *clientInterface, bool forTesting);
-
- // These methods should be used when finer control over APM initialization
- // is needed, e.g. in tests. Must be used in conjunction with the constructor
- // that only performs fields initialization. The public constructor comprises
- // these steps in the following sequence:
- // - field initializing constructor;
- // - loadConfig;
- // - initialize.
- AudioPolicyConfig& getConfig() { return mConfig; }
- void loadConfig();
+ const AudioPolicyConfig& getConfig() const { return *(mConfig.get()); }
// From AudioPolicyManagerObserver
virtual const AudioPatchCollection &getAudioPatches() const
@@ -473,7 +462,7 @@
}
virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const
{
- return mDefaultOutputDevice;
+ return mConfig->getDefaultOutputDevice();
}
std::vector<volume_group_t> getVolumeGroups() const
@@ -932,6 +921,7 @@
sp<SwAudioOutputDescriptor> ignoredOutput, uint32_t delayMs);
const uid_t mUidCached; // AID_AUDIOSERVER
+ sp<const AudioPolicyConfig> mConfig;
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor
// list of descriptors for outputs currently opened
@@ -944,8 +934,6 @@
SwAudioOutputCollection mPreviousOutputs;
AudioInputCollection mInputs; // list of input descriptors
- DeviceVector mOutputDevicesAll; // all output devices from the config
- DeviceVector mInputDevicesAll; // all input devices from the config
DeviceVector mAvailableOutputDevices; // all available output devices
DeviceVector mAvailableInputDevices; // all available input devices
@@ -955,11 +943,7 @@
bool mA2dpSuspended; // true if A2DP output is suspended
EffectDescriptorCollection mEffects; // list of registered audio effects
- sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
HwModuleCollection mHwModules; // contains modules that have been loaded successfully
- HwModuleCollection mHwModulesAll; // contains all modules declared in the config
-
- AudioPolicyConfig mConfig;
std::atomic<uint32_t> mAudioPortGeneration;
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 10403fa..2f677da 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -52,8 +52,9 @@
"libsensor",
"libsensorprivacy",
"libshmemcompat",
- "libutils",
"libstagefright_foundation",
+ "libutils",
+ "libxml2",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index e5b1c91..7757f37 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -46,6 +46,7 @@
#include <system/audio.h>
#include <system/audio_policy.h>
+#include <AudioPolicyConfig.h>
#include <AudioPolicyManager.h>
namespace android {
@@ -185,7 +186,8 @@
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
- AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
+ AudioPolicyManager *apm = new AudioPolicyManager(
+ AudioPolicyConfig::loadFromApmXmlConfigWithFallback(), clientInterface);
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index bf82680..285b354 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -19,19 +19,20 @@
],
shared_libs: [
+ "framework-permission-aidl-cpp",
"libaudioclient",
"libaudiofoundation",
"libaudiopolicy",
"libaudiopolicymanagerdefault",
"libbase",
+ "libbinder",
+ "libcutils",
"libhidlbase",
"liblog",
"libmedia_helper",
"libutils",
"libcutils",
"libxml2",
- "framework-permission-aidl-cpp",
- "libbinder",
],
static_libs: [
@@ -73,17 +74,19 @@
require_root: true,
shared_libs: [
- "libaudiofoundation",
+ "audioclient-types-aidl-cpp",
"libaudioclient",
+ "libaudioclient_aidl_conversion",
+ "libaudiofoundation",
"libaudiopolicymanagerdefault",
+ "libcutils",
"liblog",
"libmedia_helper",
- "libutils",
- "libaudioclient_aidl_conversion",
- "libstagefright_foundation",
"libshmemcompat",
"libshmemutil",
- "audioclient-types-aidl-cpp",
+ "libstagefright_foundation",
+ "libutils",
+ "libxml2",
],
static_libs: ["libaudiopolicycomponents"],
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index 2a7a060..9ad9849 100644
--- a/services/audiopolicy/tests/AudioPolicyTestManager.h
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -22,9 +22,11 @@
class AudioPolicyTestManager : public AudioPolicyManager {
public:
explicit AudioPolicyTestManager(AudioPolicyClientInterface *clientInterface)
- : AudioPolicyManager(clientInterface, true /*forTesting*/) { }
+ : AudioPolicyManager(AudioPolicyConfig::createDefault(), clientInterface) {}
+ AudioPolicyTestManager(const sp<const AudioPolicyConfig>& config,
+ AudioPolicyClientInterface *clientInterface)
+ : AudioPolicyManager(config, clientInterface) {}
using AudioPolicyManager::getConfig;
- using AudioPolicyManager::loadConfig;
using AudioPolicyManager::initialize;
using AudioPolicyManager::getOutputs;
using AudioPolicyManager::getAvailableOutputDevices;
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index 798332c..70a3022 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -21,6 +21,7 @@
#include <gtest/gtest.h>
+#include <AudioPolicyConfig.h>
#include <media/AudioSystem.h>
#include <media/TypeConverter.h>
#include <system/audio.h>
@@ -65,19 +66,17 @@
}
free(audioPorts);
- AudioPolicyManagerTestClient client;
- AudioPolicyTestManager manager(&client);
- manager.loadConfig();
- ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();
+ ASSERT_NE(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
- for (auto desc : manager.getConfig().getInputDevices()) {
+ for (const auto& desc : config->getInputDevices()) {
if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
std::string deviceType;
(void)DeviceConverter::toString(desc->type(), deviceType);
ADD_FAILURE() << "Input device \"" << deviceType << "\" not found";
}
}
- for (auto desc : manager.getConfig().getOutputDevices()) {
+ for (const auto& desc : config->getOutputDevices()) {
if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
std::string deviceType;
(void)DeviceConverter::toString(desc->type(), deviceType);
@@ -87,13 +86,13 @@
}
TEST(AudioHealthTest, ConnectSupportedDevice) {
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();
+ ASSERT_NE(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
AudioPolicyManagerTestClient client;
- AudioPolicyTestManager manager(&client);
- manager.loadConfig();
- ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
+ AudioPolicyTestManager manager(config, &client);
DeviceVector devices;
- for (const auto& hwModule : manager.getConfig().getHwModules()) {
+ for (const auto& hwModule : config->getHwModules()) {
for (const auto& profile : hwModule->getOutputProfiles()) {
devices.merge(profile->getSupportedDevices());
}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 412ab19..97a1e0d 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -92,11 +92,44 @@
} // namespace
+TEST(AudioPolicyConfigTest, DefaultConfigForTestsIsEmpty) {
+ auto config = AudioPolicyConfig::createWritableForTests();
+ EXPECT_TRUE(config->getSource().empty());
+ EXPECT_TRUE(config->getHwModules().isEmpty());
+ EXPECT_TRUE(config->getInputDevices().isEmpty());
+ EXPECT_TRUE(config->getOutputDevices().isEmpty());
+}
+
+TEST(AudioPolicyConfigTest, FallbackToDefault) {
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
+ base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
+ EXPECT_EQ(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
+}
+
+TEST(AudioPolicyConfigTest, LoadForTests) {
+ {
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(
+ base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
+ EXPECT_FALSE(result.ok());
+ }
+ {
+ const std::string source =
+ base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml";
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(source);
+ ASSERT_TRUE(result.ok());
+ EXPECT_EQ(source, result.value()->getSource());
+ EXPECT_FALSE(result.value()->getHwModules().isEmpty());
+ EXPECT_FALSE(result.value()->getInputDevices().isEmpty());
+ EXPECT_FALSE(result.value()->getOutputDevices().isEmpty());
+ }
+}
+
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
- AudioPolicyTestManager manager(&client);
- manager.getConfig().setDefault();
- manager.getConfig().setEngineLibraryNameSuffix("non-existent");
+ auto config = AudioPolicyConfig::createWritableForTests();
+ config->setDefault();
+ config->setEngineLibraryNameSuffix("non-existent");
+ AudioPolicyTestManager manager(config, &client);
ASSERT_EQ(NO_INIT, manager.initialize());
ASSERT_EQ(NO_INIT, manager.initCheck());
}
@@ -104,41 +137,12 @@
TEST(AudioPolicyManagerTestInit, ClientFailure) {
AudioPolicyTestClient client;
AudioPolicyTestManager manager(&client);
- manager.getConfig().setDefault();
// Since the default client fails to open anything,
// APM should indicate that the initialization didn't succeed.
ASSERT_EQ(NO_INIT, manager.initialize());
ASSERT_EQ(NO_INIT, manager.initCheck());
}
-// Verifies that a failure while loading a config doesn't leave
-// APM config in a "dirty" state. Since AudioPolicyConfig object
-// is a proxy for the data hosted by APM, it isn't possible
-// to "deep copy" it, and thus we have to test its elements
-// individually.
-TEST(AudioPolicyManagerTestInit, ConfigLoadingIsTransactional) {
- AudioPolicyTestClient client;
- AudioPolicyTestManager manager(&client);
- ASSERT_TRUE(manager.getConfig().getHwModules().isEmpty());
- ASSERT_TRUE(manager.getConfig().getInputDevices().isEmpty());
- ASSERT_TRUE(manager.getConfig().getOutputDevices().isEmpty());
- status_t status = deserializeAudioPolicyFile(
- (base::GetExecutableDirectory() +
- "/test_invalid_audio_policy_configuration.xml").c_str(),
- &manager.getConfig());
- ASSERT_NE(NO_ERROR, status);
- EXPECT_TRUE(manager.getConfig().getHwModules().isEmpty());
- EXPECT_TRUE(manager.getConfig().getInputDevices().isEmpty());
- EXPECT_TRUE(manager.getConfig().getOutputDevices().isEmpty());
- status = deserializeAudioPolicyFile(
- (base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml").c_str(),
- &manager.getConfig());
- ASSERT_EQ(NO_ERROR, status);
- EXPECT_FALSE(manager.getConfig().getHwModules().isEmpty());
- EXPECT_FALSE(manager.getConfig().getInputDevices().isEmpty());
- EXPECT_FALSE(manager.getConfig().getOutputDevices().isEmpty());
-}
-
class PatchCountCheck {
public:
@@ -200,6 +204,7 @@
static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
virtual AudioPolicyManagerTestClient* getClient() { return new AudioPolicyManagerTestClient; }
+ sp<AudioPolicyConfig> mConfig;
std::unique_ptr<AudioPolicyManagerTestClient> mClient;
std::unique_ptr<AudioPolicyTestManager> mManager;
@@ -208,8 +213,8 @@
void AudioPolicyManagerTest::SetUp() {
mClient.reset(getClient());
- mManager.reset(new AudioPolicyTestManager(mClient.get()));
ASSERT_NO_FATAL_FAILURE(SetUpManagerConfig()); // Subclasses may want to customize the config.
+ mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get()));
ASSERT_EQ(NO_ERROR, mManager->initialize());
ASSERT_EQ(NO_ERROR, mManager->initCheck());
}
@@ -220,7 +225,8 @@
}
void AudioPolicyManagerTest::SetUpManagerConfig() {
- mManager->getConfig().setDefault();
+ mConfig = AudioPolicyConfig::createWritableForTests();
+ mConfig->setDefault();
}
void AudioPolicyManagerTest::dumpToLog() {
@@ -467,7 +473,6 @@
void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
// TODO: Consider using Serializer to load part of the config from a string.
ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
- AudioPolicyConfig& config = mManager->getConfig();
mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
sp<AudioProfile> pcmOutputProfile = new AudioProfile(
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
@@ -483,26 +488,26 @@
sp<AudioProfile> pcmInputProfile = new AudioProfile(
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
mMsdInputDevice->addAudioProfile(pcmInputProfile);
- config.addDevice(mMsdOutputDevice);
- config.addDevice(mMsdInputDevice);
+ mConfig->addDevice(mMsdOutputDevice);
+ mConfig->addDevice(mMsdInputDevice);
if (mExpectedAudioPatchCount == 2) {
// Add SPDIF device with PCM output profile as a second device for dual MSD audio patching.
mSpdifDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPDIF);
mSpdifDevice->addAudioProfile(pcmOutputProfile);
- config.addDevice(mSpdifDevice);
+ mConfig->addDevice(mSpdifDevice);
sp<OutputProfile> spdifOutputProfile = new OutputProfile("spdif output");
spdifOutputProfile->addAudioProfile(pcmOutputProfile);
spdifOutputProfile->addSupportedDevice(mSpdifDevice);
- config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
addOutputProfile(spdifOutputProfile);
}
sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
- HwModuleCollection modules = config.getHwModules();
+ HwModuleCollection modules = mConfig->getHwModules();
modules.add(msdModule);
- config.setHwModules(modules);
+ mConfig->setHwModules(modules);
sp<OutputProfile> msdOutputProfile = new OutputProfile("msd input");
msdOutputProfile->addAudioProfile(pcmOutputProfile);
@@ -530,15 +535,15 @@
// of streams that are not supported by MSD.
sp<AudioProfile> dtsOutputProfile = new AudioProfile(
AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
- config.getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
+ mConfig->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile("encoded");
primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
- primaryEncodedOutputProfile->addSupportedDevice(config.getDefaultOutputDevice());
- config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ primaryEncodedOutputProfile->addSupportedDevice(mConfig->getDefaultOutputDevice());
+ mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
addOutputProfile(primaryEncodedOutputProfile);
- mDefaultOutputDevice = config.getDefaultOutputDevice();
+ mDefaultOutputDevice = mConfig->getDefaultOutputDevice();
if (mExpectedAudioPatchCount == 2) {
mSpdifDevice->addAudioProfile(dtsOutputProfile);
primaryEncodedOutputProfile->addSupportedDevice(mSpdifDevice);
@@ -549,12 +554,12 @@
sp<AudioProfile> iec958InputProfile = new AudioProfile(
AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
mHdmiInputDevice->addAudioProfile(iec958InputProfile);
- config.addDevice(mHdmiInputDevice);
+ mConfig->addDevice(mHdmiInputDevice);
sp<InputProfile> hdmiInputProfile = new InputProfile("hdmi input");
hdmiInputProfile->addAudioProfile(iec958InputProfile);
hdmiInputProfile->setFlags(AUDIO_INPUT_FLAG_DIRECT);
hdmiInputProfile->addSupportedDevice(mHdmiInputDevice);
- config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
addInputProfile(hdmiInputProfile);
}
@@ -721,7 +726,7 @@
int countDirectProfilesPrimary = 0;
const auto& primary = mManager->getConfig().getHwModules()
.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
- for (const auto outputProfile : primary->getOutputProfiles()) {
+ for (const auto& outputProfile : primary->getOutputProfiles()) {
if (outputProfile->asAudioPort()->isDirectOutput()) {
countDirectProfilesPrimary += outputProfile->asAudioPort()->getAudioProfiles().size();
}
@@ -731,7 +736,7 @@
int countDirectProfilesMsd = 0;
const auto& msd = mManager->getConfig().getHwModules()
.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
- for (const auto outputProfile : msd->getOutputProfiles()) {
+ for (const auto& outputProfile : msd->getOutputProfiles()) {
if (outputProfile->asAudioPort()->isDirectOutput()) {
countDirectProfilesMsd += outputProfile->asAudioPort()->getAudioProfiles().size();
}
@@ -922,9 +927,9 @@
sExecutableDir + "test_audio_policy_configuration.xml";
void AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig() {
- status_t status = deserializeAudioPolicyFile(getConfigFile().c_str(), &mManager->getConfig());
- ASSERT_EQ(NO_ERROR, status);
- mManager->getConfig().setSource(getConfigFile());
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(getConfigFile());
+ ASSERT_TRUE(result.ok());
+ mConfig = result.value();
}
TEST_F(AudioPolicyManagerTestWithConfigurationFile, InitSuccess) {