hal interface

 IDeviceFactory openDevice得到IDevice, IDevice openInput/outputStream得到IStream

 android.hardware.audio.service

存在形式

hardware/interfaces/audio/common/all-versions/default/service/android.hardware.audio.service.rc
service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service
    class hal
    user audioserver


hardware/interfaces/audio/common/all-versions/default/service/Android.bp
cc_binary {
    name: "android.hardware.audio.service",
    init_rc: ["android.hardware.audio.service.rc"],
    vendor: true,
    srcs: ["service.cpp"],
}

在同一个进程启动了多个service

int main(int /* argc */, char* /* argv */ []) {
    ::android::ProcessState::initWithDriver("/dev/vndbinder");
    // start a threadpool for vndbinder interactions
    ::android::ProcessState::self()->startThreadPool();
    const std::vector<InterfacesList> mandatoryInterfaces = {
        {
            "Audio Core API",
            "android.hardware.audio@6.0::IDevicesFactory",
            "android.hardware.audio@5.0::IDevicesFactory",
            "android.hardware.audio@4.0::IDevicesFactory",
            "android.hardware.audio@2.0::IDevicesFactory"
        },
        {
            "Audio Effect API",
            "android.hardware.audio.effect@6.0::IEffectsFactory",
            "android.hardware.audio.effect@5.0::IEffectsFactory",
            "android.hardware.audio.effect@4.0::IEffectsFactory",
            "android.hardware.audio.effect@2.0::IEffectsFactory",
        }
    };

    const std::vector<InterfacesList> optionalInterfaces = {
        {
            "Soundtrigger API",
            "android.hardware.soundtrigger@2.3::ISoundTriggerHw",
            "android.hardware.soundtrigger@2.2::ISoundTriggerHw",
            "android.hardware.soundtrigger@2.1::ISoundTriggerHw",
            "android.hardware.soundtrigger@2.0::ISoundTriggerHw",
        },
        {
            "Bluetooth Audio API",
            "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory"
        },
        // remove the old HIDL when Bluetooth Audio Hal V2 has offloading supported
        {
            "Bluetooth Audio Offload API",
            "android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioOffload"
        }
    };

    for (const auto& listIter : mandatoryInterfaces) {
        auto iter = listIter.begin();
        const std::string& interfaceFamilyName = *iter++;
        LOG_ALWAYS_FATAL_IF(!registerPassthroughServiceImplementations(iter, listIter.end()),
                            "Could not register %s", interfaceFamilyName.c_str());
    }

    for (const auto& listIter : optionalInterfaces) {
        auto iter = listIter.begin();
        const std::string& interfaceFamilyName = *iter++;
        ALOGW_IF(!registerPassthroughServiceImplementations(iter, listIter.end()),
                 "Could not register %s", interfaceFamilyName.c_str());
    }

    joinRpcThreadpool();
}
以上就是audiohalservice的启动过程,主要是通过registerPassthroughServiceImplementation注册了一组接口,关于halbinder可参考,registerPassthroughServiceImplementation函数调用HIDL_FETCH_IDevicesFactory,生成了DevicesFactory

https://www.programminghunter.com/article/7441427492/
https://blog.csdn.net/u013928208/article/month/2018/07

registerPassthroughServiceImplementation的实现

HIDL_FETCH_IDevicesFactory是怎样别调到的?
registerPassthroughServiceImplementation的实现
system/libhidl/transport/LegacySupport.cpp

registerPassthroughServiceImplementation -> 
getRawServiceInternal -> 
getPassthroughServiceManager ->
(system/libhidl/transport/ServiceManagement.cpp)
IServiceManager1_1::openLibs {
        const std::string prefix = packageAndVersion + "-impl"; //要加载的库 xxx-impl.so
        const std::string sym = "HIDL_FETCH_" + ifaceName; // 调用库导出的接口函数
}

hardware/interfaces/audio/effect/all-versions/default/Android.bp
cc_library_shared {
    name: "android.hardware.audio.effect@6.0-impl",
    defaults: ["android.hardware.audio.effect-impl_default"],
    shared_libs: [
        "android.hardware.audio.common@6.0",
        "android.hardware.audio.common@6.0-util",
        "android.hardware.audio.effect@6.0",
    ],
}

hardware/interfaces/audio/core/all-versions/default/DevicesFactory.cpp
IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) {
    return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr;
}

DevicesFactoryHalHybrid::openDevice 的实现

status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
        strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
        return mHidlFactory->openDevice(name, device);
    }
    return mLocalFactory->openDevice(name, device);
}

