Android provides 2 audio policy engines: libaudiopolicyenginedefault and libaudiopolicyengineconfigurable. This change makes the engine to be loaded dynamically based on the configuration (currently the engine name is hardcoded into AudioPolicyConfig). Dynamic loading allows building and installing of both libraries without any conflicts. Technical changes: - AudioPolicyManagerInterface renamed to EngineInterface for clarity; - For the purpose of dynamic loading, APM does not depend anymore on the EngineInstance class. The class got removed from the default AP engine, but left in the configurable engine because it is also used by its plugins; - Added EngineLibrary class to encapsulate dynamic loading of the AP engine. The class name EngineInstance is repurposed for a smart pointer to EngineInterface; - services/audiopolicy/managerdefault/Android.mk converted into Android.bp; - Added engine loading failure test; Bug: 132639720 Test: sanity tests for audio; audiopolicy_tests Change-Id: I0581569a172f810e030aec879225e817bfa7851a Merged-In: I0581569a172f810e030aec879225e817bfa7851agugelfrei
parent
3e0b02e336
commit
e13c679e4a
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class AudioPolicyManagerInterface;
|
||||
|
||||
namespace android
|
||||
{
|
||||
namespace audio_policy
|
||||
{
|
||||
|
||||
class Engine;
|
||||
|
||||
class EngineInstance
|
||||
{
|
||||
protected:
|
||||
EngineInstance();
|
||||
|
||||
public:
|
||||
virtual ~EngineInstance();
|
||||
|
||||
/**
|
||||
* Get Audio Policy Engine instance.
|
||||
*
|
||||
* @return pointer to Route Manager Instance object.
|
||||
*/
|
||||
static EngineInstance *getInstance();
|
||||
|
||||
/**
|
||||
* Interface query.
|
||||
* The first client of an interface of the policy engine will start the singleton.
|
||||
*
|
||||
* @tparam RequestedInterface: interface that the client is wishing to retrieve.
|
||||
*
|
||||
* @return interface handle.
|
||||
*/
|
||||
template <class RequestedInterface>
|
||||
RequestedInterface *queryInterface() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get Audio Policy Engine instance.
|
||||
*
|
||||
* @return Audio Policy Engine singleton.
|
||||
*/
|
||||
Engine *getEngine() const;
|
||||
|
||||
private:
|
||||
/* Copy facilities are put private to disable copy. */
|
||||
EngineInstance(const EngineInstance &object);
|
||||
EngineInstance &operator=(const EngineInstance &object);
|
||||
};
|
||||
|
||||
/**
|
||||
* Limit template instantation to supported type interfaces.
|
||||
* Compile time error will claim if invalid interface is requested.
|
||||
*/
|
||||
template <>
|
||||
AudioPolicyManagerInterface *EngineInstance::queryInterface() const;
|
||||
|
||||
} // namespace audio_policy
|
||||
} // namespace android
|
@ -0,0 +1,43 @@
|
||||
cc_library_shared {
|
||||
name: "libaudiopolicymanagerdefault",
|
||||
|
||||
srcs: [
|
||||
"AudioPolicyManager.cpp",
|
||||
"EngineLibrary.cpp",
|
||||
],
|
||||
|
||||
export_include_dirs: ["."],
|
||||
|
||||
shared_libs: [
|
||||
"libcutils",
|
||||
"libdl",
|
||||
"libutils",
|
||||
"liblog",
|
||||
"libaudiopolicy",
|
||||
"libsoundtrigger",
|
||||
"libmedia_helper",
|
||||
"libmediametrics",
|
||||
"libbinder",
|
||||
"libhidlbase",
|
||||
"libxml2",
|
||||
// The default audio policy engine is always present in the system image.
|
||||
// libaudiopolicyengineconfigurable can be built in addition by specifying
|
||||
// a dependency on it in the device makefile. There will be no build time
|
||||
// conflict with libaudiopolicyenginedefault.
|
||||
"libaudiopolicyenginedefault",
|
||||
],
|
||||
|
||||
header_libs: [
|
||||
"libaudiopolicycommon",
|
||||
"libaudiopolicyengine_interface_headers",
|
||||
"libaudiopolicymanager_interface_headers",
|
||||
],
|
||||
|
||||
static_libs: ["libaudiopolicycomponents"],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= AudioPolicyManager.cpp
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
libutils \
|
||||
liblog \
|
||||
libaudiopolicy \
|
||||
libsoundtrigger
|
||||
|
||||
ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
|
||||
|
||||
else
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
|
||||
|
||||
endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(call include-path-for, audio-utils)
|
||||
|
||||
LOCAL_HEADER_LIBRARIES := \
|
||||
libaudiopolicycommon \
|
||||
libaudiopolicyengine_interface_headers \
|
||||
libaudiopolicymanager_interface_headers
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libaudiopolicycomponents
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libmedia_helper
|
||||
LOCAL_SHARED_LIBRARIES += libmediametrics
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2
|
||||
|
||||
LOCAL_CFLAGS += -Wall -Werror
|
||||
|
||||
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
|
||||
|
||||
LOCAL_MODULE:= libaudiopolicymanagerdefault
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2019 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_EngineLoader"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "EngineLibrary.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
// static
|
||||
std::shared_ptr<EngineLibrary> EngineLibrary::load(std::string libraryPath)
|
||||
{
|
||||
std::shared_ptr<EngineLibrary> engLib(new EngineLibrary());
|
||||
return engLib->init(std::move(libraryPath)) ? engLib : nullptr;
|
||||
}
|
||||
|
||||
EngineLibrary::~EngineLibrary()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool EngineLibrary::init(std::string libraryPath)
|
||||
{
|
||||
mLibraryHandle = dlopen(libraryPath.c_str(), 0);
|
||||
if (mLibraryHandle == nullptr) {
|
||||
ALOGE("Could not dlopen %s: %s", libraryPath.c_str(), dlerror());
|
||||
return false;
|
||||
}
|
||||
mCreateEngineInstance = (EngineInterface* (*)())dlsym(mLibraryHandle, "createEngineInstance");
|
||||
mDestroyEngineInstance = (void (*)(EngineInterface*))dlsym(
|
||||
mLibraryHandle, "destroyEngineInstance");
|
||||
if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {
|
||||
ALOGE("Could not find engine interface functions in %s", libraryPath.c_str());
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
ALOGD("Loaded engine from %s", libraryPath.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
EngineInstance EngineLibrary::createEngine()
|
||||
{
|
||||
if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {
|
||||
return EngineInstance();
|
||||
}
|
||||
return EngineInstance(mCreateEngineInstance(),
|
||||
[lib = shared_from_this(), destroy = mDestroyEngineInstance] (EngineInterface* e) {
|
||||
destroy(e);
|
||||
});
|
||||
}
|
||||
|
||||
void EngineLibrary::close()
|
||||
{
|
||||
if (mLibraryHandle != nullptr) {
|
||||
dlclose(mLibraryHandle);
|
||||
}
|
||||
mLibraryHandle = nullptr;
|
||||
mCreateEngineInstance = nullptr;
|
||||
mDestroyEngineInstance = nullptr;
|
||||
}
|
||||
|
||||
} // namespace android
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <EngineInterface.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
using EngineInstance = std::unique_ptr<EngineInterface, std::function<void (EngineInterface*)>>;
|
||||
|
||||
class EngineLibrary : public std::enable_shared_from_this<EngineLibrary> {
|
||||
public:
|
||||
static std::shared_ptr<EngineLibrary> load(std::string libraryPath);
|
||||
~EngineLibrary();
|
||||
|
||||
EngineLibrary(const EngineLibrary&) = delete;
|
||||
EngineLibrary(EngineLibrary&&) = delete;
|
||||
EngineLibrary& operator=(const EngineLibrary&) = delete;
|
||||
EngineLibrary& operator=(EngineLibrary&&) = delete;
|
||||
|
||||
EngineInstance createEngine();
|
||||
|
||||
private:
|
||||
EngineLibrary() = default;
|
||||
bool init(std::string libraryPath);
|
||||
void close();
|
||||
|
||||
void *mLibraryHandle = nullptr;
|
||||
EngineInterface* (*mCreateEngineInstance)() = nullptr;
|
||||
void (*mDestroyEngineInstance)(EngineInterface*) = nullptr;
|
||||
};
|
||||
|
||||
} // namespace android
|
Loading…
Reference in new issue