Audio 参数的设置
将参数通过audioFlinger设置到HAL
通常AP层通过frameworks/base/media/java/android/media/AudioManager.java的setParameters 进行audio参数设置,将参数一层一层传入到hal层
/**
1751 /*
1752 * Sets a generic audio configuration parameter.The use of theseparameters
1753 * are platform dependant, see libaudio
1754 *
1755 * ** Temporary interface - DO NOT USE
1756 *
1757 * TODO: Replace with a more generic key:value get/set mechanism
1758 *
1759 * param key name of parameter to set. Must not be null.
1760 * param value value of parameter. Must not be null.
1761 */
1762 /**
1763 * @hide
1764 * @deprecated Use {@link #setParameters(String)} instead
1765 */
1766 @Deprecated public void setParameter(String key, String value) {
1767 setParameters(key+"="+value);
1768 }
/**
1771 * Sets a variable number of parameter values to audio hardware.
1772 *
1773 * @param keyValuePairs list of parameters key value pairs in the form:
1774 * key1=value1;key2=value2;...
1775 *
1776 */
1777 public void setParameters(String keyValuePairs) {
1778 AudioSystem.setParameters(keyValuePairs);
1779 }
参数传递的流程大致如下:
AudioManager.java setParameters
-->AudioSystem.java -->
-->AudioSystem.cpp -->
-->AudioFlinger.cpp
通过AudioFlinger与Hal层进行联系设置 setParameters
对于android O
sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
status_t result = dev->setParameters(keyValuePairs);
DeviceHalInterface接口具体的实现是 DeviceHalHidl
status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
if (mDevice == 0) return NO_INIT;
hidl_vec<ParameterValue> hidlParams;
status_t status = parametersFromHal(kvPairs, &hidlParams);
if (status != OK) return status;
return processReturn("setParameters", mDevice->setParameters(hidlParams));
对于android 7.0
audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
status_t result = dev->set_parameters(dev, keyValuePairs.string());
// return success if at least one audio device accepts the parameters as notall
// HALs are requested to support all parameters. If no audio devicesupports the
// requested parameters, the last error is reported.
audio_hw_device_t 结构体定义在audio.h中
android/hardware/libhardware/include/hardware/audio.h
/* set/get global audio parameters */
int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs);
需要时可以通过AudioSystem getParameters –>AudioManager getParameters 获取参数
将参数设置到audiopolicy传递给engine.cpp
从上面的分析可以知道,正常情况下是通过audioFlinger设置到硬件抽象层,但是有一些参数直接设置到audiopolicy,可以实现ap层控制到audiopolicy
通过AudioSystem获取AudioPolicyService
// establish binder interface to AudioPolicy service
const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service()
在AudioSystem 设置param时setParameters去获取AudioPolicyService,通过AudioPolicyService的实例去setParameters
AudioSystem.cpp
static String8 key_ring_speaker_on =String8("AudioRingSpeakerOn");//add this
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const
String8& keyValuePairs) {
...
AudioParameter param = AudioParameter(keyValuePairs);
//add this
if (param.getInt(key_ring_speaker_on, value) == NO_ERROR){
const sp& aps = AudioSystem::get_audio_policy_service();
if(aps != 0)
{
aps->SetPolicyManagerParameters(POLICY_SET_RING_SPEAKER_ON,value,0,0);
}
在AudioPolicyService中添加SetPolicyManagerParameters方法,调用AudioManager中的添加的SetPolicyManagerParameters方法
/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
status_t AudioPolicyManager::SetPolicyManagerParameters(int par1,int par2,int par3,int par4)
......
//add this
case POLICY_SET_RING_SPEAKER_ON:{
ALOGD("Set POLICY_SET_RING_SPEAKER_ON [%d]",par2);
mEngine->setringspeakeron(par2);
break;
}
AudioPolicyManagerInterface.h
//add this
virtual void setringspeakeron(int a) = 0;
/frameworks/av/services/audiopolicy/enginedefault/src/Engine.h
....
virtual audio_devices_t getDeviceForStrategy(routing_strategy
strategy,audio_output_flags_t flags) const
{
return mPolicyEngine->getDeviceForStrategy(strategy, flags);
}
//add this
virtual void setringspeakeron(int a)
{
return mPolicyEngine->setringspeakeron(a);
}
audio_devices_t getDeviceForStrategy(routing_strategy strategy,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE) const;
//add this
void setringspeakeron(int a);
......
audio_mode_t mPhoneState; /**< current phone state. */
//add this
int ring_speaker_on;
/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
Engine::Engine()
: mManagerInterface(this),
mPhoneState(AUDIO_MODE_NORMAL),
mApmObserver(NULL)
{
ring_speaker_on = 0;//在这里初始化
for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
}
}
//add this
void Engine::setringspeakeron(int a)
{
ring_speaker_on = a;
}
修改音频策略
上面AudioPolicyManager::SetPolicyManagerParameters已经调用mEngine->setringspeakeron(par2);将参数传给mEngine。
现在只需要根据参数修改音频参数即可
routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
case AUDIO_STREAM_RING:
case AUDIO_STREAM_ALARM:
return STRATEGY_SONIFICATION;
铃声对应的strategy是STRATEGY_SONIFICATION,在getDeviceForStrategy中修改 STRATEGY_SONIFICATION下的相关内容
audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy,
audio_output_flags_t flags) const
case STRATEGY_SONIFICATION:
// If incall, just select the STRATEGY_PHONE device: The rest of the
// behavior is handled by handleIncallSonification().
if (isInCall()) {
device = getDeviceForStrategy(STRATEGY_PHONE);
break;
}
// FALL THROUGH
case STRATEGY_ENFORCED_AUDIBLE:
// strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as
// STRATEGY_SONIFICATION
// except:
// - when in call where it doesn't default to STRATEGY_PHONE behavior
// - in countries where not enforced in which case it follows
// STRATEGY_MEDIA
if ((strategy == STRATEGY_SONIFICATION) ||
(mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] ==
AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
//在这里加变量控制
if(ring_speaker_on){
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
}
//
if (device == AUDIO_DEVICE_NONE) {
ALOGE("getDeviceForStrategy() speaker device not found forSTRATEGY_SONIFICATION");
}
}