Android-HAL (二) 2 HIDL Passthrough 分析 Mapper

Passthrough - HAL通常是framework进程通过HIDL接口调用,运行在framework层

<transport>hwbinder</transport> 中标明是直通式还是绑定式

out/target/product/nx563j/vendor/etc/vintf/manifest.xml

XML 复制代码
<hal format="hidl">
    <name>android.hardware.graphics.mapper</name>
    <transport arch="32+64">passthrough</transport>
    <fqname>@2.1::IMapper/default</fqname>
</hal>

<hal format="hidl">
    <name>android.hardware.gnss</name>
    <transport>hwbinder</transport>
    <fqname>@1.0::IGnss/default</fqname>
</hal>

dequeueBuffer流程

frameworks/native/libs/gui/BufferQueueProducer.cpp

在dequeueBuffer的时候回构造GraphicBuffer对象

cpp 复制代码
status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,
                                            uint32_t width, uint32_t height, PixelFormat format,
                                            uint64_t usage, uint64_t* outBufferAge,
                                            FrameEventHistoryDelta* outTimestamps) {
//...

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE)
        std::vector<GraphicBufferAllocator::AdditionalOptions> tempOptions;
        tempOptions.reserve(allocOptions.size());
        for (const auto& it : allocOptions) {
            tempOptions.emplace_back(it.name.c_str(), it.value);
        }
        const GraphicBufferAllocator::AllocationRequest allocRequest = {
                .importBuffer = true,
                .width = width,
                .height = height,
                .format = format,
                .layerCount = BQ_LAYER_COUNT,
                .usage = usage,
                .requestorName = {mConsumerName.c_str(), mConsumerName.size()},
                .extras = std::move(tempOptions),
        };
        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(allocRequest);
#else
        sp<GraphicBuffer> graphicBuffer =
                new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage,
                                  {mConsumerName.c_str(), mConsumerName.size()});
#endif

//...
}

frameworks/native/libs/ui/GraphicBuffer.cpp

构造器会调用GraphicBufferMapper::get()

cpp 复制代码
GraphicBuffer::GraphicBuffer()
    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
{
    width  =
    height =
    stride =
    format =
    usage_deprecated = 0;
    usage  = 0;
    layerCount = 0;
    handle = nullptr;
}

native/libs/ui/include_vndk/ui/GraphicBufferMapper.h

cpp 复制代码
static inline GraphicBufferMapper& get() { return getInstance(); }

native/libs/ui/Gralloc2.cpp

调用了 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();

IMapper 这是一个hal接口

cpp 复制代码
Gralloc2Mapper::Gralloc2Mapper() {
    mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
    if (mMapper == nullptr) {
        ALOGW("mapper 2.x is not supported");
        return;
    }
    if (mMapper->isRemote()) {
        LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
    }

    // IMapper 2.1 is optional
    mMapperV2_1 = IMapper::castFrom(mMapper);
}

soong/.intermediates/hardware/interfaces/graphics/mapper/2.0/android.hardware.graphics.mapper@2.0_genc++/gen/android/hardware/graphics/mapper/2.0/MapperAll.cpp

cpp 复制代码
::android::sp<IMapper> IMapper::getService(const std::string &serviceName, const bool getStub) {
    return ::android::hardware::details::getServiceInternal<BpHwMapper>(serviceName, true, getStub);
}

system/libhidl/transport/include/hidl/HidlTransportSupport.h

cpp 复制代码
template <typename BpType, typename IType = typename BpType::Pure,
          typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
          typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
    using ::android::hidl::base::V1_0::IBase;

    sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);

//...

    return IType::castFrom(base);
}

libhidl/transport/ServiceManagement.cpp

这个getTransport就相当于从manifest中查询这个服务是什么模式的

cpp 复制代码
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
                                                             const std::string& instance,
                                                             bool retry, bool getStub) {
// ...
        sm = defaultServiceManager1_1();
//...

        Return<Transport> transportRet = sm->getTransport(descriptor, instance);

//...
        transport = transportRet;
    }

    const bool vintfHwbinder = (transport == Transport::HWBINDER);
    const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
    const bool trebleTestingOverride = isTrebleTestingOverride();
    const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && isDebuggable());
    const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;

//...
    
//绑定式代码
    ...
//直通式代码
    if (getStub || vintfPassthru || vintfLegacy) {
        const sp<IServiceManager1_0> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            if (!getStub || trebleTestingOverride) {
                base = wrapPassthrough(base);
            }
            return base;
        }
    }

    return nullptr;
}

