这次的分析是从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<IAudioFlinger>& 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<hw_module_t*>(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;  |