为什么要单独写个文章讲到这个类,因为这个类在之前我们获取可用的输入输出设备的时候AudioPolicyEngine设备路由调用过其中的方法,但是没有深入分析,而且这个类是AudioPolicyManager的接口,同时这个类可以引申出其它的Audio抽象类,最后要讲解Vector和Collection容器的使用,所以说要写的内容仍然很多。
/frameworks/av/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 &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 >
可以看到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(android_atomic_inc(&mNextUniqueId));
}
递增获取的。共有变量
String8 mAddress;
现在需要掌握的是DeviceDescriptor是用于描述设备用的。
和接下来的Vector有关的两个函数,获取设备值和判断两个设备是否相等。
audio_devices_t type() const { return mDeviceType; }
bool DeviceDescriptor::equals(const sp& 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 >
{
public:
DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
ssize_t add(const sp& item);
void add(const DeviceVector &devices);
ssize_t remove(const sp& item);
ssize_t indexOf(const sp& item) const;
audio_devices_t types() const { return mDeviceTypes; }
sp getDevice(audio_devices_t type, const String8& address) const;
DeviceVector getDevicesFromType(audio_devices_t types) const;
sp getDeviceFromId(audio_port_handle_t id) const;
sp 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& 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 DeviceVector::getDevice(audio_devices_t type, const String8& address) const
{
sp 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(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 mDefaultOutputDevice; // output device selected by default at boot time
这个变量和上面提到的变量初始化是相同的道理,不在赘述。
总结:
本章主要讲述的是DeviceVector和DeviceDescriptor两个类,一个是容器,一个是物体,容器存放物体。然后讲述AudioPolicyManagerObserver关于上述两个类的接口,真正的实现是在AudioPolicyManager中,初始化是在构造器中。
下章:
总结中已经说到初始化,那么初始化是怎么工作的呢?下面会讲述加载设备配置文件。