按键事件派发已经分析过,调节音量流程直接从phonewindow onkeydown 开始分析。
protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN: {
int direction = keyCode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE
: AudioManager.ADJUST_LOWER;
if (mMediaController != null) {
mMediaController.adjustVolume(direction, AudioManager.FLAG_SHOW_UI);
} else {
MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(
mVolumeControlStreamType, direction,
AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
}
return true;
}
}
keycode用来判断音量增减,AudioManager.ADJUST_RAISE 表示增大,ADJUST_LOWER表示降低
通过getHelper静态函数实例化MediaSessionLegacyHelper, 调用其成员函数sendAdjustVolumeBy,将direction参数传入,以供使用。
具体实现见MediaSessionLegacyHelper.java
public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags);
}
mSessionManager 是在构造函数中获取的系统服务manager,通过binder 机制调用到MediaSessionService的成员函数
dispatchAdjustVolume,
MediaSessionService.java
public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
MediaSessionRecord session = mPriorityStack
.getDefaultVolumeSession(mCurrentUserId);
dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
private void dispatchAdjustVolumeLocked(int suggestedStream, int direction, int flags,
MediaSessionRecord session) {
mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
flags, packageName);
}
调用到AudioService, 这是framework层audio控制核心,通过sendmsg函数以hanlder方式调用到
AudioService.java
private void setDeviceVolume(VolumeStreamState streamState, int device) {
mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
}
public void applyDeviceVolume_syncVSS(int device) {
AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
}
通过audioSystem调用本地方法setStreamVolumeIndex, 进入jni层
android_mediao_AudioSystem.cpp
static jint
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
jobject thiz,
jint stream,
jint index,
jint device)
{
return (jint) check_AudioSystem_Command(
AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
index,
(audio_devices_t)device));
}
AudioSystem.cpp
status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream,
int index,
audio_devices_t device)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setStreamVolumeIndex(stream, index, device);
}
int index,
audio_devices_t device)
{
Mutex::Autolock _l(mLock);
return mAudioPolicyManager->setStreamVolumeIndex(stream,
index,
device);
}
AudioPolicyManager.cpp
status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
int index,
audio_io_handle_t output,
audio_devices_t device,
int delayMs,
bool force)
{
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
}
AudioPolicyClientImpl.cpp
status_t AudioPolicyService::AudioPolicyClient::setVoiceVolume(float volume, int delay_ms)
{
return mAudioPolicyService->setVoiceVolume(volume, delay_ms);
}
AudioPolicyService.cpp
int AudioPolicyService::SetVoiceVolume(float volume, int delayms){
return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayms);
}
case SET_VOICE_VOLUME: {
VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
ALOGV("AudioCommandThread() processing set voice volume volume %f",
data->mVolume);
command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
}break;
转了一圈又回到audiosystem::setVoiceVolume()
status_t AudioSystem::setVoiceVolume(float value)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setVoiceVolume(value);
}
进入到audioflinger.cpp
详情见audiofinger的分析