文章开端前面的说明:
- 这是我看源码时候认为是流程的当地,代码只是拿了要害代码
- 每句注释前加了【lyh】只是为了让我便利查找
简单的流程图
main_audioserver的初始化
可以看到就直接main_audioserver.cpp中调用了instantiate初始化办法,所以看一下instantiate是什么, 可是进入到AudioPolicyService发现是找不到该办法的,所以只好看一下他所承继的类了
# frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv)
{
if (doLog && (childPid = fork()) != 0) {
...省掉
} else {
// lyh 两个重要的Service初始化
AudioFlinger::instantiate();
AudioPolicyService::instantiate();
// lyh AAudioService 还不知道效果
if (mmapPolicy == AAUDIO_POLICY_AUTO || mmapPolicy == AAUDIO_POLICY_ALWAYS) {
AAudioService::instantiate();
}
// lyh ProcessState::self()获取目标,start发动进程内的binder线程池
ProcessState::self()->startThreadPool();
// lyh 是负责与Binder驱动进⾏具体的命令交互
IPCThreadState::self()->joinThreadPool();
}
}
BinderService新建目标
可以看到总共承继了三个类,而instantiate办法再BinderService中,所以持续进入检查
# frameworks/av/services/audiopolicy/service/AudioPolicyService.h
class AudioPolicyService :
// lyh 每个点进去看一下,或者和AudioFlinger对比一下就知道是这个类了
public BinderService<AudioPolicyService>,
public BnAudioPolicyService,
public IBinder::DeathRecipient
{
}
总的来说instantiate办法总共干了三件事
- 调用子类的结构办法,创立出Service
- 把子类Service加入到service_manager中去统一管理,命名通过子类户
- 其他的进程操作
namespace android {
// 模板类,相当于泛型
template<typename SERVICE>
class BinderService
{
public:
// lyh 调用到这边的静态办法
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
// lyh 把Service添加到service_manager中
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
static void publishAndJoinThreadPool(
bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
publish(allowIsolated, dumpFlags);
joinThreadPool();
}
// lyh 初始化办法,都会调用到这边来,接着调用自己的静态办法
static void instantiate() { publish(); }
static status_t shutdown() { return NO_ERROR; }
private:
static void joinThreadPool() {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
}
};
}
AudioPolicyService的onFirstRef
所以咱们还是持续进入到AudioPolicyService的结构办法中去,发现结构办法除了赋值什么都没干,流程进行不下去了 但通过一阵百度之后可以知道的是
- AudioPolicyService承继BnAudioPolicyService,而后者通过各种承继联系最终承继RefBase,承继RefBase的类在执行结构办法时,会调用onFirstRef办法(binder和sp,wp,RefBase智能指针的知识)
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(),
mAudioPolicyManager(NULL),
mAudioPolicyClient(NULL),
mPhoneState(AUDIO_MODE_INVALID),
mCaptureStateNotifier(false) {
}
// lyh 结构函数调用,会执行到这儿
void AudioPolicyService::onFirstRef()
{
{
// lyh 创立两个线程,控制音频和输出?还不太清楚
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
// lyh 创立AudioPolicyClient,并把自己传入
mAudioPolicyClient = new AudioPolicyClient(this);
// lyh createAudioPolicyManager 最终是执行到AudioPolicyFactory.cpp中的办法去
// lyh createAudioPolicyManager 把AudioPolicyClient传入
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
}
... 省掉代码
}
AudioPolicyFactory帮助结构AudioPolicyManager
所以检查一下AudioPolicyFactory.cpp中的办法,总结一下干了三件事
- 构建AudioPolicyManager实例目标
- 调用AudioPolicyManager初始化办法initialize
- 成功后把目标回来出去
# frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
apm = nullptr;
}
return apm;
}
AudioPolicyManager的新建和初始化
接着进入AudioPolicyManager的结构办法和初始化办法中看一下
- 结构办法首要是加载了装备文件
- 初始化办法首要是创立了引擎,和Manager绑定,并且通过
onNewAudioModulesAvailableInt
翻开输入输出流
# frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface, false /*forTesting*/)
{
// lyh 加载装备文件 audio_policy.conf
// lyh 体系会首先加载vendor/etc目录下的configure文件,再加载system/etc目录下的configure文件。
// lyh 若这两者加载都发生错误的话,体系会加载default装备文件,并命名为primary module,从这可以看
// lyh 出,音频体系中一定有必要存在的module就是primary了
loadConfig();
}
status_t AudioPolicyManager::initialize() {
{
// lyh 加载engine
auto engLib = EngineLibrary::load("libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");
// lyh 创立engine
mEngine = engLib->createEngine();
}
// lyh 引擎和Manger绑定
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
// after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
// open all output streams needed to access attached devices
// lyh 重要办法,翻开输入输出流的,可是为什么传null还没搞清楚
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
// lyh 更新一切信息
updateDevicesAndOutputs();
return status;
}
在AudioPolicyManager的onNewAudioModulesAvailableInt首要做了着几件事
- 加载硬件笼统库,通过loadHwModule办法
- 遍历装备声明中加载出来的输入输出设备
- 找到契合的输入输出设备并翻开
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
// lyh mHwModulesAll 装备声明中的一切模块,猜测是加载装备文件的时候赋值的
for (const auto& hwModule : mHwModulesAll) {
if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
continue;
}
// lyh 加载硬件笼统库,
// lyh 在结构函数中传入的mpClientInterface == AudioPolicyClient,其间实现类AudioPolicyClientImpI.cpp
hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
mHwModules.push_back(hwModule);
// lyh 翻开拜访连接设备所需的一切输出流,
for (const auto& outProfile : hwModule->getOutputProfiles()) {
// lyh 支持的设备(猜测的)
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
// lyh 在支持的设备中挑选咱们的一切设备,挑选出来的就是可用的设备(猜测的)
DeviceVector availProfileDevices = supportedDevices.filter(mOutputDevicesAll);
sp<DeviceDescriptor> supportedDevice = 0;
if (supportedDevices.contains(mDefaultOutputDevice)) {
supportedDevice = mDefaultOutputDevice;
} else {
if (availProfileDevices.isEmpty()) {
continue;
}
supportedDevice = availProfileDevices.itemAt(0);
}
if (!mOutputDevicesAll.contains(supportedDevice)) {
continue;
}
// lyh 备描述符目标 ,传入了mClientInterface
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile, mpClientInterface);
// lyh output表明这个设备的输出流的句柄
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
// lyh 翻开输出流,这儿实践也是调用了mpClientInterface->openOutput
status_t status = outputDesc->open(nullptr, DeviceVector(supportedDevice),
AUDIO_STREAM_DEFAULT,
AUDIO_OUTPUT_FLAG_NONE, &output);
for (const auto &device : availProfileDevices) {
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
// lyh 添加到可用设备列表中
mAvailableOutputDevices.add(device);
// lyh 还没进去看过,猜测是给设备设置一个可以跟HAL层通讯的目标
device->setEncapsulationInfoFromHal(mpClientInterface);
// lyh newDevices是传入的值,还不清楚什么意思
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
if (mPrimaryOutput == 0 &&outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
// lyh direct直接输出到设备的,就把流关闭了
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
outputDesc->close();
} else {
addOutput(output, outputDesc);
// lyh 设置输出设备
setOutputDevices(outputDesc,DeviceVector(supportedDevice),true,0,NULL);
}
}
// lyh 翻开一切输入流,流程和输出流一样
for (const auto& inProfile : hwModule->getInputProfiles()) {
sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile, mpClientInterface);
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
// lyh 和output同理
status_t status = inputDesc->open(nullptr,
availProfileDevices.itemAt(0),
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE,
&input);
for (const auto &device : availProfileDevices) {
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
device->importAudioPortAndPickAudioProfile(inProfile, true);
mAvailableInputDevices.add(device);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
inputDesc->close();
}
}
}
进入AudioFlinger
接着就进入loadHwModule办法看一下
- 通过AudioSystem找到AudioFlinger,再调用loadHwModule办法,这儿开端就和AudioFlinger有了联系
- outputDesc->open盯梢一下最终也是也是AudioFlinger的办法
loadHwModule的流程
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
// lyh 通过AudioSystem拿到AudioFlinger的署理目标,再调用AudioFlinger的办法
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
return af->loadHwModule(name);
}
outputDesc->open的流程
outputDesc = SwAudioOutputDescriptor
mClientInterface = AudioPolicyClientImpI.cpp
status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
const DeviceVector &devices,
audio_stream_type_t stream,
audio_output_flags_t flags,
audio_io_handle_t *output)
{
// lyh 最终回到AudioFligner,翻开输出
status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
output,
&lConfig,
device,
&mLatency,
mFlags);
}