Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

Android系统架构
Android是怎么启动的
Android 10.0系统启动之init进程
Android10.0系统启动之Zygote进程
Android 10.0 系统启动之SystemServer进程
Android 10.0 系统服务之ActivityMnagerService
Android10.0系统启动之Launcher(桌面)启动流程
Android10.0应用进程创建过程以及Zygote的fork流程
Android 10.0 PackageManagerService(一)工作原理及启动流程
Android 10.0 PackageManagerService(二)权限扫描
Android 10.0 PackageManagerService(三)APK扫描
Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》

Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​
《Binder通信原理》:

Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
Android10.0 Binder通信原理(二)-Binder入门篇
Android10.0 Binder通信原理(三)-ServiceManager篇
Android10.0 Binder通信原理(四)-Native-C\C++实例分析
Android10.0 Binder通信原理(五)-Binder驱动分析
Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
Android10.0 Binder通信原理(七)-Framework binder示例
Android10.0 Binder通信原理(八)-Framework层分析
Android10.0 Binder通信原理(九)-AIDL Binder示例
Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
Android10.0 Binder通信原理(十一)-Binder总结

《HwBinder通信原理》

HwBinder入门篇-Android10.0 HwBinder通信原理(一)
 HIDL详解-Android10.0 HwBinder通信原理(二)
HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
HwServiceManager篇-Android10.0 HwBinder通信原理(五)
Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
《编译原理》

编译系统入门篇-Android10.0编译系统(一)
编译环境初始化-Android10.0编译系统(二)
make编译过程-Android10.0编译系统(三)
Image打包流程-Android10.0编译系统(四
Kati详解-Android10.0编译系统(五)
Blueprint简介-Android10.0编译系统(六)
Blueprint代码详细分析-Android10.0编译系统(七)
Android.bp 语法浅析-Android10.0编译系统(八)
Ninja简介-Android10.0编译系统(九)
Ninja提升编译速度的方法-Android10.0编译系统(十)
Android10.0编译系统(十一)

上一节,我们学习了Native层 HIDL服务的注册原理,这一节我们来看看Native层HIDL服务的获取流程。

 

5.IDemo的服务获取
   IDemo的HIDL服务获取流程如下图所示:

 

 

5.1调用栈如下

5.2 main

[\vendor\ingres\hal_demo\cpp\hal_demo_test.cpp]
int main() {
   //1.获取IDemo这个HIDL服务的代理对象
    android::sp<IDemo> service = IDemo::getService();
 
    if(service == nullptr) {
        printf("Failed to get service\n");
        return -1;
    }
   //2.调用服务的HIDL接口 getHelloString()
    service->getHelloString("IngresGe", [&](hidl_string result) {
                printf("%s\n", result.c_str());
        });
 
    return 0;
}

主要分两步:

1.获取IDemo这个HIDL服务的代理对象

2.调用服务的HIDL接口 getHelloString()

 

5.3 getService()

[/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp]
::android::sp<IDemo> IDemo::getService(const std::string &serviceName, const bool getStub) {
    return ::android::hardware::details::getServiceInternal<BpHwDemo>(serviceName, true, getStub);
}

getService的调用栈如下:

根据上面的调用栈,最终进入getRawServiceInternal()

[/system/libhidl/transport/ServiceManagement.cpp]
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
                                                             const std::string& instance,
                                                             bool retry, bool getStub) {
    using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
    using ::android::hidl::manager::V1_0::IServiceManager;
    sp<Waiter> waiter;
 
    sp<IServiceManager1_1> sm;
    Transport transport = Transport::EMPTY;
    if (kIsRecovery) {
        transport = Transport::PASSTHROUGH;
    } else {
            //拿到HwServiceManager的对象,参考[5.4]
        sm = defaultServiceManager1_1();
        if (sm == nullptr) {
            ALOGE("getService: defaultServiceManager() is null");
            return nullptr;
        }
            //获取IDemo服务的transport,确认是直通式PASSTHROUGH,还是绑定式:HWBINDER
            //transport可以在/vendor/etc/vintf/manifest.xml中查看<transport>hwbinder</transport>
        Return<Transport> transportRet = sm->getTransport(descriptor, instance);
 
        if (!transportRet.isOk()) {
            ALOGE("getService: defaultServiceManager()->getTransport returns %s",
                  transportRet.description().c_str());
            return nullptr;
        }
        transport = transportRet;
    }
 
    const bool vintfHwbinder = (transport == Transport::HWBINDER); //绑定式服务
    const bool vintfPassthru = (transport == Transport::PASSTHROUGH); //直通式服务
        ...
 
    for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
        if (waiter == nullptr && tries > 0) {
            waiter = new Waiter(descriptor, instance, sm);
        }
        if (waiter != nullptr) {
            waiter->reset();  // don't reorder this -- see comments on reset()
        }
            //如果是绑定式的服务,调用 BpHwServiceManager::get()
        Return<sp<IBase>> ret = sm->get(descriptor, instance);
        if (!ret.isOk()) {
            ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
                  ret.description().c_str(), descriptor.c_str(), instance.c_str());
            break;
        }
        sp<IBase> base = ret;
        if (base != nullptr) {
            Return<bool> canCastRet =
                details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
 
            if (canCastRet.isOk() && canCastRet) {
                if (waiter != nullptr) {
                    waiter->done();
                }
                return base; // still needs to be wrapped by Bp class.
            }
 
            if (!handleCastError(canCastRet, descriptor, instance)) break;
        }
 
        // In case of legacy or we were not asked to retry, don't.
        if (vintfLegacy || !retry) break;
 
        if (waiter != nullptr) {
            ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
            waiter->wait(true /* timeout */);
        }
    }
 
    if (waiter != nullptr) {
        waiter->done();
    }
 
    if (getStub || vintfPassthru || vintfLegacy) {
            //如果是直通式的hidl服务,获取直通式的HwServiceManager对象来获取服务
        const sp<IServiceManager> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            if (!getStub || trebleTestingOverride) {
                base = wrapPassthrough(base);
            }
            return base;
        }
    }
    return nullptr;
}

getRawServiceInternal()步骤如下:

1.获取HwServiceManager的代理对象

2.获取IDemo 这个hidl服务的transport,来确认是绑定式服务,还是直通式服务

3.根据transport类型,调用不同的接口来获取服务对象 (我们设计的IDemo是绑定式hidl服务)

 

5.4 defaultServiceManager1_1

[/system/libhidl/transport/ServiceManagement.cpp]
sp<IServiceManager1_1> defaultServiceManager1_1() {
    return defaultServiceManager1_2();
}
 
[/system/libhidl/transport/ServiceManagement.cpp]
defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager
sp<IServiceManager1_2> defaultServiceManager1_2() {
    using android::hidl::manager::V1_2::BnHwServiceManager;
    using android::hidl::manager::V1_2::BpHwServiceManager;
 
    static std::mutex gDefaultServiceManagerLock;
    static sp<IServiceManager1_2> gDefaultServiceManager;
 
    {
        std::lock_guard<std::mutex> _l(gDefaultServiceManagerLock);
        if (gDefaultServiceManager != nullptr) {
            return gDefaultServiceManager;
        }
        //1.检查hwbinder的节点是否存在,如果不存在说明不支持hwbinder
        if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
            // HwBinder not available on this device or not accessible to
            // this process.
            return nullptr;
        }
        //2.等待属性"hwservicemanager.ready" 变为true,表明hwservicemanager已经启动好
        waitForHwServiceManager();
 
        while (gDefaultServiceManager == nullptr) {
            //3.拿到HwServiceManager的代理对象
            gDefaultServiceManager =
                fromBinder<IServiceManager1_2, BpHwServiceManager, BnHwServiceManager>(
                    ProcessState::self()->getContextObject(nullptr));
            if (gDefaultServiceManager == nullptr) {
                LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
                sleep(1);
            }
        }
    }
    return gDefaultServiceManager;
}

5.4.1 BpHwBinder::transact()

[/system/libhwbinder/BpHwBinder.cpp]
status_t BpHwBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback /*callback*/)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        //拿到IPCThreadState的对象,调用transact()执行
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }
 
    return DEAD_OBJECT;
}

BpBinder::transact()就是调用IPCThreadState::self()->transact() 进行处理

根据如下调用栈所示,BpHwBinder::transact()最终会转到BnHwServiceManager::_hidl_get(),实现流程和注册服务类似,相关源码分析参考上一节《Native层HIDL服务的注册原理》的[4.7.1] - [4.8]

 

5.5 BnHwServiceManager::_hidl_get()

[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp]
::android::status_t BnHwServiceManager::_hidl_get(
        ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
        const ::android::hardware::Parcel &_hidl_data,
        ::android::hardware::Parcel *_hidl_reply,
        TransactCallback _hidl_cb) {
 
        ...
    ::android::status_t _hidl_err = ::android::OK;
    if (!_hidl_data.enforceInterface(BnHwServiceManager::Pure::descriptor)) {
        _hidl_err = ::android::BAD_TYPE;
        return _hidl_err;
    }
 
    const ::android::hardware::hidl_string* fqName;
    const ::android::hardware::hidl_string* name;
 
    size_t _hidl_fqName_parent;
 
        //1.获取hidl服务的fqName
    _hidl_err = _hidl_data.readBuffer(sizeof(*fqName), &_hidl_fqName_parent,  reinterpret_cast<const void **>(&fqName));
 
    if (_hidl_err != ::android::OK) { return _hidl_err; }
 
    _hidl_err = ::android::hardware::readEmbeddedFromParcel(
            const_cast<::android::hardware::hidl_string &>(*fqName),
            _hidl_data,
            _hidl_fqName_parent,
            0 /* parentOffset */);
 
    if (_hidl_err != ::android::OK) { return _hidl_err; }
 
    size_t _hidl_name_parent;
 
        //2.获取hidl服务的name
    _hidl_err = _hidl_data.readBuffer(sizeof(*name), &_hidl_name_parent,  reinterpret_cast<const void **>(&name));
 
    if (_hidl_err != ::android::OK) { return _hidl_err; }
 
    _hidl_err = ::android::hardware::readEmbeddedFromParcel(
            const_cast<::android::hardware::hidl_string &>(*name),
            _hidl_data,
            _hidl_name_parent,
            0 /* parentOffset */);
 
    if (_hidl_err != ::android::OK) { return _hidl_err; }
 
    atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::get::server");
        ...
        //3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象
    ::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service = static_cast<IServiceManager*>(_hidl_this->getImpl().get())->get(*fqName, *name);
 
        //4.把reply信息写入Parcel
    ::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
 
    if (_hidl_out_service == nullptr) {
        _hidl_err = _hidl_reply->writeStrongBinder(nullptr);
    } else {
            //5.把获取的hidl服务转成IBinder对象
        ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::getOrCreateCachedBinder(_hidl_out_service.get());
        if (_hidl_binder.get() != nullptr) {
                  //6.把转换后的IBinder对象,写入reply的Parcel数据中
            _hidl_err = _hidl_reply->writeStrongBinder(_hidl_binder);
        } else {
            _hidl_err = ::android::UNKNOWN_ERROR;
        }
    }
    /* _hidl_err ignored! */
 
    atrace_end(ATRACE_TAG_HAL);
         ..
     //7.通过回调,把reply的Parcel数据给发给client
    _hidl_cb(*_hidl_reply);
    return _hidl_err;
}

_hidl_get流程如下:

       1.获取hidl服务的fqName

       2.获取hidl服务的name

       3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象

       4.把reply信息写入Parcel

       5.把获取的hidl服务转成IBinder对象

       6.把转换后的IBinder对象,写入reply的Parcel数据中

       7.通过回调,把reply的Parcel数据给发给client

 

5.5.1 ServiceManager::get()
 

[/system/hwservicemanager/ServiceManager.cpp]
Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
                                      const hidl_string& hidlName) {
    const std::string fqName = hidlFqName;
    const std::string name = hidlName;
 
    if (!mAcl.canGet(fqName, getBinderCallingContext())) {
        return nullptr;
    }
 
        //1.根据fqName和name找到对应的hidlService
    HidlService* hidlService = lookup(fqName, name);
    if (hidlService == nullptr) {
        tryStartService(fqName, name);
        return nullptr;
    }
 
    //2.根据hidlService 拿到IBase的对象
    sp<IBase> service = hidlService->getService();
    if (service == nullptr) {
        tryStartService(fqName, name);
        return nullptr;
    }
 
    hidlService->guaranteeClient();
 
    hardware::addPostCommandTask([hidlService] {
        hidlService->handleClientCallbacks(false /* isCalledOnInterval */);
    });
    return service;
}

5.7.3 ServiceManager::lookup()

  主要是根据fqName和name从 HwServiceManager的服务map:mServiceMap 中找到对应的hidlservice。

[/system/hwservicemanager/ServiceManager.cpp]
HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) {
        //1.根据fqName从 mServiceMap 中 找到一个节点
    auto ifaceIt = mServiceMap.find(fqName);
    if (ifaceIt == mServiceMap.end()) {
        return nullptr;
    }
        //2.从找到的map节点中,拿到PackageInterfaceMap的内容
    PackageInterfaceMap &ifaceMap = ifaceIt->second;
        //3.从PackageInterfaceMap中根据name找到hidlService
    HidlService *hidlService = ifaceMap.lookup(name);
    return hidlService;
}

5.5.2 HidlService::getService()

获取HidlService对象的mService

[/system/hwservicemanager/HidlService.cpp]
sp<IBase> HidlService::getService() const {
    return mService;
}

6. 协议码的转换流程

  Binder通信协议是基于Command-Reply的方式的。

7.IDemo Client\Server交互流程
  在IDemo的服务注册和获取的过程中,IDemo的服务和Client都是作为Client端,HwServiceManager作为Server端。

  在IDemo的服务和client调用过程中,IDemo的服务为Server端,Client为客户端。

 

8.代码路径

/system/libhwbinder/BpHwBinder.cpp
/system/libhwbinder/IPCThreadState.cpp
/system/libhidl/transport/ServiceManagement.cpp
/system/libhidl/transport/include/hidl/HidlTransportSupport.h
/vendor/ingres/hal_demo/cpp/hal_demo_test.cpp
/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp
/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp

9. 总结

  至此,Native层的HIDL服务注册和获取就梳理完了,主要就是进程和HwBinder驱动、HwServiceManager的交互流程,下一节我们再一起看看JAVA层的hidl服务注册和获取流程。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值