• (原)一句mpAudioPolicy->get_input引发的血案


    今天分析Android的Audio系统时,对mpAudioPolicy->get_input进行了分析,没想到这一句话的背后如此复杂,简直是一句话引出的血案啊!

    分析结果如下:(关于排版:各个变量的调用关系的图在博客里屏幕太窄了,可以复制到notepad++中看)

    调用mpAudioPolicy的get_input,它是mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy)中赋值的

    定义:struct audio_policy_device *mpAudioPolicyDev;

    定义:struct audio_policy *mpAudioPolicy;

    而audio_policy_dev_open(module, &mpAudioPolicyDev);中将赋值给mpAudioPolicyDev

    而audio_policy_dev_open定义如下

    static inline int audio_policy_dev_open(const hw_module_t* module,

                                        struct audio_policy_device** device)

    {

        return module->methods->open(module, AUDIO_POLICY_INTERFACE,

                                     (hw_device_t**)device);

    }

    看来得找model的来源了

                                          AudioPolicyInterface

                                                      |继

                                                      |承

                                          AudioPolicyManagerBase

                                                      |继

                                                      |承

                                         AudioPolicyManagerDefault编译成的audio_policy.default.so//hardware/libhardware_legacy/audio/AudioPolicyManagerDefault.cpp、

                                                      |    //AudioPolicyManagerDefault.h

                                                      |    //    而audio_policy.default.so又依赖于静态库libaudiopolicy_legacy.a(hardware/libhardware_legacy/audio/Android.mk

                                                      |    //中:LOCAL_WHOLE_STATIC_LIBRARIES := libaudiopolicy_legacy)

                                                      |    //    libaudiopolicy_legacy.a由 AudioPolicyManagerBase.cpp、AudioPolicyCompatClient.cpp、audio_policy_hal.cpp生成

                                                      |    //    HAL_MODULE_INFO_SYM在audio_policy_hal.cpp中定义,下面分析audio_policy_hal.cpp中的内容

                                                      |

                                                      |

                   hw_get_module_by_class(id, NULL, module)//id=AUDIO_POLICY_HARDWARE_MODULE_ID,hw_get_module_by_class即会加载audio_policy的HAL的SO,

                                                      |    //此从原生系统中找到了audio_policy.stub.so、audio_policy.default.so、audio_policy.msm8960.so

                                                      |    //    根据使用getprop命令查看模拟器的系统属性可知,模拟器中将会加载audio_policy.default.so,

                                                      |    //相关源码在hardware/libhardware_legacy/audio/目录下

                                                      |

                                                      |

    hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module)//#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy"; 而module的类型为hw_module_t

                                                      |

                                                      |

                            module->methods->open(module, AUDIO_POLICY_INTERFACE,(hw_device_t**)device)//audio_policy_dev_open函数中,将hw_device_t类型转换成了

                                                                                                   |//audio_policy_device返回给mpAudioPolicyDev

                                                                                                   |

                                                                                                   |

                                                                                                   |

                                                            audio_policy_dev_open(module, &mpAudioPolicyDev)

                                                                                                   |

                                                                                                   |

                                                                                          mpAudioPolicyDev->

                                                                                          create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy)

                                                                                                                                                     |

                                                                                                                                                     |

                                                                                                                                              mpAudioPolicy->get_input(...)

    看audio_policy_hal.cpp中的:

    static struct hw_module_methods_t legacy_ap_module_methods = {

            open: legacy_ap_dev_open

    };

    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,

                name: "LEGACY Audio Policy HAL",

                author: "The Android Open Source Project",

                methods: &legacy_ap_module_methods,

                dso : NULL,

                reserved : {0},

            },

        },

    };

    所以module->methods->open将调用到legacy_ap_dev_open函数

    而mpAudioPolicyDev最终将成为legacy_ap_dev_open函数的最后一个参数hw_device_t** device

    而由:

    dev->device.create_audio_policy = create_legacy_ap;

    *device = &dev->device.common;

    知mpAudioPolicy成为create_legacy_ap的最后一个参数struct audio_policy **ap

    而由:

    lap->policy.get_input = ap_get_input;

    *ap = &lap->policy;

    mpAudioPolicy->get_input(...)最终将变成调用ap_get_input

    所以:mpAudioPolicy->get_input将调用hardware/libhardware_legacy/audio/audio_policy_hal.cpp中的ap_get_input函数

    下面分析ap_get_input函数它的内容如下:

          struct legacy_audio_policy *lap = to_lap(pol);

          return lap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask,(AudioSystem::audio_in_acoustics)acoustics);

    而lap->apm由create_legacy_ap中如下语句创造

    lap->apm = createAudioPolicyManager(lap->service_client);

    所以此处的apm即new AudioPolicyManagerDefault(lap->service_client)对象,而lap->service_client = new AudioPolicyCompatClient(aps_ops, service);

    其中的参数是本cpp中调用create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy)中传入的aps_ops和this参数

    AudioPolicyManagerBase由定义知它完全等价于AudioPolicyManagerBase

    最终分析结论:mpAudioPolicy->get_input将最终调用hardware/libhardware_legacy/audio/AudioPolicyManagerBase.cpp中的getInput函数

    而在AudioPolicyManagerBase中调用AudioPolicyCompatClient的openInput,在openInput中会根据audio_policy.conf文件的配置信息决定使用什么音频设备,

    以此确定audio_module_handle_t的值,

    然后又在openInput中又将通过本cpp传入的aps_ops回调本cpp中的aps_open_input_on_module

    aps_open_input_on_module中调用AudioFlinger的openInput了

    AudioFlinger的openInput会产生一个唯一整数作为audio_io_handle_t

    AudioFlinger的openInput还会根据AudioPolicyManagerBase中选出的合适音频设备的audio_module_handle_t来在mAudioHwDevs中查找对应的设备的AudioHwDevice对象inHwDev

    找出inHwDev设备后,调用改设备的HAL中的open_input_stream,即audio_hw.c中的adev_open_input_stream

    在adev_open_input_stream中构造HAL层的自定义类型stream_in(如stub_stream_in),并在stream_in中植入自己定义的HAL层函数,然后把该stream_in返回AudioFlinger

    AudioFlinger使用HAL返回的stream_in以及前面找出的设备的AudioHwDevice构造AF中的AudioStreamIn类型对象input,然后创建一个新的RecordThread线程,

    并将该线程以前面传入的audio_io_handle_t做索引存入mRecordThreads中,返回audio_io_handle_t,即audio_io_handle_t是在AudioFlinger中找出对应线程的索引

  • 相关阅读:
    [linux驱动]设备驱动模型相关(二)——常用API
    [Linux驱动]字符设备驱动学习笔记(三)———高级
    Android 禁用Home键
    Android 使用QuickContactBadge关联联系人
    Android 使用SeekBar调节系统音量
    Android 完全退出应用程序
    Android 窗体显示状态
    Eclipse中常见问题
    解读人们对安卓系统的种种误解
    使用Bitmap加载图片出现OOM问题
  • 原文地址:https://www.cnblogs.com/albert1017/p/3837152.html
Copyright © 2020-2023  润新知