您的位置:首页 > 移动开发 > Android开发

android音量调整流程+HDMI音量控制修改

2015-07-07 21:48 363 查看
当按键按下时,底层上报事件给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类型。

 

最后,sendVolumeUpdate直接调用mVolumePanel.postVolumeChanged(streamType, flags) 设定并显示进度条,VolumePanel内部会根据flags 标志是否包含 FLAG_FIXED_VOLUME,设定进度条sc.seekbarView.setEnabled(false / 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_DOCK_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 --> setOutputDevice --> setOutputDevice --> checkAndSetVolume
--> getNewDevice --> getNewDevice 等,具体可查看log:

 

ToneGenerator: ToneGenerator constructor: streamType=2, volume=0.011220

AudioTrack:
audiotrack 0x58ba9540 set Type 2, rate 0, fmt 1, chn 1, fcnt 0, flag 4

AudioFlinger: createTrack() sessionId: 0

AudioFlinger: 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

AudioTrack: sched_setscheduler to rt, priority: 1

AudioFlinger: Track constructor name4099, calling pid519

AudioFlinger: acquiring 26 from 519

AudioFlinger:  added new entry for 26

ToneGenerator: startTone

AudioTrack: start 0x58ba9540

AudioFlinger: start(4099), calling pid 519 session 26

AudioFlinger: ? => ACTIVE (4099) on thread 0x417afb70

AudioPolicyManager: startOutput()output 2, stream2, session 26

AudioPolicyManager: getNewDevice()
STRATEGY_SONIFICATION selected device2 output= 2

AudioPolicyManager: getNewDevice() selected device2 output= 2

AudioPolicyManager: setOutputDevice() output 2 device0002 delayMs 0

AudioPolicyManager: checkDeviceMuteStrategies outputDesc = 0x41630950 prevDevice = 2 delayMs = 0

AudioPolicyManager: setOutputDevice() setting samedevice 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 selected device2 output= 2

AudioPolicyManager: getNewDevice() selected device2 output= 2

AudioFlinger: mWaitWorkCV.broadcast

AudioFlinger: thread 0x4179f050 type 0 TID 447 waking up

 

这里会在getNewDevice时获取输出设备,会进入策略方法进行判断,需要去掉STRATEGY_SONIFICATION部分限制,如下:

if ((device2 ==AUDIO_DEVICE_NONE))//&& (strategy!=
STRATEGY_SONIFICATION))      {// no sonification on aux digital (e.g. HDMI)

     device2 = mAvailableOutputDevices& AUDIO_DEVICE_OUT_AUX_DIGITAL;

}

 

以上从策略层进行修改,另一种方法是从framework进行修改,从VolumePanle中修改StreamResources中的值:

VoiceStream(AudioManager.STREAM_VOICE_CALL,

               R.string.volume_icon_description_incall,

                R.drawable.ic_audio_phone,

                R.drawable.ic_audio_phone,

                false)

为,

VoiceStream(AudioManager.STREAM_MEDIA,

               R.string.volume_icon_description_incall,

                R.drawable.ic_audio_phone,

                R.drawable.ic_audio_phone,

                false)

但第二种修改不适合带modem功能的设备,第二种修改也就是直接将通话改为多媒体类型。

 

出处 http://wenku.baidu.com/link?url=NBpwxTLRDyCD3NErm1P3CZgYYc3HvAKN_bM9DL80m8curLxMMa8qmP69nePlILNO2iIBdoqZ41Ijjr9Sc9R03RJZ2mAikF0AHbCX_SuQ5OC
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: