这次的分析是从setting设置开始,进入声音设置,然后进入音量设置!

先上传上来,后期进行整理吧

 

调用流程:
--------------------------------------------------------------------------------------------------------
                       Setting应用
    ... ...                      
 RingerVolumePreference(DialogPreference).onClick()
    →RingerVolumePreference(DialogPreference).showDialog(Bundle)
     →RingerVolumePreference.onBindDialogView(View)
      →RingerVolumePreference.updateSlidersAndMutedStates()
          →mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
       →mAudioManager.getStreamVolume(streamType);
          |  
-------------------------|------------------------------------------------------------------------------      
       |                                                         AudioManager
     getStreamVolume
        |→IAudioService service = getService();
        |→service.getStreamVolume(streamType);
         |
---------------------------|-----------------------------------------------------------------------------
         |                        AudioService.java               AudioService(JAVA层)
      getStreamVolume
       ensureValidStreamType(streamType);
       (mStreamStates[streamType].mLastAudibleIndex + 5) / 10;
             |
      VolumeStreamState
         |①从setting provider中读取上次保存的音量值
         |→mLastAudibleIndex = Settings.System.getInt(cr,
                           |                            mLastAudibleVolumeIndexSettingName,
                           | (mIndex > 0) ? mIndex : AudioManager.DEFAULT_STREAM_VOLUME[streamType]);
         |②初始化native层的音量值
         |→AudioSystem.initStreamVolume(streamType, 0, mIndexMax);
         |③设置native层的音量值
         |→setStreamVolumeIndex(streamType, mIndex);
                  |
       AudioSystem.setStreamVolumeIndex(stream, (index + 5)/10);
       
       
   initStreamVolume                   setStreamVolumeIndex    
       |                                                      |
------------------JNI----------------------------------------------------JNI-------------------------------
       |                        |              JNI层
android_media_AudioSystem_initStreamVolume     android_media_AudioSystem_setStreamVolumeIndex
       |                        |
       |  check_AudioSystem_Command                  |
       |                        |
-------------------|---------------------------------------------------------------------------------------     
       |                        |  AudioPolicyService客户端
       |               |
 AudioSystem::initStreamVolume                          AudioSystem::setStreamVolumeIndex
       |                        |
       | aps = AudioSystem::get_audio_policy_service();    |
       |               |
aps->initStreamVolume(stream, indexMin, indexMax);   aps->setStreamVolumeIndex(stream, index);
       |               |
remote()->transact(INIT_STREAM_VOLUME, data, &reply);  remote()->transact(SET_STREAM_VOLUME, data, &reply);
       |               |
-------------------|-------------------binder通信-------------------------|---------------------------------
       |               |  AudioPolicyService服务端
       |               |
AudioPolicyService::initStreamVolume       AudioPolicyService::setStreamVolumeIndex
       |               |
mpAudioPolicy->init_stream_volum     mpAudioPolicy->set_stream_volume_index  
       |               |
-------------------|------------------------------------------------------|------------------------------------------
       |               |      Audio policy HAL 硬件抽象层
                    |
               ap_set_stream_volume_index
                    |
            lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,index);
                    |
            AudioPolicyManagerBase::setStreamVolumeIndex
                    |
            checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
                    |
             AudioPolicyManagerBase::checkAndSetVolume
                    |
             mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
                    |
             AudioPolicyCompatClient::setStreamVolume
                    |
           mServiceOps->set_stream_volume(mService, (audio_stream_type_t)stream,volume, output, delayMs);
                    |
                aps_set_stream_volume    AudioPolicyService.cpp
                    |
            audioPolicyService->setStreamVolume(stream, volume, output,delay_ms);
                    |
            mAudioCommandThread->volumeCommand((int)stream, volume,(int)output, delayMs);
                    |
            AudioPolicyService::AudioCommandThread::volumeCommand
                    |
               insertCommand_l(command, delayMs);
  
  至此,我们需要去分析执行command的后台线程,会如何执行这些命令的。               
               
----------------------------------------AudioPolicyService::AudioCommandThread::threadLoop-----------------------------------------------------

bool AudioPolicyService::AudioCommandThread::threadLoop()
{
    nsecs_t waitTime = INT64_MAX;

    mLock.lock();
    while (!exitPending())
    {
        while(!mAudioCommands.isEmpty()) {
    ... ...
                switch (command->mCommand) {
    ... ...
                case SET_VOLUME: {
                    VolumeData *data = (VolumeData *)command->mParam;
                    LOGV("AudioCommandThread() processing set volume stream %d, \
                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
                                                            |        data->mVolume,
                                                            |        data->mIO);
                    if (command->mWaitStatus) {    |
                        command->mCond.signal();   |
                        mWaitWorkCV.wait(mLock);   |
                    }          |
                    delete data;       |
                    }break;         |
    ... ...          |
}               |
               |
           AudioSystem::setStreamVolume
               |
               |
               |→const sp& af = AudioSystem::get_audio_flinger();
               |→af->setStreamVolume(stream, value, output);
               |
               |
------------------------------------------------------------|--------------------------------------------------------------------
               |        AudioFlinger
            AudioFlinger::setStreamVolume              
               |
           thread->setStreamVolume(stream, value); 
               |
       AudioFlinger::PlaybackThread::setStreamVolume
               |
           mStreamTypes[stream].volume = value;         至此音量设置完毕   
               
              
 接下来分析下上面遗留的Init相关的流程:
     AudioPolicyService::initStreamVolume 
           |
       
 
----------------------现在有必要搞清楚mpAudioPolicy到底是怎么来的----------------------------------------------------

AudioPolicyService是Android音频系统的两大服务之一,另一个服务是AudioFlinger,这两大服务都在系统启动时由MediaSever加载,
加载的代码位于:frameworks/base/media/mediaserver/main_mediaserver.cpp。AudioFlinger主要负责管理音频数据处理以及和硬件
抽象层相关的工作。下面研究下AudioPolicyService。    
AudioPolicyService主要完成以下任务:
    JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务
    输入输出设备的连接状态
    系统的音频策略(strategy)的切换
    音量/音频参数的设置

AudioPolicyService有一个内部线程类AudioCommandThread,顾名思义,所有的命令(音量控制,输入、输出的切换等)最终都会在该线程中排队执行;
AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音频策略(strategy)管理,输入输出设备管理。 

我们现在比较关心的是音量的控制,所以我们还是到AudioCommandThread线程中了解一下。
AudioCommandThread线程是在AudioPolicyService的构造函数中创建的。
AudioPolicyService::AudioPolicyService()
 →mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));

AudioCommandThread线程的主要工作是在bool AudioPolicyService::AudioCommandThread::threadLoop()中完成的。
threadLoop中主要处理音频设置相关的命令:
 ▲START_TONE/STOP_TONE:播放电话系统中常用的特殊音调,例如:TONE_DTMF_0,TONE_SUP_BUSY等等。
 ▲SET_VOLUME:最终会调用AudioFlinger进行音量设置
 ▲SET_PARAMETERS:最终会调用AudioFlinger进行电话音量设置
 ▲SET_VOICE_VOLUME:通过一个KeyValuePairs形式的字符串进行参数设置
 
我们比较关心"音量设置"相关,所以只关注SET_VOLUME.
    case SET_VOLUME: {
        VolumeData *data = (VolumeData *)command->mParam;
            command->mStatus = AudioSystem::setStreamVolume(data->mStream,data->mVolume,data->mIO); 
---------------------------------------------------------------------------------------------------------------------------------------------
下面研究一下AudioPolicyManager:   
AudioPolicyManager是在AudioPolicyService的构造函数中创建的。
AudioPolicyService::AudioPolicyService
 |→hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
 |(获得AudioPolicyHardwareModule,根据模块ID找到硬件模块动态链接库的地址,然后调用load去打开动态链接库并从中获取硬件模块结构体地址。)
 |struct legacy_ap_module HAL_MODULE_INFO_SYM = {
    |module: {
    |    common: {
    |        tag: HARDWARE_MODULE_TAG,
    |        version_major: 1,
    |        version_minor: 0,
    |        id: AUDIO_POLICY_HARDWARE_MODULE_ID, //ID
    |        name: "LEGACY Audio Policy HAL",
    |        author: "The Android Open Source Project",
    |        methods: &legacy_ap_module_methods,
    |        dso : NULL,
    |        reserved : {0},
    |    },
    |},
    |};
 |
 |→audio_policy_dev_open(module, &mpAudioPolicyDev); //打开 audio policy device
 |→mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy);
 | |static int legacy_ap_dev_open(const hw_module_t* module, const char* name,
    |   |                             hw_device_t** device)
 | |{
    | | struct legacy_ap_device *dev;
 | |
    | | if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
    |   |   return -EINVAL;
 | |
    | | dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));
    | | if (!dev)
    |   |   return -ENOMEM;
 | |
    | | dev->device.common.tag = HARDWARE_DEVICE_TAG;
    | | dev->device.common.version = 0;
    | | dev->device.common.module = const_cast(module);
    | | dev->device.common.close = legacy_ap_dev_close;
    | | dev->device.create_audio_policy = create_legacy_ap;//create_audio_policy对应的操作函数。
    | | dev->device.destroy_audio_policy = destroy_legacy_ap;
 | |
    | | *device = &dev->device.common;
 | |
    | | return 0;
 | |}
 | |
 | |→create_legacy_ap
 |  |→lap->policy.init_check = ap_init_check;
 |  |→lap->policy.init_stream_volume = ap_init_stream_volume;
 |  |→lap->policy.set_stream_volume_index = ap_set_stream_volume_index;
 |  |→... ...
 |  |→ap->apm = createAudioPolicyManager(lap->service_client);//创建AudioPolicyManager
 |     |→new AudioPolicyManagerDefault(clientInterface);
 |        |→AudioPolicyManagerBase::AudioPolicyManagerBase
 |         |→mpClientInterface = clientInterface;


 |

 

更多相关文章

  1. android 手机铃声获取
  2. Android左右声道音频文件测试
  3. android音频波形图绘制
  4. Android的postOnAnimation分析
  5. android 手机虚拟按键 震动过程的追溯(1)
  6. Android(安卓)之 远程图片获取和本地缓存
  7. Android(Java):音量调节
  8. android 音量调节时,嘟 的 发声位置
  9. Android(安卓)浅析 EventBus (一) 使用

随机推荐

  1. Android(安卓)源码分析之旅3.4--onConfig
  2. Android(安卓)自定义底部导航栏和动态添
  3. android 显示消息框的方法
  4. 一文全面了解Android单元测试
  5. 传智播客成都java培训中心andriod实训班
  6. Android辅助功能
  7. Android(安卓)中进程、Activity、Boradca
  8. 【专家专栏】Android中的防缓冲区溢出技
  9. Android(安卓)动态设置TextView的drawabl
  10. 如何修改Android5.1系统音量大小