sp<IServiceManager1_0> getPassthroughServiceManager() {
    return getPassthroughServiceManager1_1();
}

sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
    static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
    return manager;
}

sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);

sym 就是 HIDL_FETCH_IMapper 方法,dlopen 的形式调用

name 就是 default 就是 HIDL_FETCH_IMapper 方法的入参

cpp 复制代码
Return<sp<IBase>> get(const hidl_string& fqName,
                          const hidl_string& name) override {
        sp<IBase> ret = nullptr;
//...

        openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
            IBase* (*generator)(const char* name);
            *(void **)(&generator) = dlsym(handle, sym.c_str());
//...
            ret = (*generator)(name.c_str());
//...
        });

        return ret;
    }

openLibs

以android.hardware.graphics.mapper@2.0-impl-2.1.so为例

prefix 就是 android.hardware.graphics.mapper@2.0-impl

sym 就是 interfaces/graphics/mapper/2.1/default/passthrough.cpp

HIDL_FETCH_IMapper

最后通过 eachLib 返回回去

cpp 复制代码
static void openLibs(
        const std::string& fqName,
        const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
                                                 const std::string& /* sym */)>& eachLib) {
        //fqName looks like android.hardware.foo@1.0::IFoo
        size_t idx = fqName.find("::");

//... 拼凑名称

        const std::string prefix = packageAndVersion + "-impl";
        const std::string sym = "HIDL_FETCH_" + ifaceName;
//...
        for (const std::string& path : paths) {
            std::vector<std::string> libs = findFiles(path, prefix, ".so");

            for (const std::string &lib : libs) {
                const std::string fullPath = path + lib;

                if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
                    handle = dlopen(fullPath.c_str(), dlMode);
                } else {
#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
                    handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
                }
//...
                if (!eachLib(handle, lib, sym)) {
                    return;
                }
            }
        }
    }

findFiles 找一个以入参开头的文件 StartsWith

cpp 复制代码
static std::vector<std::string> findFiles(const std::string& path, const std::string& prefix,
                                          const std::string& suffix) {
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
    if (!dir) return {};

    std::vector<std::string> results{};

    dirent* dp;
    while ((dp = readdir(dir.get())) != nullptr) {
        std::string name = dp->d_name;

        if (base::StartsWith(name, prefix) && base::EndsWith(name, suffix)) {
            results.push_back(name);
        }
    }

    return results;
}

dlopen找到对应的库后调用代码

interfaces/graphics/mapper/2.1/default/passthrough.cpp

cpp 复制代码
extern "C" IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
    return GrallocLoader::load();
}

interfaces/graphics/mapper/2.1/utils/passthrough/include/mapper-passthrough/2.1/GrallocLoader.h

cpp 复制代码
static IMapper* load() {
    const hw_module_t* module = loadModule();
    if (!module) {
        return nullptr;
    }
    auto hal = createHal(module);
    if (!hal) {
        return nullptr;
    }
    return createMapper(std::move(hal));
}

interfaces/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h

cpp 复制代码
#define GRALLOC_HARDWARE_MODULE_ID "gralloc"

static const hw_module_t* loadModule() {
    const hw_module_t* module;
    int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    if (error) {
        ALOGE("failed to get gralloc module");
        return nullptr;
    }

    return module;
}

NX563J:/vendor/lib64/hw # ls | grep gralloc
gralloc.default.so
gralloc.msm8998.so
相关推荐
孙严Pay4 小时前
代付功能的跨界新玩法:不止于金融领域
笔记·科技·计算机网络·其他·微信
爱搜索人工智能6 小时前
2025年GEO优化实战评测:杭州爱搜索人工智能成口碑好的GEO优化厂家首选
其他
t057771 天前
德意志飞机公司D328eco项目2025年度回顾
其他
爱搜索人工智能2 天前
2025年GEO优化实践评测:杭州爱搜索人工智能引领供应链创新
其他
老陈头聊SEO3 天前
生成引擎优化(GEO)助力内容创作与用户体验协同提升的新方法
其他·搜索引擎·seo优化
渡我白衣3 天前
计算机组成原理(8):各种码的作用详解
c++·人工智能·深度学习·神经网络·其他·机器学习
DELOK ULTRASONIC4 天前
德诺超声波焊接机供应与维修服务全面解析
其他
爱搜索人工智能4 天前
2025年GEO优化源头供应链实践测评:爱搜索人工智能引领行业新标准
其他
t057774 天前
解锁城市骑行美学!VELO ANGEL TT坐垫适配自在漫游
其他