当按键按下时,底层上报事件给KeyguardUpdateMonitor,窗口管理器WindowManager,从KeyguardUpdateMonitor获取具体按键信息,如果是Volume +/- 则直接由AudioManager.java处理,调用方法adjustSuggestedStreamVolume,其参数direction包括ADJUST_LOWER(- 键)、ADJUST_RAISE(+ 键)、ADJUST_SAME(不调整),suggestedStreamType为音频流类型,flags为特殊标志位,下面会讲到。
adjustSuggestedStreamVolume方法内直接通过IAudioService获取framework层的AudioService服务,广西大学医学院AudioService针对强制使用某种音频,通过AudioSystem的JNI从HAL层获取状态,并进行切换,再执行adjustMasterVolume / adjustSuggestedStreamVolume方法,方法内部处理了STREAM_REMOTE_MUSIC和非REMOTE_MUSIC的音量调整,STREAM_REMOTE_MUSIC是在当后台播放音乐时,不在前台运行的情况。adjustSuggestedStreamVolume先对当前stream获取在执行的streamtype类型,包括通话状态收音机播放,音乐播放等,此处需要hal层获取streamtype,得到streamtype后如果是STREAM_REMOTE_MUSIC,将清楚flags中的标志FLAG_PLAY_SOUND、FLAG_FIXED_VOLUME等。
STREAM_REMOTE_MUSIC类型继续执行adjustRemoteVolume,否则执行adjustStreamVolume,这里主要进入adjustStreamVolume方法。在adjustStreamVolume方法内检查SafeMedaiVolume在插耳机情况下需提示,如果streamtypealias为STREAM_MUSIC,且设备类型包括DEVICE_OUT_AUX_DIGITAL ,将添加flags 标志位:
flags |= AudioManager.FLAG_FIXED_VOLUME
固定不能调节音量的设备包括:
final int mFixedVolumeDevices =
AudioSystem.DEVICE_OUT_AUX_DIGITAL |
AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET |
AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET |
AudioSystem.DEVICE_OUT_ALL_USB;
DEVICE_OUT_AUX_DIGITAL 是针对HDMI类型。
最后,ndVolumeUpdate直接调用mVolumePanel.postVolumeChanged(streamType, flags) 设定并显示进度条,VolumePanel内部会根据flags 标志是否包含 FLAG_FIXED_VOLUME,设定进度条sc.ekbarView.tEnabled(fal / true),VolumePanel内会有个dialog显示。至此,上层的调用过程结束。
在HAL策略上只需修改一处,AudioPolicyManager的computeVolume方法,修改如下:
修改前:
if (stream == AudioSystem::MUSIC &&
index != mStreams[stream].mIndexMin &&
(device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
return 1.0;
}
修改后:
if (stream == AudioSystem::MUSIC &&
index != mStreams[stream].mIndexMin &&
(//device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
device == AUDIO_DEVICE_OUT_DGTL_DOC团总支副书记K_HEADSET ||
device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
return 1.0;
}
具体流程如何走到这里。
对输出策略的管理上,在插HDMI时于桌面调整音量,默认不使用HDMI输出,因为在输出设备判断上有操作:
if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {// no sonification on aux digital (e.g. HDMI)
device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
}
STRATEGY_SONIFICATION为在桌面时调整的声音所使用的类型,每当调整音量时,通过ToneGenerator初始化构造对应音频流鸡西毒王的ToneGenerator桂香,借助AudioFlinger建立AudioTrack实例,在AudioFlinger内部会对音频流类型设置AudioTrack的参数。建立AudioTrack后设置优先级为1并调度运行该线程(叫线程是因为AudioTrack继承thread本分,
可查看类继承)。一旦调度startTone时,AudioTrack start,经过AudioFlinger start 进行数据处理,最后通过AudioService调用AudioPolicyManager,从startoutput --> getNewDevice --> tOutputDevice --> tOutputDevice --> checkAndSetVolume --> getNewDevice --> getNewDevice 等,具体可查看log:
ToneGenerator: ToneGenerator constructor: streamType=2, volume=0.011220
AudioTrack: audiotrack晋文公重耳 0x58ba9540 t Type 2, rate 0, fmt 1, chn 1, fcnt 0, flag 4
AudioFlinger: createTrack() ssionId: 0
AudioFlinge护发素和发膜的区别r: createTrack() lSessionId: 26
AudioFlinger: AUDIO_OUTPUT_FLAG_FAST denied: isTimed=0 sharedBuffer=0x0 frameCount=0 mFrameCount=2048 format=1 isLinear=1 channelMask=0x1 sampleRate=44100 mSampleRate=44100 hasFastMixer=0 tid孟冬寒气至=2176 fastTrackAvailMask=0xfe
dalvikvm: threadid=81: interp stack at 0x566c5000
王献之书法AudioTrac学会爱自己k: sched_tscheduler to rt, priority: 1
AudioFlinger: Track constructor name 4099, calling pid 519
AudioFlinger: acquiring 26 from 519
AudioFlinger: added new entry for 26
ToneGenerator: startTone
AudioTrack: start 0x58ba9540
AudioFlinger: start(4099), calling pid 519 ssion 26
AudioFlinger: ? => ACTIVE (4099) on thread 0x417afb70
AudioPolicyManager: startOutput() output 2, stream 2, ssion 26
AudioPolicyManager: getNewDevice() STRATEGY_SONIFICATION lected device 2 output= 2
AudioPolicyManager: getNewDevice() lected device 2 output= 2
AudioPolicyManager: tOutputDevice() output 2 device 0002 delayMs 0
AudioPolicyManager: checkDeviceMuteStrategies outputDesc = 0x41630950 prevDevice = 2 delayMs = 0
AudioPolicyManager: tOutputDevice() tting same device 0002 or null device for output 2
AudioPolicyManager: checkAndSetVolume stream = 2 index = 7 output = 2 device = 0x2 delayMs = 0 force = 0
AudioPolicyManager: getNewDevice() STRATEGY_SONIFICATION lected device 2 output= 2
AudioPolicyManager: getNewDevice() lected device 2 output= 2
AudioFlinger: mWaitWorkCV.broadcast
AudioFlinger: thread 0x4179f050 type 0 TID 447 waking up