Android Audio Framework 之AudioPolicyService

AudioPolicyService 是audio framework 的一大service, 另外一个是AudioFlinger。

一直觉得通过代码来分析的话写起来很费劲, 最近去看了下UML, 通过同UML 去分析感觉比较清晰,而我自己看回来的话也很容易就知道框架是怎样。

先看下AudioPolicyService 的各个主要类的关系。

这个看起来简单清晰多了。

有必要说一下代码中AudioPolicyClient, 它是AudioPolicyService 的子类,它是这么存在的。

 void AudioPolicyService::onFirstRef()
{
        ......
        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
        ......
}
对象在AudioPolicyService::onFirstRef() 被创建, 并以指针的形式作为参数去创建AudioPolicyManager
extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManager(clientInterface);
}

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
    :
#ifdef AUDIO_POLICY_TEST
    Thread(false),
#endif //AUDIO_POLICY_TEST
    mPrimaryOutput((audio_io_handle_t)0),
    mPhoneState(AUDIO_MODE_NORMAL),
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
    mA2dpSuspended(false),
    mSpeakerDrcEnabled(false), mNextUniqueId(1),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false)
{
    mUidCached = getuid();
    mpClientInterface = clientInterface;
}
所以在AudioPolicyManager 里面看到mpClientInterface 的调用就是AudioPolicyClient 类的方法。AudioPolicyClient 的方法实现在文件AudioPolicyClientImpl.cpp 中, 它主要的功能就是通过它来call 到AudioFlinger 的方法, 其中有两种方式, 一种是直接通过AudioSystem::get_audio_flinger() 来获得BpAudioFlinger,然后。。。
status_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
                                                          audio_io_handle_t *input,
                                                          audio_config_t *config,
                                                          audio_devices_t *device,
                                                          const String8& address,
                                                          audio_source_t source,
                                                          audio_input_flags_t flags)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return PERMISSION_DENIED;
    }

    return af->openInput(module, input, config, device, address, source, flags);
}

另外一种方法就是调用AudioPolicyService 的方法, 将cmd作为一个node放到AudioPolicyService::AudioCommandThread 的队列中,然后一个CommandThread 会不断的处理这些cmd node, 在处理的时候也是通过第一种方式call 到AudioFlinger, 加个队列我想是考虑某些cmd 比较频繁, 考虑性能问题。

status_t AudioPolicyService::AudioPolicyClient::createAudioPatch(const struct audio_patch *patch,
                                                                  audio_patch_handle_t *handle,
                                                                  int delayMs)
{
    return mAudioPolicyService->clientCreateAudioPatch(patch, handle, delayMs);
}

status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
                                                audio_patch_handle_t *handle,
                                                int delayMs)
{
    return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
}

status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
                                                const struct audio_patch *patch,
                                                audio_patch_handle_t *handle,
                                                int delayMs)
{
    status_t status = NO_ERROR;

    sp<AudioCommand> command = new AudioCommand();
    command->mCommand = CREATE_AUDIO_PATCH;
    CreateAudioPatchData *data = new CreateAudioPatchData();
    data->mPatch = *patch;
    data->mHandle = *handle;
    command->mParam = data;
    command->mWaitStatus = true;
    ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
    status = sendCommand(command, delayMs);
    if (status == NO_ERROR) {
        *handle = data->mHandle;
    }
    return status;
}

                case CREATE_AUDIO_PATCH: {
                    CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
                    ALOGV("AudioCommandThread() processing create audio patch");
                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
                    if (af == 0) {
                        command->mStatus = PERMISSION_DENIED;
                    } else {
                        command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
                    }
                    } break;


然后再以getOutput 的时序图看下,整个AudioPolicyService 的各种调用关系。

在Audio Framework中 两个service 的入口都是AudioSystem 类, 所以这个时序图以AduioSystem开始,同时通过这个时序图也可以发现AudioPolicyService 是怎么走到AudioFlinger 的,也是通过AudioSystem类。

AudioPolicyService 的框架基本就这样了, 代码中的一些具体实现就是业务相关的了。。。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值