IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Audio代码分析(2): AudioPoilicyService -> 正文阅读

[移动开发]Android Audio代码分析(2): AudioPoilicyService

AudioPolicyService 所在进程

frameworks/av/media/audioserver
? ?audioserver git:(0111) ? tree
.
├── Android.mk
├── audioserver.rc
├── main_audioserver.cpp
└── OWNERS

int main(int argc __unused, char **argv)
{
? ? ? ? android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
? ? ? ? sp<ProcessState> proc(ProcessState::self());
? ? ? ? sp<IServiceManager> sm = defaultServiceManager();
? ? ? ? ALOGI("ServiceManager: %p", sm.get());

? ? ? ? AudioFlinger::instantiate();
? ? ? ? ALOGI("ServiceManager: AudioFlinger instantiate done %p", sm.get());

? ? ? ? AudioPolicyService::instantiate();
? ? ? ? ALOGI("ServiceManager: AudioPolicyService instantiate done %p", sm.get());

? ? ? ? instantiateVRAudioServer();
? ? ? ? ALOGI("ServiceManager: VRAudioServer instantiate done %p", sm.get());

? ? ? ? ALOGI("ServiceManager: done %p", sm.get());
? ? ? ? ProcessState::self()->startThreadPool();
? ? ? ? IPCThreadState::self()->joinThreadPool();
}

AudioPolicyService::instantiate()

就这么一句话包含了整个AudioPolicyService的初始化

在 class AudioPolicyService中没有找到instantiate(),看基类BinderService
template<typename SERVICE>
class BinderService
{
public:
? ? static status_t publish(bool allowIsolated = false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
? ? ? ? sp<IServiceManager> sm(defaultServiceManager());
? ? ? ? return sm->addService(String16(SERVICE::getServiceName()),

????????????????????????????????????????????????new SERVICE(),? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allowIsolated,?dumpFlags);
? ? }

? ? static void instantiate() { publish(); }
};

new SERVICE() -> new AudioPolicyService()

AudioPolicyService()

BinderService::instantiate 调用到 new?AudioPolicyService()

触发对象的创建和初次使用AudioPolicyService() and?AudioPolicyService::onFirstRef()

AudioPolicyService::AudioPolicyService()
? ? : BnAudioPolicyService(), //构造函数
? ? ? mAudioPolicyManager(NULL), //变量初始化
? ? ? mAudioPolicyClient(NULL),
? ? ? mPhoneState(AUDIO_MODE_INVALID),
? ? ? mCaptureStateNotifier(false) {
}

void AudioPolicyService::onFirstRef()
{
? ? {
? ? ? ? // start audio commands thread
? ? ? ? mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
? ? ? ? // start output activity command thread
? ? ? ? mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);

? ? ? ? mAudioPolicyClient = new AudioPolicyClient(this);
? ? ? ? mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

? ? }
? ? // load audio processing modules
? ? sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();

? ? sp<UidPolicy> uidPolicy = new UidPolicy(this);
? ? uidPolicy->registerSelf();
}

AudioCommandThread

?

AudioCommandThread: 哪里有对user permission的判断?
// Thread used to send audio config commands to audio flinger
// For audio config commands, it is necessary because audio flinger requires that the calling
// process (user) has permission to modify audio settings.
class AudioCommandThread : public Thread {}

AudioPolicyClient

class AudioPolicyClient : public AudioPolicyClientInterface

构造函数很简单

AudioPolicyClient(AudioPolicyService *service) : mAudioPolicyService(service) {}

AudioPolicyManager

mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

大部分工作是这个函数完成的,在详细分析该函数之前先看下AudioPolicyInterface 和?AudioPolicyClientInterface

IAudioPolicyService? AudioPolicyInterface? AudioPolicyClientInterface

这三个接口有些函数比较相似,看上去比较乱。IAudioPolicyService是向外提供的接口,其他两个接口是服务它的, AudioPoliocyInterface是平台无关或者说是它会去调用平台相关的AudioPolicyClientInterface, AudioPolicyClientInterface会调用AudioFlinger service 去执行策略。

// The AudioPolicyInterface and AudioPolicyClientInterface classes define the communication interfaces
// between the platform specific audio policy manager and Android generic audio policy manager.
// The platform specific audio policy manager must implement methods of the AudioPolicyInterface class.
// This implementation makes use of the AudioPolicyClientInterface to control the activity and
// configuration of audio input and output streams.

// The platform specific audio policy manager is in charge of the audio routing and volume control
// policies for a given platform.
// The main roles of this module are:
[1] - keep track of current system state (removable device connections, phone state, user requests...).
// ? System state changes and user actions are notified to audio policy manager with methods of the AudioPolicyInterface.

[2] ? - process getOutput() queries received when AudioTrack objects are created: Those queries
// ? return a handler on an output that has been selected, configured and opened by the audio policy manager and that
// ? must be used by the AudioTrack when registering to the AudioFlinger with the createTrack() method.
// ? When the AudioTrack object is released, a putOutput() query is received and the audio policy manager can decide
// ? to close or reconfigure the output depending on other streams using this output and current system state.

[3] ? - similarly process getInput() and putInput() queries received from AudioRecord objects and configure audio inputs.

[4] ? - process volume control requests: the stream volume is converted from an index value (received from UI) to a float value
// ? applicable to each output as a function of platform specific settings and current output route (destination device). It
// ? also make sure that streams are not muted if not allowed (e.g. camera shutter sound in some countries).
//

AudioPolicyManager (APM)

AudioPolicyManager implements audio policy manager behavior common to all platforms
class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver
{}

mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

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;
}

// These methods should be used when finer control over APM initialization
// is needed, e.g. in tests. Must be used in conjunction with the constructor
// that only performs fields initialization. The public constructor comprises
// these steps in the following sequence:
// ? - field initializing constructor;
// ? - loadConfig;
// ? - initialize.

createAudioPolicyManager分为两部分:

1. new AudioPolicyManager(AudioPolicyClientInterface)

2. apm->initialize()

new AudioPolicyManager(clientInterface)

这里构造函数有两个:一个参数、两个参数,但最关键的函数还是 loadConfig()

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
? ? ? ? : AudioPolicyManager(clientInterface, false /*forTesting*/)
{
? ? loadConfig();
}


AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?bool /*forTesting*/)
? ? :
? ? mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
? ? mpClientInterface(clientInterface),
? ? mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
? ? mA2dpSuspended(false),
? ? mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice),
? ? mAudioPortGeneration(1),
? ? mEnableAudioLoopback(false),
? ? mIsCERegion(false),
? ? mBeaconMuteRefCount(0),
? ? mBeaconPlayingRefCount(0),
? ? mBeaconMuted(false), ? ??
? ? mTtsOutputAvailable(false),
? ? mMasterMono(false),
? ? mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
}

loadConfig()

audio_policy_configuration.xml的格式

audio_policy_configuration.xml
? ? <!-- Modules section:
? ? ? ? There is one section per audio HW module present on the platform.
? ? ? ? Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
? ? ? ? The module names are the same as in current .conf file:
? ? ? ? ? ? ? ? “primary”, “A2DP”, “remote_submix”, “USB”
? ? ? ? Each module will contain the following sections:
? ? ? ? “devicePorts”: a list of device descriptors for all input and output devices accessible via this
? ? ? ? module.
? ? ? ? This contains both permanently attached devices and removable devices.
? ? ? ? “mixPorts”: listing all output and input streams exposed by the audio HAL

? ? ? ? ?(HAL 不导出devicePorts?)
? ? ? ? “routes”: list of possible connections between input and output devices or between stream? ? ? ? ? ? ? ? ? ? ? ? ? and devices.
? ? ? ? ? ? "route": is defined by an attribute:
? ? ? ? ? ? ? ? -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
? ? ? ? ? ? ? ? -"sink": the sink involved in this route
? ? ? ? ? ? ? ? -"sources": all the sources than can be connected to the sink via vis route
? ? ? ? “attachedDevices”: permanently attached devices.
? ? ? ? The attachedDevices section is a list of devices names. The names correspond to device names
? ? ? ? defined in <devicePorts> section.
? ? ? ? “defaultOutputDevice”: device to be used by default when no policy rule applies
? ? -->

deserializeAudioPolicyXmlConfig解析配置文件

deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) ->
? ? ? ? deserializeAudioPolicyFile(audioPolicyXmlConfigFile,??//"audio_policy_configuration.xml"

? ? ? ? ? ? ? ? ? ? ? ? &config);?

frameworks/av/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp

status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config)
{
? ? PolicySerializer serializer;
? ? return serializer.deserialize(fileName, config);
}

template<typename E, typename C>
struct AndroidCollectionTraits {
? ? typedef sp<E> Element;
? ? typedef C Collection;
? ? typedef void* PtrSerializingCtx;

? ? static status_t addElementToCollection(const Element &element, Collection *collection) {
? ? ? ? return collection->add(element) >= 0 ? NO_ERROR : BAD_VALUE;
? ? }
};

// A profile section contains a name, ?one audio format and the list of supported sampling rates
// and channel masks for this format
struct AudioProfileTraits : public AndroidCollectionTraits<AudioProfile, AudioProfileVector>
{
? ? static constexpr const char *tag = "profile";
? ? static constexpr const char *collectionTag = "profiles";

? ? struct Attributes
? ? {
? ? ? ? static constexpr const char *samplingRates = "samplingRates";
? ? ? ? static constexpr const char *format = "format";
? ? ? ? static constexpr const char *channelMasks = "channelMasks";
? ? };

? ? static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};


struct MixPortTraits : public AndroidCollectionTraits<IOProfile, IOProfileCollection>
{
? ? static constexpr const char *tag = "mixPort";
? ? static constexpr const char *collectionTag = "mixPorts";

? ? struct Attributes
? ? {
? ? ? ? static constexpr const char *name = "name";
? ? ? ? static constexpr const char *role = "role";
? ? ? ? static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
? ? ? ? static constexpr const char *flags = "flags";
? ? ? ? static constexpr const char *maxOpenCount = "maxOpenCount";
? ? ? ? static constexpr const char *maxActiveCount = "maxActiveCount";
? ? };

? ? static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
? ? // Children: GainTraits
};

