Move engine loading out from the AudioPolicyManager
Separating loading of the APM Engine configuration from the APM
initialization. This opens the way for loading the engine
configuration from other sources than the XML file. The APM
receives an engine instance pre-loaded with the configuration on
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
Change-Id: I5185d8e27fccf64ba14856d3a1f0ea07a47f02e0
Merged-In: I5185d8e27fccf64ba14856d3a1f0ea07a47f02e0
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b558fed..e087d8a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5997,10 +5997,12 @@
}
AudioPolicyManager::AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
+ EngineInstance&& engine,
AudioPolicyClientInterface *clientInterface)
:
mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
mConfig(config),
+ mEngine(std::move(engine)),
mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
@@ -6015,18 +6017,8 @@
}
status_t AudioPolicyManager::initialize() {
- {
- auto engLib = EngineLibrary::load(
- "libaudiopolicyengine" + mConfig->getEngineLibraryNameSuffix() + ".so");
- if (!engLib) {
- ALOGE("%s: Failed to load the engine library", __FUNCTION__);
- return NO_INIT;
- }
- mEngine = engLib->createEngine();
- if (mEngine == nullptr) {
- ALOGE("%s: Failed to instantiate the APM engine", __FUNCTION__);
- return NO_INIT;
- }
+ if (mEngine == nullptr) {
+ return NO_INIT;
}
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index b2ac181..88bafef 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -95,6 +95,7 @@
public:
AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
+ EngineInstance&& engine,
AudioPolicyClientInterface *clientInterface);
virtual ~AudioPolicyManager();
@@ -922,6 +923,7 @@
const uid_t mUidCached; // AID_AUDIOSERVER
sp<const AudioPolicyConfig> mConfig;
+ EngineInstance mEngine; // Audio Policy Engine instance
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor
// list of descriptors for outputs currently opened
@@ -974,9 +976,6 @@
uint32_t nextAudioPortGeneration();
- // Audio Policy Engine Interface.
- EngineInstance mEngine;
-
// Surround formats that are enabled manually. Taken into account when
// "encoded surround" is forced into "manual" mode.
std::unordered_set<audio_format_t> mManualSurroundFormats;
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.cpp b/services/audiopolicy/managerdefault/EngineLibrary.cpp
index ef699aa..939fbc5 100644
--- a/services/audiopolicy/managerdefault/EngineLibrary.cpp
+++ b/services/audiopolicy/managerdefault/EngineLibrary.cpp
@@ -23,9 +23,27 @@
namespace android {
-// static
-std::shared_ptr<EngineLibrary> EngineLibrary::load(std::string libraryPath)
+EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
+ const std::string& configXmlFilePath)
{
+ auto engLib = EngineLibrary::load(librarySuffix);
+ if (!engLib) {
+ ALOGE("%s: Failed to load the engine library, suffix \"%s\"",
+ __func__, librarySuffix.c_str());
+ return nullptr;
+ }
+ auto engine = engLib->createEngineUsingXmlConfig(configXmlFilePath);
+ if (engine == nullptr) {
+ ALOGE("%s: Failed to instantiate the APM engine", __func__);
+ return nullptr;
+ }
+ return engine;
+}
+
+// static
+std::shared_ptr<EngineLibrary> EngineLibrary::load(const std::string& librarySuffix)
+{
+ std::string libraryPath = "libaudiopolicyengine" + librarySuffix + ".so";
std::shared_ptr<EngineLibrary> engLib(new EngineLibrary());
return engLib->init(std::move(libraryPath)) ? engLib : nullptr;
}
@@ -35,6 +53,20 @@
close();
}
+EngineInstance EngineLibrary::createEngineUsingXmlConfig(const std::string& xmlFilePath) {
+ auto instance = createEngine();
+ if (instance != nullptr) {
+ if (status_t status = instance->loadFromXmlConfigWithFallback(xmlFilePath);
+ status == OK) {
+ return instance;
+ } else {
+ ALOGE("%s: loading of the engine config with XML configuration file \"%s\" failed: %d",
+ __func__, xmlFilePath.empty() ? "default" : xmlFilePath.c_str(), status);
+ }
+ }
+ return nullptr;
+}
+
bool EngineLibrary::init(std::string libraryPath)
{
mLibraryHandle = dlopen(libraryPath.c_str(), 0);
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.h b/services/audiopolicy/managerdefault/EngineLibrary.h
index f143916..dc138a1 100644
--- a/services/audiopolicy/managerdefault/EngineLibrary.h
+++ b/services/audiopolicy/managerdefault/EngineLibrary.h
@@ -26,9 +26,12 @@
using EngineInstance = std::unique_ptr<EngineInterface, std::function<void (EngineInterface*)>>;
+EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
+ const std::string& configXmlFilePath = "");
+
class EngineLibrary : public std::enable_shared_from_this<EngineLibrary> {
public:
- static std::shared_ptr<EngineLibrary> load(std::string libraryPath);
+ static std::shared_ptr<EngineLibrary> load(const std::string& librarySuffix);
~EngineLibrary();
EngineLibrary(const EngineLibrary&) = delete;
@@ -36,11 +39,12 @@
EngineLibrary& operator=(const EngineLibrary&) = delete;
EngineLibrary& operator=(EngineLibrary&&) = delete;
- EngineInstance createEngine();
+ EngineInstance createEngineUsingXmlConfig(const std::string& xmlFilePath);
private:
EngineLibrary() = default;
bool init(std::string libraryPath);
+ EngineInstance createEngine();
void close();
void *mLibraryHandle = nullptr;