前言
本系列文章基于Android14源码进行分析解读,部分框图直接使用了原作者的图片,侵权必删。
我们既生成文章,也是各路文章的搬运工。
一、What&Why AudioFlinger
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初始化
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<AudioFlinger>::make();
const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af);
/* 2、创建AudioPolicyService实例 */
const auto aps = sp<AudioPolicyService>::make();
/* 3、添加AudioFlinger和AudioPolicyService服务到ServiceManager */
// Add AudioFlinger and AudioPolicy to ServiceManager.
sp<IServiceManager> 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<AudioMMapPolicyInfo> 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。
1、AudioFlinger实例构建
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的实例没有做太多的工作:
- 完成电池状态的复位;
- 构建音频设备Device工厂实例;
- 构建音效Effect工厂实例;
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
return createPreferredImpl<DevicesFactoryHalInterface>(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呢。
2、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);
}
2.1、createAudioPolicyManager
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() !=
AudioPolicyConfig::kDefaultEngineLibraryNameSuffix,
"Only default engine is currently supported with the AIDL HAL");
apm = new AudioPolicyManager(config,
loadApmEngineLibraryAndCreateEngine(
config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
clientInterface);
} else {
/* 2、加载系统预定义的audio_policy_configuration配置 */
auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();
/* 3、config->getEngineLibraryNameSuffix()返回的
字符串为“default”(kDefaultEngineLibraryNameSuffix),
加载libaudiopolicyengine.default.so并完成AudioPolicyManager实例构造 */
apm = new AudioPolicyManager(config,
loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
clientInterface);
}
/* 4、初始化AudioPolicyManager */
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
apm = nullptr;
}
return apm;
}
// static
sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
const std::string& xmlFilePath) {
/* 2.1 - xmlFilePath为空,audio_get_audio_policy_config_file获取到的路径为/vendor/etc/audio_policy_configuration.xml */
const std::string filePath =
xmlFilePath.empty() ? audio_get_audio_policy_config_file() : xmlFilePath;
auto config = sp<AudioPolicyConfig>::make();
/* 2.2 - 解析audio_policy_configuration.xml 文件并获得音频策略配置信息 */
if (status_t status = config->loadFromXml(filePath, false /*forVts*/); status == NO_ERROR) {
return config;
}
/* 2.3 - 不会运行到这里 */
return createDefault();
}
status_t AudioPolicyConfig::loadFromXml(const std::string& xmlFilePath, bool forVts) {
...
status_t status = deserializeAudioPolicyFile(xmlFilePath.c_str(), this);
...
}
status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config)
{
PolicySerializer serializer;
return status = serializer.deserialize(fileName, config);
}
status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig *config,
bool ignoreVendorExtensions)
{
/* 完成audio_policy_configuration.xml的解析*/
......
}
以Android的car/emulator的audio_policy_configuration.xml文件为例,下图是xml文件解析后得到的结果,整个解析按照mixPort,devicePort和route的属性解析并最终形成HwModule,条理比较简单,读者自行撸代码也能看懂。
得益于Android丰富的工具,可以通过 dumpsys media.audio_policy 命令查看最终配置的路由策略。
dumpsys media.audio_policy
Supported System Usages:
AUDIO_USAGE_CALL_ASSISTANT, AUDIO_USAGE_EMERGENCY, AUDIO_USAGE_SAFETY, AUDIO_USAGE_VEHICLE_STATUS, AUDIO_USAGE_ANNOUNCEMENT
UID Policy:
mObserverRegistered=True
Assistants UIDs:
No UIDs present.
Active Assistants UIDs:
No UIDs present.
Accessibility UIDs:
No UIDs present.
Input Method Service UID=1010067
Is RTT Enabled: False
AudioCommandThread: 0xb400007416624090
- Commands:
Command Time Wait pParam
Last Command
05 092141.687 0 0xb40000739666f2e0
OutputCommandThread: 0xb400007416625950
- Commands:
Command Time Wait pParam
Last Command
09 092141.966 0 0xb400007306620340
AudioPolicyManager Dump: 0xb4000074466246b0
Primary Output I/O handle: 13
Phone state: AUDIO_MODE_NORMAL
Force use for communications: 0
Force use for media: 10
Force use for record: 0
Force use for dock: 9
Force use for system: 0
Force use for HDMI system audio: 0
Force use for encoded surround output: 0
Force use for vibrate ringing: 0
TTS output not available
Master mono: off
Communication Strategy id: 14
Config source: /vendor/etc/audio_policy_configuration.xml
Available output devices (17):
1. Port ID: 50; "bus1000_mirror_device"; {AUDIO_DEVICE_OUT_BUS, @:bus1000_mirror_device}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- gains:
Gain 1:
- mode: 00000001
- channel_mask: 00000000
- min_value: -3200 mB
- max_value: 600 mB
- default_value: 0 mB
- step_value: 100 mB
- min_ramp_ms: 0 ms
- max_ramp_ms: 0 ms
2. Port ID: 47; "bus211_audio_zone_2"; {AUDIO_DEVICE_OUT_BUS, @:bus211_audio_zone_2}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- gains:
Gain 1:
- mode: 00000001
- channel_mask: 00000000
- min_value: -3200 mB
- max_value: 600 mB
- default_value: 0 mB
- step_value: 100 mB
- min_ramp_ms: 0 ms
- max_ramp_ms: 0 ms
...
6. Port ID: 35; "bus111_audio_zone_1"; {AUDIO_DEVICE_OUT_BUS, @:bus111_audio_zone_1}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- gains:
Gain 1:
- mode: 00000001
- channel_mask: 00000000
- min_value: -3200 mB
- max_value: 600 mB
- default_value: 0 mB
- step_value: 100 mB
- min_ramp_ms: 0 ms
- max_ramp_ms: 0 ms
...
10. Port ID: 23; "bus7_system_sound_out"; {AUDIO_DEVICE_OUT_BUS, @:bus7_system_sound_out}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- gains:
Gain 1:
- mode: 00000001
- channel_mask: 00000000
- min_value: -3200 mB
- max_value: 600 mB
- default_value: 0 mB
- step_value: 100 mB
- min_ramp_ms: 0 ms
- max_ramp_ms: 0 ms
17. Port ID: 2; "bus0_media_out"; {AUDIO_DEVICE_OUT_BUS, @:bus0_media_out}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- gains:
Gain 1:
- mode: 00000001
- channel_mask: 00000000
- min_value: -3200 mB
- max_value: 600 mB
- default_value: 0 mB
- step_value: 100 mB
- min_ramp_ms: 0 ms
- max_ramp_ms: 0 ms
Available input devices (7):
1. Port ID: 53; "Built-In Mic"; {AUDIO_DEVICE_IN_BUILTIN_MIC, @:Built-In Mic}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
channel masks: 0x000c, 0x0010, 0x0030
AUDIO_ENCAPSULATION_TYPE_NONE
2. Port ID: 54; "Built-In Back Mic"; {AUDIO_DEVICE_IN_BACK_MIC, @:Built-In Back Mic}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
channel masks: 0x000c, 0x0010, 0x0030
AUDIO_ENCAPSULATION_TYPE_NONE
...
Hardware modules (3):
1. Handle: 10; "primary"
- Output MixPorts (17):
1. "mixport_bus0_media_out"; 0x0002 (AUDIO_OUTPUT_FLAG_PRIMARY)
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- Supported devices (1):
1. Port ID: 2; "bus0_media_out"; {AUDIO_DEVICE_OUT_BUS, @:bus0_media_out}
Encapsulation modes: 0, metadata types: 0
- maxOpenCount: 1; curOpenCount: 1
- maxActiveCount: 1; curActiveCount: 0
- recommendedMuteDurationMs: 0 ms
2. "mixport_bus1_navigation_out"; 0x0000 (AUDIO_OUTPUT_FLAG_NONE)
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- Supported devices (1):
1. Port ID: 5; "bus1_navigation_out"; {AUDIO_DEVICE_OUT_BUS, @:bus1_navigation_out}
Encapsulation modes: 0, metadata types: 0
- maxOpenCount: 1; curOpenCount: 1
- maxActiveCount: 1; curActiveCount: 0
- recommendedMuteDurationMs: 0 ms
...
- Input MixPorts (4):
1. "primary input"; 0x0000 (AUDIO_INPUT_FLAG_NONE)
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
channel masks: 0x000c, 0x0010, 0x0030
AUDIO_ENCAPSULATION_TYPE_NONE
- Supported devices (3):
1. Port ID: 53; "Built-In Mic"; {AUDIO_DEVICE_IN_BUILTIN_MIC, @:Built-In Mic}
Encapsulation modes: 0, metadata types: 0
2. Port ID: 54; "Built-In Back Mic"; {AUDIO_DEVICE_IN_BACK_MIC, @:Built-In Back Mic}
Encapsulation modes: 0, metadata types: 0
3. Port ID: 55; "Echo-Reference Mic"; {AUDIO_DEVICE_IN_ECHO_REFERENCE, @:Echo-Reference Mic}
Encapsulation modes: 0, metadata types: 0
- maxOpenCount: 1; curOpenCount: 0
- maxActiveCount: 1; curActiveCount: 0
- recommendedMuteDurationMs: 0 ms
...
- Declared devices (23):
1. Port ID: 50; "bus1000_mirror_device"; {AUDIO_DEVICE_OUT_BUS, @:bus1000_mirror_device}
Encapsulation modes: 0, metadata types: 0
- Profiles (1):
1. ""; AUDIO_FORMAT_PCM_16_BIT (0x1)
sampling rates: 48000
channel masks: 0x0003
AUDIO_ENCAPSULATION_TYPE_NONE
- gains:
Gain 1:
- mode: 00000001
- channel_mask: 00000000
- min_value: -3200 mB
- max_value: 600 mB
- default_value: 0 mB
- step_value: 100 mB
- min_ramp_ms: 0 ms
- max_ramp_ms: 0 ms
...
- Audio Routes (21):
1. Mix; Sink: "bus0_media_out"
Sources: "mixport_bus0_media_out"
2. Mix; Sink: "bus1_navigation_out"
Sources: "mixport_bus1_navigation_out"
3. Mix; Sink: "bus2_voice_command_out"
Sources: "mixport_bus2_voice_command_out"
...
2.2 AudioPolicyManager实例构建
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
...
apm = new AudioPolicyManager(config,
loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
clientInterface);
}
2.2.1 loadApmEngineLibraryAndCreateEngine
在2.1章的第3步中config->getEngineLibraryNameSuffix()返回的字符串为“default”(kDefaultEngineLibraryNameSuffix),所以loadApmEngineLibraryAndCreateEngine传入的参数为("default”,null)。
EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
const std::string& configXmlFilePath)
{
/* 1 - 加载libaudiopolicyengine.default.so,获取createEngineInstance句柄并赋值给mCreateEngineInstance */
auto engLib = EngineLibrary::load(librarySuffix);
if (!engLib) {
ALOGE("%s: Failed to load the engine library, suffix \"%s\"",
__func__, librarySuffix.c_str());
return nullptr;
}
/* 2 - 创建ape,这里的configXmlFilePath为空 */
auto engine = engLib->createEngineUsingXmlConfig(configXmlFilePath);
if (engine == nullptr) {
ALOGE("%s: Failed to instantiate the APM engine", __func__);
return nullptr;
}
return engine;
}
EngineInstance EngineLibrary::createEngineUsingXmlConfig(const std::string& xmlFilePath)
{
auto instance = createEngine();
if (instance != nullptr) {
/* 2.1 - xmlFilePath为空,加载engine 配置文件*/
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;
}
status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath) {
return loadWithFallback(xmlFilePath);
}
template<typename T>
status_t Engine::loadWithFallback(const T& configSource) {
/* 2.1.1 - 加载engineConfig::DEFAULT_PATH("/vendor/etc/audio_policy_engine_configuration.xml") 下的ape配置文件 */
auto result = EngineBase::loadAudioPolicyEngineConfig(configSource);
auto legacyStrategy = getLegacyStrategy();
for (const auto &strategy : legacyStrategy) {
mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
}
return OK;
}
APE的调用逻辑比较繁琐,但是原理很清晰:首先确定是否存在用户自定义的configurable engine,如果不存在则使用default engine;确认之后逐步调用并解析相关的APE配置文件。譬如车机的APE配置如下:/frameworks/av/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="audio_policy_engine_product_strategies.xml"/>
<xi:include href="audio_policy_engine_criterion_types.xml"/>
<xi:include href="audio_policy_engine_criteria.xml"/>
<xi:include href="audio_policy_engine_volumes.xml"/>
</configuration>
具体内容在后续使用的过程中分析。
2.3、AudioPolicyManager::initialize
回到2.1的第4步,也是最后一步:AudioPolicyManager的initialize。
status_t AudioPolicyManager::initialize() {
/* 1 - 这里的mEngine就是上面分析的APE,肯定非空了 */
if (mEngine == nullptr) {
return NO_INIT;
}
/* 2 - 将APM设置为Engine的观察器(mApmObserver=APM),
允许Engine检索Devices、Streams、HwModules的信息:
Engine通过APM获取/设置相关信息 */
mEngine->setObserver(this);
/* 3 - 检测Engine是否被正确初始化:mApmObserver!=null, 这不是废话吗?
前面刚设置完成*/
status_t status = mEngine->initCheck();
if (status != NO_ERROR) {
LOG_FATAL("Policy engine not initialized(err=%d)", status);
return status;
}
// The actual device selection cache will be updated when calling `updateDevicesAndOutputs`
// at the end of this function.
/* 4 - 使用产品策略初始化设备,这些设备的策略会在音频模块初始化后更新。*/
mEngine->initializeDeviceSelectionCache();
mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
/* 5 - 有音频模块可用(实际上是首次初始化),完成模块的初始化。*/
// 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 (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;
}
/* 6 - 第5步中完成了整个音频模块的初始化,跟新相关信息到Cache缓存中。
在音频系统稳定后,为了加快处理速度,引擎会缓存基于AudioAttribute/Streams的设备选择。当一个设备连接时,Android的模式会发生变化,引擎会收到通知并更新缓存。如果某个输出上音频流的启动/停止可能影响通知时,引擎需要通过updateDevicesAndOutputs函数更新缓存。*/
updateDevicesAndOutputs();
return status;
}
2.3.1、AudioPolicyManager::onNewAudioModulesAvailableInt
经过2.2章节的分析,我们已经清楚系统已经完成xml配置文件的解析并形成HwModule的多维数据,该函数就是根据先前分析的数据完成音频系统的最重要的一步:调用AF->AHAL完成设备节
点的open,并在AF中创建数据流播放/录制线程,为后面AudioTrack做好准备
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
ALOGD("AudioAnt: onNewAudioModulesAvailableInt enter ......");
/* 1. 遍历audio_policy_configuration.xml中配置的所有模块 */
for (const auto& hwModule : mConfig->getHwModules()) {
if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
continue;
}
if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
ALOGD("AudioAnt: loadHwModule with module name %s", hwModule->getName());
/* 2. 加载相关module,获取module的句柄handle */
if (audio_module_handle_t handle = mpClientInterface->loadHwModule(hwModule->getName());
handle != AUDIO_MODULE_HANDLE_NONE) {
hwModule->setHandle(handle);
} else {
ALOGW("could not load HW module %s", hwModule->getName());
continue;
}
}
/* 3. 如果xml中配置的module存在,则记录到mHwModules容器中以便后面访问使用 */
mHwModules.push_back(hwModule);
/* 4. 遍历当前模块支持的profiles */
for (const auto& outProfile : hwModule->getOutputProfiles()) {
ALOGD("AudioAnt: outProfile with name: %s", outProfile->getTagName().c_str());
/* 5. 获取当前profile支持的设备 */
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
for(auto& device: supportedDevices) {
ALOGD("AudioAnt: supportedDevices with name: %s", device->getTagName().c_str());
}
DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
sp<DeviceDescriptor> supportedDevice = 0;
if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
supportedDevice = mConfig->getDefaultOutputDevice();
} else {
// choose first device present in profile's SupportedDevices also part of
// mAvailableOutputDevices.
if (availProfileDevices.isEmpty()) {
continue;
}
supportedDevice = availProfileDevices.itemAt(0);
}
if (!mConfig->getOutputDevices().contains(supportedDevice)) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile, mpClientInterface);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
/* 6. 打开设备,涉及AHAL的open操作,并在AF中创建相关播放/录制线程 */
status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
DeviceVector(supportedDevice),
AUDIO_STREAM_DEFAULT,
AUDIO_OUTPUT_FLAG_NONE, &output);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for devices %s on hw module %s",
supportedDevice->toString().c_str(), hwModule->getName());
continue;
}
for (const auto &device : availProfileDevices) {
ALOGD("AudioAnt: availProfileDevices with name: %s", device->getTagName().c_str());
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
mAvailableOutputDevices.add(device);
device->setEncapsulationInfoFromHal(mpClientInterface);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
if (mPrimaryOutput == nullptr &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
outputDesc->close();
} else {
addOutput(output, outputDesc);
setOutputDevices(outputDesc,
DeviceVector(supportedDevice),
true,
0,
NULL);
}
}
/* 7. 同输出设置一样的操作逻辑,不赘述 */
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
for (const auto& inProfile : hwModule->getInputProfiles()) {
}
}
/* 8. 如果有声场相关输出,在使用之前先关闭它 */
// Check if spatializer outputs can be closed until used.
// mOutputs vector never contains duplicated outputs at this point.
std::vector<audio_io_handle_t> outputsClosed;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if ((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0
&& !isOutputOnlyAvailableRouteToSomeDevice(desc)) {
outputsClosed.push_back(desc->mIoHandle);
desc->close();
}
}
for (auto output : outputsClosed) {
removeOutput(output);
}
}
最终的操作输出如下:
06-06 21:51:06.077 16876 16876 D APM_AudioPolicyManager: AudioAnt: onNewAudioModulesAvailableInt enter ......
06-06 21:51:06.077 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name primary
06-06 21:51:09.092 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus0_media_out
06-06 21:51:09.092 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus0_media_out
06-06 21:51:09.096 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus0_media_out, SamplingRate
48000, Format 0x000001, Channels 0x3, flags 0x2
06-06 21:51:09.266 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus0_media_out
06-06 21:51:09.316 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus1_navigation_out
06-06 21:51:09.316 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus1_navigation_out
06-06 21:51:09.316 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus1_navigation_out, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.327 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus1_navigation_out
06-06 21:51:09.354 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus2_voice_command_out
06-06 21:51:09.354 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus2_voice_command_out
06-06 21:51:09.354 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus2_voice_command_out, Samp
lingRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.365 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus2_voice_command_out
06-06 21:51:09.391 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus3_call_ring_out
06-06 21:51:09.392 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus3_call_ring_out
06-06 21:51:09.392 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus3_call_ring_out, Sampling
Rate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.403 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus3_call_ring_out
06-06 21:51:09.416 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus4_call_out
06-06 21:51:09.416 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus4_call_out
06-06 21:51:09.416 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus4_call_out, SamplingRate
48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.423 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus4_call_out
06-06 21:51:09.441 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus5_alarm_out
06-06 21:51:09.442 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus5_alarm_out
06-06 21:51:09.442 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus5_alarm_out, SamplingRate
48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.451 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus5_alarm_out
06-06 21:51:09.463 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus6_notification_out
06-06 21:51:09.463 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus6_notification_out
06-06 21:51:09.463 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus6_notification_out, Sampl
ingRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.471 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus6_notification_out
06-06 21:51:09.491 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus7_system_sound_out
06-06 21:51:09.491 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus7_system_sound_out
06-06 21:51:09.491 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus7_system_sound_out, Sampl
ingRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.499 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus7_system_sound_out
06-06 21:51:09.519 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus100_audio_zone_1
06-06 21:51:09.519 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus100_audio_zone_1
06-06 21:51:09.520 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus100_audio_zone_1, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.530 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus100_audio_zone_1
06-06 21:51:09.557 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus101_audio_zone_1
06-06 21:51:09.558 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus101_audio_zone_1
06-06 21:51:09.558 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus101_audio_zone_1, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.569 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus101_audio_zone_1
06-06 21:51:09.598 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus110_audio_zone_1
06-06 21:51:09.598 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus110_audio_zone_1
06-06 21:51:09.598 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus110_audio_zone_1, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.604 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus110_audio_zone_1
06-06 21:51:09.630 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus111_audio_zone_1
06-06 21:51:09.630 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus111_audio_zone_1
06-06 21:51:09.631 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus111_audio_zone_1, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.642 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus111_audio_zone_1
06-06 21:51:09.678 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus200_audio_zone_2
06-06 21:51:09.679 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus200_audio_zone_2
06-06 21:51:09.679 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus200_audio_zone_2, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.690 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus200_audio_zone_2
06-06 21:51:09.713 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus201_audio_zone_2
06-06 21:51:09.713 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus201_audio_zone_2
06-06 21:51:09.713 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus201_audio_zone_2, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.720 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus201_audio_zone_2
06-06 21:51:09.742 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus210_audio_zone_2
06-06 21:51:09.742 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus210_audio_zone_2
06-06 21:51:09.742 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus210_audio_zone_2, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.747 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus210_audio_zone_2
06-06 21:51:09.773 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus211_audio_zone_2
06-06 21:51:09.773 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus211_audio_zone_2
06-06 21:51:09.773 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus211_audio_zone_2, Samplin
gRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.779 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus211_audio_zone_2
06-06 21:51:09.810 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: mixport_bus1000_mirror_device
06-06 21:51:09.810 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: bus1000_mirror_device
06-06 21:51:09.810 16876 16876 I AudioFlinger: AudioAnt: openOutput() this 0xb40000738661f010, module 10 Device AUDIO_DEVICE_OUT_BUS, @:bus1000_mirror_device, Sampl
ingRate 48000, Format 0x000001, Channels 0x3, flags 0
06-06 21:51:09.817 16876 16876 D APM_AudioPolicyManager: AudioAnt: availProfileDevices with name: bus1000_mirror_device
06-06 21:51:09.881 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name a2dp
06-06 21:51:09.882 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name usb
06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: usb_accessory output
06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: USB Host Out
06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: usb_device output
06-06 21:51:09.884 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: USB Device Out
06-06 21:51:09.885 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: USB Headset Out
06-06 21:51:09.885 16876 16876 D APM_AudioPolicyManager: AudioAnt: loadHwModule with module name r_submix
06-06 21:51:09.888 16876 16876 D APM_AudioPolicyManager: AudioAnt: outProfile with name: r_submix output
06-06 21:51:09.888 16876 16876 D APM_AudioPolicyManager: AudioAnt: supportedDevices with name: Remote Submix Out
可以看到此时系统已经创建了多个AudioOut线程(主进程为audioservice),随后如果应用创建了AudioTrack,就可以根据strategy绑定到相关线程,触发或者加入到播放/录制线程。
auto8678p1_64_bsp_vm:/ # ps -ef | grep audioserver
audioserver 16876 1 0 21:51:04 ? 00:00:02 audioserver
auto8678p1_64_bsp_vm:/ # ps -T -p 16876
USER PID TID PPID VSZ RSS WCHAN ADDR S CMD
audioserver 16876 16876 1 12552792 50996 binder_th+ 0 S audioserver
audioserver 16876 16884 1 12552792 50996 binder_th+ 0 S binder:16876_1
audioserver 16876 16885 1 12552792 50996 futex_wai+ 0 S AudioFlinger_Pa
audioserver 16876 16886 1 12552792 50996 binder_th+ 0 S binder:16876_2
audioserver 16876 16887 1 12552792 50996 binder_th+ 0 S HwBinder:16876_
audioserver 16876 16888 1 12552792 50996 binder_th+ 0 S HwBinder:16876_
audioserver 16876 16889 1 12552792 50996 binder_th+ 0 S HwBinder:16876_
audioserver 16876 16891 1 12552792 50996 futex_wai+ 0 S AudioUtilThread
audioserver 16876 16892 1 12552792 50996 futex_wai+ 0 S ApmAudio
audioserver 16876 16893 1 12552792 50996 futex_wai+ 0 S ApmOutput
audioserver 16876 16913 1 12552792 50996 futex_wai+ 0 S TimerThread
audioserver 16876 16914 1 12552792 50996 futex_wai+ 0 S AudioOut_D
audioserver 16876 16915 1 12552792 50996 futex_wai+ 0 S AudioOut_15
audioserver 16876 16916 1 12552792 50996 futex_wai+ 0 S AudioOut_1D
audioserver 16876 16917 1 12552792 50996 futex_wai+ 0 S AudioOut_25
audioserver 16876 16918 1 12552792 50996 futex_wai+ 0 S AudioOut_2D
audioserver 16876 16919 1 12552792 50996 futex_wai+ 0 S AudioOut_35
audioserver 16876 16920 1 12552792 50996 futex_wai+ 0 S AudioOut_3D
audioserver 16876 16921 1 12552792 50996 futex_wai+ 0 S AudioOut_45
audioserver 16876 16922 1 12552792 50996 futex_wai+ 0 S AudioOut_4D
audioserver 16876 16923 1 12552792 50996 futex_wai+ 0 S AudioOut_55
audioserver 16876 16924 1 12552792 50996 futex_wai+ 0 S AudioOut_5D
audioserver 16876 16925 1 12552792 50996 futex_wai+ 0 S AudioOut_65
audioserver 16876 16926 1 12552792 50996 futex_wai+ 0 S AudioOut_6D
audioserver 16876 16927 1 12552792 50996 futex_wai+ 0 S AudioOut_75
audioserver 16876 16928 1 12552792 50996 futex_wai+ 0 S AudioOut_7D
audioserver 16876 16929 1 12552792 50996 futex_wai+ 0 S AudioOut_85
audioserver 16876 16930 1 12552792 50996 futex_wai+ 0 S AudioOut_8D
audioserver 16876 16945 1 12552792 50996 binder_th+ 0 S binder:16876_3
audioserver 16876 16948 1 12552792 50996 binder_th+ 0 S binder:16876_4
audioserver 16876 17743 1 12552792 50996 binder_th+ 0 S binder:16876_5
总结
整体音频链路的准备工作暂时画上一个句号,复杂但是容易理解。音频服务端已经准备就绪,等待音频客户端(AudioTrack/AudioRecord)的加入并开始奇妙的音频之旅。