struct DevicePortTraits : public AndroidCollectionTraits<DeviceDescriptor, DeviceVector>
{
? ? static constexpr const char *tag = "devicePort";
? ? static constexpr const char *collectionTag = "devicePorts";

? ? struct Attributes
? ? {
? ? ? ? /** ?<device tag name>: any string without space. */
? ? ? ? static constexpr const char *tagName = "tagName";
? ? ? ? static constexpr const char *type = "type"; /**< <device type>. */
? ? ? ? static constexpr const char *role = "role"; /**< <device role: sink or source>. */
? ? ? ? static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
? ? ? ? /** optional: device address, char string less than 64. */
? ? ? ? static constexpr const char *address = "address";
? ? ? ? /** optional: the list of encoded audio formats that are known to be supported. */
? ? ? ? static constexpr const char *encodedFormats = "encodedFormats";
? ? };

? ? static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
? ? // Children: GainTraits (optional)
};


struct RouteTraits : public AndroidCollectionTraits<AudioRoute, AudioRouteVector>
{
? ? static constexpr const char *tag = "route";
? ? static constexpr const char *collectionTag = "routes";

? ? struct Attributes
? ? {
? ? ? ? static constexpr const char *type = "type"; /**< <route type>: mix or mux. */
? ? ? ? static constexpr const char *typeMix = "mix"; /**< type attribute mix value. */
? ? ? ? static constexpr const char *sink = "sink"; /**< <sink: involved in this route>. */
? ? ? ? /** sources: all source that can be involved in this route. */
? ? ? ? static constexpr const char *sources = "sources";
? ? };

? ? typedef HwModule *PtrSerializingCtx;

? ? static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};

struct ModuleTraits : public AndroidCollectionTraits<HwModule, HwModuleCollection>
{
? ? static constexpr const char *tag = "module";
? ? static constexpr const char *collectionTag = "modules";

? ? static constexpr const char *childAttachedDevicesTag = "attachedDevices";
? ? static constexpr const char *childAttachedDeviceTag = "item";
? ? static constexpr const char *childDefaultOutputDeviceTag = "defaultOutputDevice";

? ? struct Attributes
? ? {
? ? ? ? static constexpr const char *name = "name";
? ? ? ? static constexpr const char *version = "halVersion";
? ? };

? ? typedef AudioPolicyConfig *PtrSerializingCtx;

? ? static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
? ? // Children: mixPortTraits, devicePortTraits, and routeTraits
? ? // Need to call deserialize on each child
};

每个xxxTraints都有自己的deserialize 函数

Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
{
1]: <module name="primary" halVersion="2.0">
? ? std::string name = getXmlAttribute(cur, Attributes::name);

? ? uint32_t versionMajor = 0, versionMinor = 0;
? ? std::string versionLiteral = getXmlAttribute(cur, Attributes::version);
? ? if (!versionLiteral.empty()) {
? ? ? ? sscanf(versionLiteral.c_str(), "%u.%u", &versionMajor, &versionMinor);
? ? }

? ? Element module = new HwModule(name.c_str(), versionMajor, versionMinor);


? ? // Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes

2]: <mixPorts>
? ? MixPortTraits::Collection mixPorts;
? ? status_t status = deserializeCollection<MixPortTraits>(cur, &mixPorts, NULL);
? ? if (status != NO_ERROR) {
? ? ? ? return Status::fromStatusT(status);
? ? }
? ? module->setProfiles(mixPorts); // class HwModule -> addProfile-> addOut/InputProfile:?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// mOut/InputProfiles.add(profile) and mPorts.add(profile)
?? ??? ??? ??? ? ??
3]: <devicePorts>
? ? DevicePortTraits::Collection devicePorts;
? ? status = deserializeCollection<DevicePortTraits>(cur, &devicePorts, NULL);
? ? if (status != NO_ERROR) {
? ? ? ? return Status::fromStatusT(status);
? ? }
? ? module->setDeclaredDevices(devicePorts); // mDeclaredDevices = devices; mPorts.add(device[i])

4]: <routes>
? ? RouteTraits::Collection routes;
? ? status = deserializeCollection<RouteTraits>(cur, &routes, module.get());
? ? if (status != NO_ERROR) {
? ? ? ? return Status::fromStatusT(status);
? ? }
? ? module->setRoutes(routes);

5]: attachedDevices
? ? ?sp<DeviceDescriptor> device = module->getDeclaredDevices().
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? getDeviceFromTagName(std::string(reinterpret_cast<const char*>(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? attachedDevice.get())));
? ? ?ctx->addDevice(device); // ctx指的是 class AudioPolicyConfig

6]: defaultOutputDevice
? ? sp<DeviceDescriptor> device = module->getDeclaredDevices().getDeviceFromTagName(
? ? ? ? ? ? ? ? ? ? ? ? std::string(reinterpret_cast<const char*>(defaultOutputDevice.get())));
? ? ctx->setDefaultOutputDevice(device);
}
?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:57:05  更:2021-08-06 09:57:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 11:29:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码