audiopolicymanagertest之TEST(AudioPolicyManagerTestInit, Failure)

代码段一览

TEST(AudioPolicyManagerTestInit, Failure) {
    AudioPolicyTestClient client;
    AudioPolicyTestManager manager(&client);
    manager.getConfig().setDefault();
    // Since the default client fails to open anything,
    // APM should indicate that the initialization didn't succeed.
    ASSERT_EQ(NO_INIT, manager.initialize());
    ASSERT_EQ(NO_INIT, manager.initCheck());
}

流程分析

根据gtest框架,test代码最终会执行上面的代码块中的内容。

  • 首先创建一个AudioPolicyTestClient对象
  1. AudioPolicyTestClient派生于AudioPolicyClientInterface。是AudioPolicy与AudioFlinger通信的客户端。
  2. AudioPolicyClientInterface提供了关于硬件的一些操作方法。比如一些常用的接口loadHwModuleopenOutputopenInputgetParameterssetParameters等。
  • 创建AudioPolicyTestManager对象
  1. AudioPolicyTestManager派生于AudioPolicyManager。而AudioPolicyManager继承于AudioPolicyInterfaceAudioPolicyInterface提供了对音频流的管理接口。
  2. AudioPolicyInterface提供了对于音频流控制和策略选择的操作方法,比如getStrategystartOutputgetOutputForAttr等。所以AudioPolicyManager提供了音频策略和设备管理,以及音频流控制的功能。
  3. AudioPolicyTestManager的定义如下:
  class AudioPolicyTestManager : public AudioPolicyManager {
  public:
    explicit AudioPolicyTestManager(AudioPolicyClientInterface *clientInterface)
            : AudioPolicyManager(clientInterface, true /*forTesting*/) { }
    using AudioPolicyManager::getConfig;
    using AudioPolicyManager::initialize;
};

实例化AudiopolicyManager对象,则会调用父类的AudioPolicyManager(clientInterface, true)构造函数,在父类的构造函数中会将AudioPolicyTestClient的实例注册到mpClientInterface。创建StreamDescriptorCollection/VolumeCurvesCollection对象,该对象注册到mVolumeCurves,mVolumeCurves包含一个mVector,mVector保存着流id:StreamDescriptor。创建AudioPolicyConfig对象注册到mConfig。代码如下:

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
                                       bool /*forTesting*/)
    :
    mUidCached(getuid()),
    mpClientInterface(clientInterface),
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
#ifdef USE_XML_AUDIO_POLICY_CONF
    mVolumeCurves(new VolumeCurvesCollection()),
    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
            mDefaultOutputDevice, static_cast<VolumeCurvesCollection*>(mVolumeCurves.get())),
#else
    mVolumeCurves(new StreamDescriptorCollection()),
    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
            mDefaultOutputDevice),
#endif
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
    mHasComputedSoundTriggerSupportsConcurrentCapture(false)
{
}
  • AudioPolicyTestManager设置配置
  1. 通过调用setDefault来对AudioPolicyTestManager实例设置配置,具体代码如下:
manager.getConfig().setDefault()

最终会调用AudioPolicyConfig中的setDefault()方法。

    void setDefault(void)
    {
        mDefaultOutputDevices = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
        sp<HwModule> module;
        sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
        mAvailableOutputDevices.add(mDefaultOutputDevices);
        mAvailableInputDevices.add(defaultInputDevice);

        module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY);

        sp<OutputProfile> outProfile;
        outProfile = new OutputProfile(String8("primary"));
        outProfile->attach(module);
        outProfile->addAudioProfile(
                new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
        outProfile->addSupportedDevice(mDefaultOutputDevices);
        outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
        module->addOutputProfile(outProfile);

        sp<InputProfile> inProfile;
        inProfile = new InputProfile(String8("primary"));
        inProfile->attach(module);
        inProfile->addAudioProfile(
                new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000));
        inProfile->addSupportedDevice(defaultInputDevice);
        module->addInputProfile(inProfile);

        mHwModules.add(module);
    }
  1. setDefault流程分析
    首先通过new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER)创建一个mDefaultOutputDevices对象。通过new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC)创建一个defaultInputDevice对象。最终将mDefaultOutputDevicesdefaultInputDevice分别注册mAvailableOutputDevicesmAvailableInputDevices链表中。
    接着通过new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY)创建一个硬件模块module
    通过new OutputProfile(String8("primary"))创建一个输出配置outProfile,给输出配置添加一个new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100)对象,并将之前创建的SPEAK设备添加到outProfile中,最后在硬件模块module中添加outProfile
    通过new InputProfile(String8("primary"))创建一个输入配置inProfile,给输入配置添加一个 new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000)对象,并将之前创建的MIC设备添加到InputProfile中,最后在硬件模块module中添加InputProfile
    最后,将module注册到mHwModules中。
  • managerinitializeinitCheck进行断言。
    具体代码如下:
    ASSERT_EQ(NO_INIT, manager.initialize());
    ASSERT_EQ(NO_INIT, manager.initCheck());
  1. 调用initializeVolumeCurves来进行每一个流的StreamDescriptor策略初始化。如果该Speaker有DRC1功能,则使用默认的VolumeCurvePoint。
  2. 创建Engine引擎实例,并返回引擎实例。Engine代码如下:
Engine::Engine()
    : mManagerInterface(this),
      mPhoneState(AUDIO_MODE_NORMAL),
      mApmObserver(NULL)
{
    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
    }
}
  1. AudioPolicyManager注册到Engine实例中,并做观察者检测。
    mEngine->setObserver(this);
    status_t status = mEngine->initCheck();
    if (status != NO_ERROR) {
        LOG_FATAL("Policy engine not initialized(err=%d)", status);
        return status;
    }
  1. 加载硬件库,并将其返回句柄添加到hwModule中。
    for (const auto& hwModule : mHwModulesAll) {
        hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
        if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
            ALOGW("could not open HW module %s", hwModule->getName());
            continue;
        }
        ...
}

默认会调用AudioPolicyClient中的loadHwModule方法,但是测试类重新了此方法。具体代码如下:

//默认方法
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return AUDIO_MODULE_HANDLE_NONE;
    }

    return af->loadHwModule(name);
}

//AudioPolicyTestClient重新的方法
    audio_module_handle_t loadHwModule(const char* /*name*/) override {
        return AUDIO_MODULE_HANDLE_NONE;
    }

如果返回参数为AUDIO_MODULE_HANDLE_NONE则不调用后面的操作,最终退出循环。
5. 将无效的输入输出从mAvailableOutputDevicesmAvailableInputDevices列表中移除,并返回NO_INIT,初始化断言成功。
6. 调用AudioPolicyManager::initCheck()来进行初始化检查。代码如下:

status_t AudioPolicyManager::initCheck()
{
    return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
}
  1. for循环没有执行,就没有创建输出,故mPrimaryOutput为0。

  1. Dynamic Range Control(动态范围控制)提供声音压缩和放大能力,使声音听起来更柔和或更大声,即一种信号调幅方式。 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值