Android源码分析--AudioPolicyManagerObserver类讲解(05)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WAN_EXE/article/details/79156218

    为什么要单独写个文章讲到这个类,因为这个类在之前我们获取可用的输入输出设备的时候AudioPolicyEngine设备路由调用过其中的方法,但是没有深入分析,而且这个类是AudioPolicyManager的接口,同时这个类可以引申出其它的Audio抽象类,最后要讲解Vector和Collection容器的使用,所以说要写的内容仍然很多。

/frameworks/av/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h

#pragma once

#include <IVolumeCurvesCollection.h>
#include <AudioGain.h>
#include <AudioPort.h>
#include <AudioPatch.h>
#include <IOProfile.h>
#include <DeviceDescriptor.h>
#include <AudioInputDescriptor.h>
#include <AudioOutputDescriptor.h>
#include <AudioPolicyMix.h>
#include <SoundTriggerSession.h>

namespace android {

/**
 * This interface is an observer that the manager shall implement to allows e.g. the engine
 * to access to policy pillars elements (like output / input descritors collections,
 * HwModule collections, AudioMix, ...
 */
class AudioPolicyManagerObserver
{
public:
    virtual const AudioPatchCollection &getAudioPatches() const = 0;

    virtual const SoundTriggerSessionCollection &getSoundTriggerSessionCollection() const = 0;

    virtual const AudioPolicyMixCollection &getAudioPolicyMixCollection() const = 0;

    virtual const SwAudioOutputCollection &getOutputs() const = 0;

    virtual const AudioInputCollection &getInputs() const = 0;

    virtual const DeviceVector &getAvailableOutputDevices() const = 0;

    virtual const DeviceVector &getAvailableInputDevices() const = 0;

    virtual IVolumeCurvesCollection &getVolumeCurves() = 0;

    virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const = 0;

protected:
    virtual ~AudioPolicyManagerObserver() {}
};

};

这个类全是获取方法,来看DeviceVector类的作用和实现。后面的章节应该会专门抽出章节讲述C++的容器,现在还是以看代码为准,没有必要去弄清楚每个类,但是需要知道它们的意思,以便更好的分析,接下来来看两个类。

/frameworks/av/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h

class DeviceDescriptor : public AudioPort, public AudioPortConfig
class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
可以看到DeviceVector继承自SortedVector,从名字上就可以看到,SortedVector是已经排好序的Vector的实现,Android并没有用标准库中的Vector,但是应该可以知道和它实现的功能差不多。

需要弄清楚这个变量

audio_devices_t mDeviceTypes;
可以看到后面有个s,表示它是多种类型的设备,为什么是audio_devices_t类型呢?最开始介绍设备选择的时候,有提到

AUDIO_DEVICE_OUT_ALL = 2013265919u,它是所有输出设备的集合,Android中用位来表示每个设备,用整形来表示设备的集合,所以这里的mDeviceTypes表示所有的设备。

接下来看如何向这个类中增加设备,移除设备,给出设备确定设备的index值,通过types值获取设备向量,通过type获取设备。先来看存到向量里面的类DeviceDescriptor,有三个私有变量

private:
    String8 mTagName; // Unique human readable identifier for a device port found in conf file.
    audio_devices_t     mDeviceType;
    audio_port_handle_t mId;
mDeviceType就是指设备值,就是上面提到的type值,mId是通过

// Note that is a different namespace than AudioFlinger unique IDs
audio_port_handle_t AudioPort::getNextUniqueId()
{
    return static_cast<audio_port_handle_t>(android_atomic_inc(&mNextUniqueId));
}
递增获取的。共有变量

    String8 mAddress;

现在需要掌握的是DeviceDescriptor是用于描述设备用的。

和接下来的Vector有关的两个函数,获取设备值和判断两个设备是否相等。

    audio_devices_t type() const { return mDeviceType; }
bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
{
    // Devices are considered equal if they:
    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
    // - have the same address
    if (other == 0) {
        return false;
    }
    return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
}
DeviceVector类也很容易理解

