本系列文章基于Android14源码进行分析解读,部分框图直接使用了原作者的图片,侵权必删。
我们既生成文章,也是各路文章的搬运工。
AudioHAL(AHAL)提供隔离Vendor硬件差异的抽象,通过tinyalsa实现对底层硬件声卡节点的操作。AHAL作为一个独立的service,在Android系统中肯定有client通过binder与其通信,实现数据流与控制流的交互,完成对声卡节点数据的访问。
AudioTrack.java和AudioRecord.java是应用层的API,透过GNI访问了Native层的AudioTrack.cpp和AudioRecord.cpp,AudioTrack和AudioRecord又是如何把数据写进和读出底层声卡的呢?
Linux声卡设备节点是一个互斥的节点,每次只能被一个应用打开,其他应用尝试open一个已经打开的节点会返回device busy的错误。但是在实际Android使用过程中又存在多个音频数据流同时播放的场景,这是如何做到的呢?
所有这些疑问都会在AudioFlinger服务中解决。AudioFlinger向下访问AudioHardware,实现输出音频数据,控制音频参数;AudioFlinger向上通过IAudioFinger接口对AudioTrack和AudioRecord供服务。AudioFlinger在Android的音频系统框架中起着承上启下的作用,地位相当重要。
AudioFlinger创建PlaybackThread/RecordThread服务线程,实现对AHAL层音频节点的独占操作。多个AudioTrack/AudioRecord作为Clinet端同PlaybackThread/RecordThread服务线程交互,Thread实现音频流的mix/snoop,来实现整个音频框架。
下面通过分析代码,完成对AudioFlinger的深入理解。
AudioFlinger在audioserver中启动,代码在:
frameworks/av/media/audioserver/main_audioserver.cpp
#define LOG_TAG "audioserver"
int main(int argc __unused, char **argv)
{
......
这里修改了AudioFling和AudioPolicyService的初始化方式,以解决独立初始化模式下引起的
服务启动时间差,这个时间差会导致部分服务时间检测异常而强行退出。
// Instantiating AudioFlinger (making it public, e.g. through ::initialize())
// and then instantiating AudioPolicy (and making it public)
// leads to situations where AudioFlinger is accessed remotely before
// AudioPolicy is initialized. Not only might this
// cause inaccurate results, but if AudioPolicy has slow audio HAL
// initialization, it can cause a TimeCheck abort to occur on an AudioFlinger
// call which tries to access AudioPolicy.
//
// We create AudioFlinger and AudioPolicy locally then make it public to ServiceManager.
// This requires both AudioFlinger and AudioPolicy to be in-proc.
//
/* 1、创建AudioFling实例,必须在AudioPolicyService之前,因为aps会访问af中的接口 */
const auto af = sp::make();
const auto afAdapter = sp::make(af);
/* 2、创建AudioPolicyService实例 */
const auto aps = sp::make();
/* 3、添加AudioFlinger和AudioPolicyService服务到ServiceManager */
// Add AudioFlinger and AudioPolicy to ServiceManager.
sp sm = defaultServiceManager();
sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME), afAdapter,
false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
sm->addService(String16(AudioPolicyService::getServiceName()), aps,
false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
// AAudioService should only be used in OC-MR1 and later.
// And only enable the AAudioService if the system MMAP policy explicitly allows it.
std::vector policyInfos;
status_t status = af->getMmapPolicyInfos(
AudioMMapPolicyType::DEFAULT, &policyInfos);
// Initialize aaudio service when querying mmap policy succeeds and
// any of the policy supports MMAP.
if (status == NO_ERROR &&
std::any_of(policyInfos.begin(), policyInfos.end(), [](const auto& info) {
return info.mmapPolicy == AudioMMapPolicy::AUTO ||
info.mmapPolicy == AudioMMapPolicy::ALWAYS;
})) {
/* 4、创建AAudioService实例 */
AAudioService::instantiate();
}
......
IPCThreadState::self()->joinThreadPool();
}
}
主函数里面没有做太多的任务,创建了AudioFlinger和AudioPolicyService两个实例,并将服务注册到servicemanager中,除此之外还检测并创建了AAudioService。
AudioFlinger::AudioFlinger() {
......
// reset battery stats.
// if the audio service has crashed, battery stats could be left
// in bad state, reset the state upon service start.
BatteryNotifier::getInstance().noteResetAudio();
/* 构建音频device和音效effect实例 */
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
}
AudioFlinger的实例没有做太多的工作:
sp DevicesFactoryHalInterface::create() {
return createPreferredImpl(true /* isDevice */);
}
void *createPreferredImpl(bool isDevice) {
......
if (...) {
.....
/* 1、创建AudioHal服务 */
if (createHalService(std::max(*ifaceVersionIt, *siblingVersionIt), isDevice,
&rawInterface)) {
return rawInterface;
}
return nullptr;
}
bool createHalService(const AudioHalVersionInfo& version, bool isDevice, void** rawInterface) {
const std::string libName = "libaudiohal@" + version.toVersionString() + ".so";
const std::string factoryFunctionName =
isDevice ? "createIDevicesFactory" : "createIEffectsFactory";
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
/* 2、打开 [email protected] 动态库 */
handle = dlopen(libName.c_str(), dlMode);
......
void* (*factoryFunction)();
/*3、函数进来后首先初始化factoryFunctionName为createIDevicesFactory, 所以这里获取到的factoryFunction句柄为createIDevicesFactory函数 */
*(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
if (!factoryFunction) {
......
}
/* 4、调用libaudiohal动态库的createIDevicesFactory函数,完成AHAL句柄的创建 */
*rawInterface = (*factoryFunction)();
return true;
}
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
return createIDevicesFactoryImpl();
}
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
return service ? new DevicesFactoryHalHidl(service) : nullptr;
}
DevicesFactoryHalEntry.cpp::createIDevicesFactory() ->
DevicesFactoryHalHidl.cpp::createIDevicesFactoryImpl() ->
DevicesFactoryHalHidl.cpp::DevicesFactoryHalHidl()
具体逻辑这里不做深入的分析了,后面有机会再展开。
整个AudioFlinger完成初始化之后,并没有做太多的任务。而是作为一个服务运行在系统中,等待客户端与其进行通信:这也符合AF的功能,我只做一个执行者,不做决策。那谁优势决策者呢?别忘了我们还没有分析AudioPolicyService呢。
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(),
mAudioPolicyManager(NULL),
mAudioPolicyClient(NULL),
mPhoneState(AUDIO_MODE_INVALID),
mCaptureStateNotifier(false),
/* 1 - 初始化mCreateAudioPolicyManager为createAudioPolicyManager */
mCreateAudioPolicyManager(createAudioPolicyManager),
mDestroyAudioPolicyManager(destroyAudioPolicyManager) {
setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
}
/* 在完成实例后,首先调用的函数就是onFirstRef,具体原因请搜索其他文章 */
void AudioPolicyService::onFirstRef()
{
{
Mutex::Autolock _l(mLock);
/* 2 - 创建两个命令线程,用于接收并处理其他服务发送的命令 */
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
// start output activity command thread
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
/* 3 - 构造AudioPolicyClient实例:APC是AF的clinet端,很多任务都是通过跨进程调用到AF中 */
mAudioPolicyClient = new AudioPolicyClient(this);
/* 4 - 加载用户自定义的的AudioPolicyManager实现:libaudiopolicymanagercustom.so */
loadAudioPolicyManager();
/* 5 - 调用createAudioPolicyManager接口 */
mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
}
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
AudioPolicyManager *apm = nullptr;
media::AudioPolicyConfig apmConfig;
/* 1、与AHAL交互获取modules信息,以确定是否存在用户自定义的configurable AudioPolicyConfig */
if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix()