defaultPassthroughServiceImplementation在android新老版本的差异

发布于:2025-02-17 ⋅ 阅读:(139) ⋅ 点赞:(0)

背景:

近来有学员朋友在群里讨论到一个hal相关的知识点,就是看到有的程序注册自己服务时候使用如下方式:


int main() {
    return defaultPassthroughServiceImplementation<IGatekeeper>();
}

有学员朋友很可能就被它的名字误解了,以为这个就是直通式,这块比较疑惑,同时

这个注册服务方式以前安卓8.1老版本的其实还比较常见,新版本安卓没有再使用这种方式都是使用如下方式

int main() {
    ::android::hardware::configureRpcThreadpool(1, true /* willJoinThreadpool */);
    android::sp<SoftGateKeeperDevice> gatekeeper(new SoftGateKeeperDevice());
    auto status = gatekeeper->registerAsService();
    if (status != android::OK) {
        LOG(FATAL) << "Could not register service for Gatekeeper 1.0 (software) (" << status << ")";
    }

    android::hardware::joinRpcThreadpool();
    return -1;  // Should never get here.
}

下面来正式分析一下老版本为啥可以用defaultPassthroughServiceImplementation进行注册服务

源码分析

android-8.1.0_r1/system/libhidl/transport/include/hidl/LegacySupport.h

template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
        std::string name = "default") {
        //这里会构造出对象,注意这里的参数getStub为true
    sp<Interface> service = Interface::getService(name, true /* getStub */);

   //上面构造完成后也会调用registerAsService进行注册
    status_t status = service->registerAsService(name);


    return status;
}

实际上defaultPassthroughServiceImplementation本质也是构造出对象然后注册服务,注册相对好理解,重点分析一下对象获取。
但是这里看到对应的构造Interface::getService,可以看出这个Interface其实是依赖我们传递模板,这个getService其实实现是hidl工具编译自动生成的。
./1.0/android.hardware.gatekeeper@1.0_genc++/gen/android/hardware/gatekeeper/1.0/GatekeeperAll.cpp


// static
::android::sp<IGatekeeper> IGatekeeper::getService(const std::string &serviceName, const bool getStub) {
   

    //getStub为true不会进入下面,虽然vintfHwbinder为true也没用
    for (int tries = 0; !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)); tries++) {
      
        return iface;
    }
    //getStub为true会进入下面
    if (getStub || vintfPassthru || vintfLegacy) {
        const sp<::android::hidl::manager::V1_0::IServiceManager> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            Return<sp<::android::hidl::base::V1_0::IBase>> ret = 
                    pm->get(IGatekeeper::descriptor, serviceName);
            if (ret.isOk()) {
                sp<::android::hidl::base::V1_0::IBase> baseInterface = ret;
                if (baseInterface != nullptr) {
                    iface = IGatekeeper::castFrom(baseInterface);
                    if (!getStub || trebleTestingOverride) {
                        iface = new BsGatekeeper(iface);
                    }
                }
            }
        }
    }
    return iface;
}

这里的getPassthroughServiceManager
system\libhidl\transport\ServiceManagement.cpp

sp<IServiceManager1_0> getPassthroughServiceManager() {
    return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
    static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
    return manager;
}
struct PassthroughServiceManager : IServiceManager1_1 {
   
    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());
            if(!generator) {
                const char* error = dlerror();
                LOG(ERROR) << "Passthrough lookup opened " << lib
                           << " but could not find symbol " << sym << ": "
                           << (error == nullptr ? "unknown error" : error);
                dlclose(handle);
                return true;
            }

            ret = (*generator)(name.c_str());

            if (ret == nullptr) {
                dlclose(handle);
                return true; // this module doesn't provide this instance name
            }

            registerReference(fqName, name);
            return false;
        });

        return ret;
    }

这里最后调用到如下:
hardware/interfaces/gatekeeper/1.0/default/Gatekeeper.cpp

IGatekeeper* HIDL_FETCH_IGatekeeper(const char* /* name */) {
    return new Gatekeeper();
}

高版本安卓不直接使用defaultPassthroughServiceImplementation原因调查

主要通过调查发现
具体提交如下:

commit 4fc43b48e598cf3da7254bddb49d855de61db75e
Author: Mikhail Naganov <mnaganov@google.com>
Date:   Wed Jan 29 15:36:57 2020 -0800

    transport: Add non-template functions for service registration
    
    Add an implementation of registerPassthroughServiceImplementation
    which takes interface name as string instead of using a template.
    This allows services to avoid dependency on interface libraries.
    
    Bug: 148115870
    Test: verify that updated audio HAL service works
    Change-Id: I1ef9d9f830e4ff217c5b24bb5b4919af05d7cfa6

这里面说明了目的就是为了减少相关的对接口库相关的强依赖,想直接通过名字这种方式进行注册,实现松耦合

更多framework实战干货,请关注下面“千里马学框架”


网站公告

今日签到

点亮在社区的每一天
去签到