class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
{
public:
    DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}

    ssize_t add(const sp<DeviceDescriptor>& item);
    void add(const DeviceVector &devices);
    ssize_t remove(const sp<DeviceDescriptor>& item);
    ssize_t indexOf(const sp<DeviceDescriptor>& item) const;

    audio_devices_t types() const { return mDeviceTypes; }

    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8& address) const;
    DeviceVector getDevicesFromType(audio_devices_t types) const;
    sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
    sp<DeviceDescriptor> getDeviceFromTagName(const String8 &tagName) const;
    DeviceVector getDevicesFromTypeAddr(audio_devices_t type, const String8& address) const;

    audio_devices_t getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;

    status_t dump(int fd, const String8 &tag, int spaces = 0, bool verbose = true) const;

private:
    void refreshTypes();
    audio_devices_t mDeviceTypes;
};

可以通过type, id, tag获取设备描述,通过type获取设备向量。两个增加函数,一个移除设备函数,最后一个查找设备的函数。

        增加设备描述,首先判断设备描述是否存在,如果存在indexOf函数返回大于0的值,如果返回值小于0,说明设备描述还没有加入到DeviceVector中,那么利用父类的SortedVector::add增加函数加入设备,然后更新设备向量值。

ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
{
    ssize_t ret = indexOf(item);

    if (ret < 0) {
        ret = SortedVector::add(item);
        if (ret >= 0) {
            refreshTypes();
        }
    } else {
        ALOGW("DeviceVector::add device %08x already in", item->type());
        ret = -1;
    }
    return ret;
}
remove的函数也是相同的道理,都是调用父类的SortedVector::remove函数之后然后更新设备向量值。

通过type和address进行查找,从函数来看,只需要type就可以查找到设备描述,如果传递的address为空的话。

sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address) const
{
    sp<DeviceDescriptor> device;
    for (size_t i = 0; i < size(); i++) {
        if (itemAt(i)->type() == type) {
            if (address == "" || itemAt(i)->mAddress == address) {
                device = itemAt(i);
                if (itemAt(i)->mAddress == address) {
                    break;
                }
            }
        }
    }
    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
          type, address.string(), device.get());
    return device;
}
分析完成DeviceVector之后,主要是记住DeviceDescriptor的4个变量,然后DeviceVector就是存放这个DeviceDescripter的,下面接着来分析AudioPolicyManagerObserver和DeviceVector有关的三个函数。

class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver
可以看到AudioPolicyManager继承AudioPolicyManagerObserver接口,实现是在AudioPolicyManager中。

非常简单,就是在头文件中定义两个变量

        DeviceVector  mAvailableOutputDevices; // all available output devices
        DeviceVector  mAvailableInputDevices;  // all available input devices
然后返回

        virtual const DeviceVector &getAvailableOutputDevices() const
        {
            return mAvailableOutputDevices;
        }
        virtual const DeviceVector &getAvailableInputDevices() const
        {
            return mAvailableInputDevices;
        }
很明显这两个变量需要在AudioPolicyManager构造器中进行初始化。可以看到

#ifdef USE_XML_AUDIO_POLICY_CONF
    mVolumeCurves = new VolumeCurvesCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled,
                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
#else
    mVolumeCurves = new StreamDescriptorCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled);
    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
#endif
        ALOGE("could not load audio policy configuration file, setting defaults");
        config.setDefault();
    }
它们是通过xml文件进行解析配置的,所以下章需要分析这个配置文件是如何加载到framework层的。

还有一个变量

        sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
这个变量和上面提到的变量初始化是相同的道理,不在赘述。

总结:

        本章主要讲述的是DeviceVector和DeviceDescriptor两个类,一个是容器,一个是物体,容器存放物体。然后讲述AudioPolicyManagerObserver关于上述两个类的接口,真正的实现是在AudioPolicyManager中,初始化是在构造器中。

下章:

        总结中已经说到初始化,那么初始化是怎么工作的呢?下面会讲述加载设备配置文件。













猜你喜欢

转载自blog.csdn.net/WAN_EXE/article/details/79156218