1. 程式人生 > >android5.0 按鍵調節音量詳解

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的分析