android5.0 按键调节音量详解

按键事件派发已经分析过,调节音量流程直接从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);
}


AudioPolicyInterfaceImpl.cpp

status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
                                                  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的分析



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值