文章开端前面的说明:

  1. 这是我看源码时候认为是流程的当地,代码只是拿了要害代码
  2. 每句注释前加了【lyh】只是为了让我便利查找

简单的流程图

Android音视频一:AudioPolicyService启动

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办法总共干了三件事

  1. 调用子类的结构办法,创立出Service
  2. 把子类Service加入到service_manager中去统一管理,命名通过子类户
  3. 其他的进程操作
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的结构办法中去,发现结构办法除了赋值什么都没干,流程进行不下去了 但通过一阵百度之后可以知道的是

  1. 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中的办法,总结一下干了三件事

  1. 构建AudioPolicyManager实例目标
  2. 调用AudioPolicyManager初始化办法initialize
  3. 成功后把目标回来出去
# 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的结构办法和初始化办法中看一下

  1. 结构办法首要是加载了装备文件
  2. 初始化办法首要是创立了引擎,和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首要做了着几件事

  1. 加载硬件笼统库,通过loadHwModule办法
  2. 遍历装备声明中加载出来的输入输出设备
  3. 找到契合的输入输出设备并翻开

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办法看一下

  1. 通过AudioSystem找到AudioFlinger,再调用loadHwModule办法,这儿开端就和AudioFlinger有了联系
  2. 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);
}