【Android源码 栏目提醒】:网学会员在Android源码 频道为大家收集整理了“Android深入浅出之AudioPolicy - 操作系统“提供大家参考,希望对大家有所帮助!
Android深入浅出之Audio Policy 一 目的 上回我们说了AudioFlingerAF总感觉代码里边有好多东西没说清楚心里发毛。
就看了看AF的流程我们敢说自己深入了解了Android系统吗AudioPolicyServiceAPS是个什么东西为什么要有它的存在下层的Audio HAL层又是怎么结合到Android中来的更有甚者问个实在问题插入耳机后声音又怎么从最开始的外放变成从耳机输出了调节音量的时候到底是调节Music的还是调节来电音量呢这些东西我们在AF的流程中统统都没讲到。
但是这些他们又是至关重要的。
从我个人理解来看策略Policy比流程更复杂和难懂。
当然遵循我们的传统分析习惯得有一个切入点否则我们都不知道从何入手了。
这里的切入点将是 AF和APS系统第一次起来后到底干了什么。
检测到耳机插入事件后AF和APS的处理。
大家跟着我一步步来看很快就发现啊哈APS也不是那么难嘛。
另外这次代码分析的格式将参考《Linux内核情景分析》的样子函数调用的解析将采用深度优先的办法即先解释所调用的函数然后再出来继续讲。
我曾经数度放弃分析APS关键原因是我没找到切入点只知道代码从头看到尾 二 AF和APS的诞生 这个东西已经说得太多了。
在framework/base/media/MediaServer/Main_MediaServer中。
我们看看。
int mainint argc char argv spltProcessStategt procProcessState::self spltIServiceManagergt sm defaultServiceManager //先创建AF AudioFlinger::instantiate //再创建APS AudioPolicyService::instantiate ProcessState::self-gtstartThreadPool IPCThreadState::self-gtjoinThreadPool 2.1 new AudioFlinger 前面说过instantiate内部会实例化一个对象那直接看AF的构造函数。
AudioFlinger::AudioFlinger : BnAudioFlinger//基类构造函数 mAudioHardware0 mMasterVolume1.0f mMasterMutefalse mNextThreadId0 注意mAudioHardware和mNextThreadId mHardwareStatus AUDIO_HW_IDLE //创建audio的HAL代表 mAudioHardware AudioHardwareInterface::create mHardwareStatus AUDIO_HW_INIT //下面这些不至于会使用APS吧APS还没创建呢 if mAudioHardware-gtinitCheck NO_ERROR setModeAudioSystem::MODE_NORMAL setMasterVolume1.0f setMasterMutefalse 感觉上AF的构造函数就是创建了一个最重要的AudioHardWare的HAL代表。
其他好像是没干什么策略上的事情。
不过AF创建了一个AudioHardware的HAL对象。
注意整个系统就这一个AudioHardware了。
也就是说不管是线控耳机蓝牙耳机麦克外放等等最后都会由这一个HAL统一管理。
再看APS吧。
2.2 new AudioPolicyService AudioPolicyService::AudioPolicyService : BnAudioPolicyService mpPolicyManagerNULL // mpPolicyManager策略管理器可能很重要 char valuePROPERTY_VALUE_MAX // TonePlayback播放铃声的为什么放在这里以后来看看 mTonePlaybackThread new AudioCommandThreadString8quotquot // Audio Command音频命令看到Command我就想到设计模式中的Command模式了 //Android尤其是MediaPlayerService中大量使用了这种模式。
mAudioCommandThread new AudioCommandThreadString8quotApmCommandThreadquot if defined GENERIC_AUDIO defined AUDIO_POLICY_TEST //注意AudioPolicyManagerBase的构造函数把this传进去了。
mpPolicyManager new AudioPolicyManagerBasethis //先假设我们使用Generic的Audio设备吧。
else ... endif // 根据系统属性来判断摄像机是否强制使用声音。
这个...为什么会放在这里 //手机带摄像机好像刚出来的时候为了防止偷拍强制按快门的时候必须发出声音 //就是这个目的吧 property_getquotro.camera.sound.forcedquot value quot0quot mpPolicyManager-gtsetSystemPropertyquotro.camera.sound.forcedquot value so easy不至于吧我们不应该放过任何一个疑问这么多疑问先看哪个呢这里分析的是Audio Policy而构造函数中又创建了一个AudioPolicyManagerBase而且不同厂商还可以实现自己的AudioPolicyManager看来这个对于音频策略有至关重要的作用了。
不得不说的是Android代码中的这些命名在关键地方上还是比较慎重和准确的。
另外AudioPolicyManagerBase的构造函数可是把APS传进去了看来又会有一些回调靠APS了。
真绕。
2.3 AudioPolicyManagerBase 代码位置在framework/base/libs/audioflinger/AudioPolicyManagerBase.cpp中 AudioPolicyManagerBase::AudioPolicyManagerBaseAudioPolicyClientInterface clientInterface : mPhoneStateAudioSystem::MODE_NORMAL ----gt这里有电话的状态 mRingerMode0 mMusicStopTime0 mLimitRingtoneVolumefalse ---gtmPhoneStateAudioSystem::MODE_NORMAL AudioSystem其实是窥视Android如何管理音频系统的好地方。
位置在 framework/base/include/media/AudioSystem.h中定义了大量的枚举之类的东西来表达Google对音频系统的看法。
我们只能见招拆招了。
下面是audio_mode的定义。
这里要注意一个地方 这些定义都和SDK中的JAVA层定义类似。
实际上应该说先有C层的定义然后再反映到JAVA层中。
但是C层的定义一般没有解释说明而SDK中有。
所以我们不能不面对的一个痛苦现实就是常常需要参考SDK的说明才能搞明白到底是什么。
关于C的AudioSystem这块SDK的说明在AudioManager中。
enum audio_mode //解释参考SDK说明以下不再说明 MODE_INVALID -2 //无效mode MODE_CURRENT -1//当前mode和音频设备的切换路由有关 MODE_NORMAL 0//正常mode没有电话和铃声 MODE_RINGTONE//收到来电信号了此时会有铃声 MODE_IN_CALL//电话mode这里表示已经建立通话了 NUM_MODES // Android大量采用这种技巧来表示枚举结束了。
好继续 ... mPhoneStateAudioSystem::MODE_NORMAL ----gt这里有电话的状态 mRingerMode0 mMusicStopTime0 mLimitRingtoneVolumefalse mpClientInterface clientInterface//BT保存APS对象。
//forceUse这是个什么玩意儿 for int i 0 i lt AudioSystem::NUM_FORCE_USE i mForceUsei AudioSystem::FORCE_NONE ----gtAudioSystem::FORCE_NONE和AudioSystem::NUM_FORCE_USE 注意这里有两个枚举太无耻了。
先看看FORCE_NONE这个 enum forced_config 强制_配置看名字好像是强制使用设备吧比如外放耳机蓝牙等 FORCE_NONE FORCE_SPEAKER FORCE_HEADPHONES FORCE_BT_SCO FORCE_BT_A2DP FORCE_WIRED_ACCESSORY FORCE_BT_CAR_DOCK FORCE_BT_DESK_DOCK NUM_FORCE_CONFIG FORCE_DEFAULT FORCE_NONE //这个太无聊了。
再看看AudioSystem::NUM_FORCE_USE这个 enum force_use FOR_COMMUNICATION//这里是for_xxx不是force_xxx。
FOR_MEDIA FOR_RECORD FOR_DOCK NUM_FORCE_USE 不懂两个都不懂。
为何能猜出来什么吗也不行。
因为我们没找到合适的场景那好吧我们去SDK找找。
恩 我看到AudioManager这个函数setSpeakerphoneOn boolean on。
好吧我 这么调用 setSpeakerphoneOntrue看看实现。
这次我没再浪费时间了我用一个新的工具coolfind把搜索framework目录寻找.java文件匹配字符串setSpeakerphone。
终于我在 framework/base/media/java/android/media/AudioService.java中找到了。
pub
上一篇:
Android开发指南
下一篇:
7*30m公路预应力混凝土连续梁桥上部结构设计