/** HAL service 要加载的hal 具体实现库的命名规则
 * List of known audio HAL modules. This is the base name of the audio HAL
 * library composed of the "audio." prefix, one of the base names below and
 * a suffix specific to the device.
 * e.g: audio.primary.goldfish.so or audio.a2dp.default.so
 *
 * The same module names are used in audio policy configuration files.
 */
#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary"
#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp"
#define AUDIO_HARDWARE_MODULE_ID_USB "usb"
#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix"
#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload"
#define AUDIO_HARDWARE_MODULE_ID_STUB "stub"
#define AUDIO_HARDWARE_MODULE_ID_HEARING_AID "hearing_aid"
#define AUDIO_HARDWARE_MODULE_ID_MSD "msd"

mHidlFactory->openDevice(name, device)的实现

通过binderDeviceFactory得到了Device: DeviceHalInterface
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    auto factories = copyDeviceFactories();
    if (factories.empty()) return NO_INIT;
    status_t status;
    auto hidlId = idFromHal(name, &status);
    if (status != OK) return status;
    Result retval = Result::NOT_INITIALIZED;
    for (const auto& factory : factories) {
        Return<void> ret = factory->openDevice(
                hidlId,
                [&](Result r, const sp<IDevice>& result) {

               // IDeviceFactory::openDevice返回的是IDevice: result
                    retval = r;
                    if (retval == Result::OK) {
                        //调用new DeviceHalHidl(IDevice)
                        *device = new DeviceHalHidl(result);
                    }
                });
    }
    ALOGW("The specified device name is not recognized: \"%s\"", name);
    return BAD_VALUE;
}

DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
        : ConversionHelperHidl("Device"), mDevice(device),
          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
}

hal service端的openDevice

hardware/interfaces/audio/core/all-versions/default/DevicesFactory.cpp
template <class DeviceShim, class Callback>
Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
    audio_hw_device_t* halDevice;

    sp<DeviceShim> result;
    int halStatus = loadAudioInterface(moduleName, &halDevice);
    if (halStatus == OK) {
        result = new DeviceShim(halDevice);
        retval = Result::OK;
    }

    _hidl_cb(retval, result); //这里是个callback 和上面的client callback 实现对应上
    return Void();
}

hardware device的框架

hw_module_t/ hw_device_t由这两个数据结构组成


int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) {
    const hw_module_t* mod;
    int rc;

    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID("audio"), if_name, &mod);

    rc = audio_hw_device_open(mod, dev);

    return OK;
}

hal service的框架大概分为两部分:

1. hw_get_module_by_class 根据输入参数找到并加载 xxx.so

2. xxx(class)_hw_device_open 得到(打开)一个device 并把device返回给client


hw_get_module_by_class

hardware/libhardware/hardware.c

hw_get_module_by_class的实现分为两部分:1. 找到module  2. 加载module

int hw_get_module_by_class(const char *class_id, const char *inst,
                           const struct hw_module_t **module)
{
    snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
    property_get(xxx);
    hw_module_exists(); // 根据路径信息找到module
    // path: /vendor/lib64/hw/audio.primary.xxx.so
    /* load the module */
    return load(class_id, path, module);
}

static int load(const char *id,
        const char *path,
        const struct hw_module_t **pHmi)
{
    int status = -EINVAL;
    void *handle = NULL;
    struct hw_module_t *hmi = NULL;
    handle = dlopen(path, RTLD_NOW);
    /* Get the address of the struct hal_module_info. */
    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;(HMI)
    hmi = (struct hw_module_t *)dlsym(handle, sym);

    // 通过这里可以得到一个技巧:通过搜索class_id找到对应的hal实现

   // 如搜索AUDIO_HARDWARE_MODULE_ID
    if (strcmp(id, hmi->id) != 0) {
        ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
        status = -EINVAL;
    }

    hmi->dso = handle;

    *pHmi = hmi;

    return status;
}

/vendor/lib64/hw/audio.primary.xxx.so具体实现

 

vendor/qcom/opensource/audio-hal/primary-hal/hal/Android.mk
LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_RELATIVE_PATH := hw

struct audio_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = AUDIO_HARDWARE_MODULE_ID,
        .name = "QCOM Audio HAL",
        .author = "The Linux Foundation",
        .methods = &hal_module_methods,
    },
};

static struct hw_module_methods_t hal_module_methods = {
    .open = adev_open,
};
 

audio_hw_device_open

 

static inline int audio_hw_device_open(const struct hw_module_t* module,
                                       struct audio_hw_device** device)
{
    return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
                                 TO_HW_DEVICE_T_OPEN(device));
}

struct audio_hw_device {
    struct hw_device_t common;
    
   // 一组函数指针:这些接口封装了所有对 audio_hw_device的操作
   open_output_stream等
}

static int adev_open(const hw_module_t *module, const char *name,
                     hw_device_t **device)
{
  // ---
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