Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
摘要:本节主要来讲解Android10.0 Native层HIDL服务的注册原理
阅读本文大约需要花费23分钟。
文章首发微信公众号:IngresGe
专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!
欢迎关注我的公众号!
[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编译系统(五)
1.概述
在上一节中,我们知道了HwServiceManager的启动过程,注册、获取服务的细节处理。服务的信息都存在于一个mServiceMap的map容器中。
mServiceMap对应的key为package interface 名称,例如"android.hidl.manager@1.0::IServiceManager", 对应的value为一个PackageInterfaceMap结构体,其中包含了lookup()、insertService()等方法,
service的对象最终被插入到 InstanceMap 这个map容器中。
前面我们已经写了一个HIDL实例,来展示了Native层的服务注册和获取调用流程,但是Native层的服务注册、获取流程是如何实现的,现在还不清楚。
这一节,我们深度分析Native层的HAL服务的注册和获取。
2. Native层的HwBinder架构
3. 重要类分析
在真正看代码前,需要先了解两个类-ProcessState和IPCThreadState 这两个很重要类的概念。
3.1 ProcessState
ProcessState从字面意思可以理解,表示是“进程状态”,代表了这个进程的行为,Android中,每个进程都是独立的,所以每个进程都要有一个“进程状态”--ProcessState.
在Binder通信机制中,ProcessState使用了单例模式,即一个进程只有个ProcessState对象,一个进程中有很多个线程,不能每个线程都来new一个新的ProcessState(),采用单例模式后,每个线程都可以使用同一个ProcessState来和Binder驱动通信。
ProcessState作为进程状态的记录器,主要用来打开Binder驱动获取句柄,mmap申请一块(1M-8K)的内存空间,设置Binder线程最大个数。
3.2 IPCThreadState
IPCThreadState从字面意思可以理解,表示是“进程间通信的线程状态”,有了进程状态后,自然需要有线程状态。
ProcessState代表了进程,IPCThreadState代表了线程。Android系统中有很多进程,进程间相互隔离,每个进程内部又有很多线程,线程之间也是相互独立的。所以说一个进程会存在很多个线程,每个线程都有自己的“线程状态”--IPCThreadState对象.这个对象存储在线程的本地存储区(TLS:Thread local storage)中,每个线程都拥有自己的TLS,并且是私有空间,线程之间不会共享。
IPCThreadState对象根据key:gTLS去进行存储。通过pthread_getspecific/pthread_setspecific函数可以获取/设置这些空间中的内容。
IPCThreadState负责与Binder驱动进行数据交互。
3.3 BpHwBinder
BpHwBinder 展开后就是Binder Proxy,也就是Binder代理的含义。BpHwBinder 是客户端用来与服务交互的代理类,负责实现跨进程传输的传输机制,不关心具体的传输内容。通信功能由其它类和函数实现,但由于这些类和函数被BpHwBinder代理,所以客户端需要通过BpHwBinder来发送Binder通信数据。
3.4 BHwBinder
BHwBinder代表服务端,可以理解为服务的Binder实体,当服务端从Binder驱动中读取到数据后,由BHwBinder类进行处理。
4. IDemo的服务注册
IDemo的HIDL服务注册流程如下图所示:
4.1 调用栈如下
4.2 main()
[\vendor\ingres\interfaces\demo\1.0\default\Service.cpp]
int main() {configureRpcThreadpool(4, true); //和"dev/hwbinder" 进行通信,设置最大的线程个数为4Demo demo;auto status = demo.registerAsService(); //注册服务,参考[4.3]CHECK_EQ(status, android::OK) << "Failed to register demo HAL implementation";joinRpcThreadpool(); //把当前线程加入到线程池return 0;
}
IDemo的服务注册流程分为以下几步:
1.获得ProcessState实例对象,与"/dev/hwbinder"进行通信,设置最大的线程个数为4
2.获取Demo服务对象
3.调用registerAsService注册IDemo服务
4.把当前线程加入到线程池
服务注册,主要的入口就是 registerAsService(),下面我们从registerAsService()进一步分析
4.3 registerAsService()
开始HIDL服务注册,DemoAll.cpp 在编译的时候生成,源对象为IDemo.hal
[\out\soong\.intermediates\vendor\ingres\interfaces\demo\1.0\vendor.ingres.demo@1.0_genc++\gen\vendor\ingres\demo\1.0\DemoAll.cpp]
DemoAll.cpp 在编译的时候生成,源对象为IDemo.hal
__attribute__ ((warn_unused_result))::android::status_t registerAsService(const std::string &serviceName="default");::android::status_t IDemo::registerAsService(const std::string &serviceName) {//默认的serviceName是default,参考[4.4]return ::android::hardware::details::registerAsServiceInternal(this, serviceName);
}
4.4 registerAsServiceInternal()
[/system/libhidl/transport/ServiceManagement.cpp]
status_t registerAsServiceInternal(const sp<IBase>& service, const std::string& name) {if (service == nullptr) {return UNEXPECTED_NULL;}//1.获取HwServiceManager代理对象:BpHwServiceManager,fromBinder最终为 new BpHwServiceManager(new BpHwBinder(0))//参考[4.5]sp<IServiceManager1_2> sm = defaultServiceManager1_2();if (sm == nullptr) {return INVALID_OPERATION;}bool registered = false;Return<void> ret = service->interfaceChain([&](const auto& chain) {//2.通过HwServiceManager代理对象BpHwServiceManager进行服务的注册//参考[4.6]registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false); });if (!ret.isOk()) {LOG(ERROR) << "Could not retrieve interface chain: " << ret.description();}if (registered) {onRegistrationImpl(getDescriptor(service.get()), name);}return registered ? OK : UNKNOWN_ERROR;
}
核心步骤:
1.拿到HwServiceManager的代理对象 BpHwServiceManager
2.通过该代理对象,进行HAL服务的注册
4.5sp<IServiceManager1_2> defaultServiceManager1_2()
defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager
[/system/libhidl/transport/ServiceManagement.cpp]
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的节点是否存在,如果不存在说明不支持hwbinderif (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;
}
4.5.1 ProcessState::getContextObject
[/system/libhwbinder/ProcessState.cpp]
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{return getStrongProxyForHandle(0); //传入handle = 0, HwServiceManager的handle就为0
}
获取一个BpHwBinder的对象,即当Service向HwServiceManager进行注册时,Service变成了Client,HwServiceManager变成了Server,需要先把Service 转换成一个BpHwBinder对象,作为Binder代理进行通信
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{sp<IBinder> result;AutoMutex _l(mLock);handle_entry* e = lookupHandleLocked(handle);if (e != nullptr) {IBinder* b = e->binder;//handle = 0传入的binder在lookupHandleLocked()中赋值为nullptrif (b == nullptr || !e->refs->attemptIncWeak(this)) {b = new BpHwBinder(handle); //binder对象为new BpHwBinder(0)e->binder = b;if (b) e->refs = b->getWeakRefs();result = b;} else {result.force_set(b);e->refs->decWeak(this);}}return result;
}
4.5.2 fromBinder()
根据BpHwBinder 这个远程对象,拿到HwServiceManager的对象,这里是远程对象,所以返回一个BpHwServiceManager 对象。
BpHwBinder负责数据传输,而BpHwServiceManager服务数据业务,业务数据在BpHwServiceManager层打包好后,转交给BpHwBinder发送。
[/system/libhidl/transport/ServiceManagement.cpp]
template <typename IType, typename ProxyType, typename StubType>
sp<IType> fromBinder(const sp<IBinder>& binderIface) {using ::android::hidl::base::V1_0::IBase;using ::android::hidl::base::V1_0::BnHwBase;if (binderIface.get() == nullptr) {return nullptr;}//这里传入的binderIface 其中的Binder对象为 new BpHwBinder(0),这是一个remote的Binder,这里的ProxyType是BpHwServiceManager 所以返回一个new BpHwServiceManager()if (binderIface->localBinder() == nullptr) {return new ProxyType(binderIface);}sp<IBase> base = static_cast<BnHwBase*>(binderIface.get())->getImpl();if (details::canCastInterface(base.get(), IType::descriptor)) {StubType* stub = static_cast<StubType*>(binderIface.get());return stub->getImpl();} else {return nullptr;}
}
BpHwServiceManager的类继承关系如下图所示:
4.6 BpHwServiceManager::addWithChain()
[\out\soong\.intermediates\system\libhidl\transport\manager\1.2\android.hidl.manager@1.2_genc++\gen\android\hidl\manager\1.2\ServiceManagerAll.cpp]
::android::hardware::Return<bool> BpHwServiceManager::addWithChain(const ::android::hardware::hidl_string& name, const ::android::sp<::android::hidl::base::V1_0::IBase>& service, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& chain){::android::hardware::Return<bool> _hidl_out = ::android::hidl::manager::V1_2::BpHwServiceManager::_hidl_addWithChain(this, this, name, service, chain); //调用_hidl_addWithChain()进行执行return _hidl_out;
}
_hidl_addWithChain的主要步骤如下:
1.准备两个Parcel结构-- _hidl_data,_hidl_reply
2.组装Parcel数据
3.写入RPC头信息"android.hidl.manager@1.2::IServiceManager"
4.写入服务名称,如果没有配置的话,name为"default"
5.写入服务的实体对象--new Demo()
6.调用remote的transact,发送 12 /* addWithChain */ 的命令进行服务的注册
7.得到返回的reply数据
::android::hardware::Return<bool> BpHwServiceManager::_hidl_addWithChain(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_string& name, const ::android::sp<::android::hidl::base::V1_0::IBase>& service, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& chain) {#ifdef __ANDROID_DEBUGGABLE__bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();#else(void) _hidl_this_instrumentor;#endif // __ANDROID_DEBUGGABLE__::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, "HIDL::IServiceManager::addWithChain::client");#ifdef __ANDROID_DEBUGGABLE__if (UNLIKELY(mEnableInstrumentation)) {std::vector<void *> _hidl_args;_hidl_args.push_back((void *)&name);_hidl_args.push_back((void *)&service);_hidl_args.push_back((void *)&chain);for (const auto &callback: mInstrumentationCallbacks) {callback(InstrumentationEvent::CLIENT_API_ENTRY, "android.hidl.manager", "1.2", "IServiceManager", "addWithChain", &_hidl_args);}}#endif // __ANDROID_DEBUGGABLE__::android::hardware::Parcel _hidl_data; //定义一个Parcel的data数据包::android::hardware::Parcel _hidl_reply; //定义一个Parcel的reply数据包::android::status_t _hidl_err;::android::hardware::Status _hidl_status;bool _hidl_out_success;//1.写入RPC头信息"android.hidl.manager@1.2::IServiceManager"_hidl_err = _hidl_data.writeInterfaceToken(BpHwServiceManager::descriptor);if (_hidl_err != ::android::OK) { goto _hidl_error; }size_t _hidl_name_parent;//2.写入服务名称,如果没有配置的话,name为"default"_hidl_err = _hidl_data.writeBuffer(&name, sizeof(name), &_hidl_name_parent);if (_hidl_err != ::android::OK) { goto _hidl_error; }_hidl_err = ::android::hardware::writeEmbeddedToParcel(name,&_hidl_data,_hidl_name_parent,0 /* parentOffset */);if (_hidl_err != ::android::OK) { goto _hidl_error; }if (service == nullptr) {_hidl_err = _hidl_data.writeStrongBinder(nullptr);} else {//3.根据传入的service,获取对应的hidl binder实体,把一个binder实体“打扁”并写入parcel,实体为 new Demo()::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::getOrCreateCachedBinder(service.get());if (_hidl_binder.get() != nullptr) {_hidl_err = _hidl_data.writeStrongBinder(_hidl_binder);} else {_hidl_err = ::android::UNKNOWN_ERROR;}}if (_hidl_err != ::android::OK) { goto _hidl_error; }size_t _hidl_chain_parent;_hidl_err = _hidl_data.writeBuffer(&chain, sizeof(chain), &_hidl_chain_parent);if (_hidl_err != ::android::OK) { goto _hidl_error; }size_t _hidl_chain_child;_hidl_err = ::android::hardware::writeEmbeddedToParcel(chain,&_hidl_data,_hidl_chain_parent,0 /* parentOffset */, &_hidl_chain_child);if (_hidl_err != ::android::OK) { goto _hidl_error; }for (size_t _hidl_index_0 = 0; _hidl_index_0 < chain.size(); ++_hidl_index_0) {_hidl_err = ::android::hardware::writeEmbeddedToParcel(chain[_hidl_index_0],&_hidl_data,_hidl_chain_child,_hidl_index_0 * sizeof(::android::hardware::hidl_string));if (_hidl_err != ::android::OK) { goto _hidl_error; }}//4.启动一个线程池::android::hardware::ProcessState::self()->startThreadPool();//5.调用BpHwBinder::transact(),asBinder转换过程,参考下图//_hidl_this 指的是 BpHwServiceManager,通过asBinder转换为传输层面的BpHwBinder对象,其实就是取出BpHwServiceManager的成员变量mRemote的值_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(12 /* addWithChain */, _hidl_data, &_hidl_reply);if (_hidl_err != ::android::OK) { goto _hidl_error; }//6.从_hidl_reply读取返回结果_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);if (_hidl_err != ::android::OK) { goto _hidl_error; }if (!_hidl_status.isOk()) { return _hidl_status; }_hidl_err = _hidl_reply.readBool(&_hidl_out_success);if (_hidl_err != ::android::OK) { goto _hidl_error; }#ifdef __ANDROID_DEBUGGABLE__if (UNLIKELY(mEnableInstrumentation)) {std::vector<void *> _hidl_args;_hidl_args.push_back((void *)&_hidl_out_success);for (const auto &callback: mInstrumentationCallbacks) {callback(InstrumentationEvent::CLIENT_API_EXIT, "android.hidl.manager", "1.2", "IServiceManager", "addWithChain", &_hidl_args);}}#endif // __ANDROID_DEBUGGABLE___hidl_status.setFromStatusT(_hidl_err);return ::android::hardware::Return<bool>(_hidl_out_success);_hidl_error:_hidl_status.setFromStatusT(_hidl_err);return ::android::hardware::Return<bool>(_hidl_status);
}
asBinder的转换后,得到的对象是BpHwBinder,asBinder转换如下图所示:
4.7 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() 进行处理
4.7.1 IPCThreadState::transact()
[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::transact(int32_t handle,uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
{status_t err;flags |= TF_ACCEPT_FDS;...//1.传输数据, 参考[4.7.2]err = writeTransactionData(BC_TRANSACTION_SG, flags, handle, code, data, nullptr);if (err != NO_ERROR) {if (reply) reply->setError(err);return (mLastError = err);}if ((flags & TF_ONE_WAY) == 0) {if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {ALOGE("Process making non-oneway call but is restricted.");CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),ANDROID_LOG_ERROR);} else /* FATAL_IF_NOT_ONEWAY */ {LOG_ALWAYS_FATAL("Process may not make oneway calls.");}}...//2.等待响应if (reply) {err = waitForResponse(reply);} else {Parcel fakeReply;err = waitForResponse(&fakeReply);}...} else {//3.oneway,则不需要等待reply的场景err = waitForResponse(nullptr, nullptr);}return err;
}
IPCThreadState::transact()主要做了下面几步:
1. writeTransactionData() 组装一个 binder_transaction_data_sg 结构的数据,存入mOut中,mOut是一个Parcel的数据结构,处理的时候,前4个字节存入BC_XX 请求码,这里是BC_TRANSACTION,后面存入sizeof(binder_transaction_data_sg)长度的数据
2. waitForResponse() 和hwbinder进行通信,传送内容,等待响应
4.7.2 IPCThreadState::writeTransactionData()
[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{binder_transaction_data_sg tr_sg;/* Don't pass uninitialized stack data to a remote process */tr_sg.transaction_data.target.ptr = 0;tr_sg.transaction_data.target.handle = handle;tr_sg.transaction_data.code = code;tr_sg.transaction_data.flags = binderFlags;tr_sg.transaction_data.cookie = 0;tr_sg.transaction_data.sender_pid = 0;tr_sg.transaction_data.sender_euid = 0;const status_t err = data.errorCheck();if (err == NO_ERROR) {//把Parcel的数据转换到binder_transaction_data中tr_sg.transaction_data.data_size = data.ipcDataSize();// 这部分是待传递数据tr_sg.transaction_data.data.ptr.buffer = data.ipcData();// 这部分是扁平化的binder对象在数据中的具体位置tr_sg.transaction_data.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);tr_sg.transaction_data.data.ptr.offsets = data.ipcObjects();tr_sg.buffers_size = data.ipcBufferSize();} else if (statusBuffer) {tr_sg.transaction_data.flags |= TF_STATUS_CODE;*statusBuffer = err;tr_sg.transaction_data.data_size = sizeof(status_t);tr_sg.transaction_data.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);tr_sg.transaction_data.offsets_size = 0;tr_sg.transaction_data.data.ptr.offsets = 0;tr_sg.buffers_size = 0;} else {return (mLastError = err);}//把组装好的binder_transaction_data_sg 写入mOutmOut.writeInt32(cmd);mOut.write(&tr_sg, sizeof(tr_sg));return NO_ERROR;
}
writeTransactionData() 主要就是把传入的Parcel数据,转换成
binder_transaction_data_sg,写入mOut,用来与Binder驱动交互。其中
tr_sg.transaction_data.data.ptr.buffer 记录了Parcel传输的数据,
tr_sg.transaction_data.data.ptr.offsets "待传数据"中记录所有binder对象的具体位置。
4.7.3 IPCThreadState::waitForResponse()
waitForResponse()里面是一个while(1)循环,可以处理多个命令,只有进入goto finish后,循环才退出。如果返回的cmd不在switch的case中,进入default,调用executeCommand()来单独执行这些cmd.
[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{uint32_t cmd;int32_t err;while (1) {//1.和hwbinder进行通信,把上面writeTransactionData()组装的mOut发给hwbinder,参考[4.7.4]if ((err=talkWithDriver()) < NO_ERROR) break;...//2.读取hwbinder返回回来的cmd值cmd = (uint32_t)mIn.readInt32();...switch (cmd) {case BR_TRANSACTION_COMPLETE:if (!reply && !acquireResult) goto finish;break;case BR_DEAD_REPLY:...goto finish;case BR_FAILED_REPLY:...goto finish;case BR_ACQUIRE_RESULT:...goto finish;case BR_REPLY:...goto finish;default://3.执行cmd,参考[4.7.5]err = executeCommand(cmd);if (err != NO_ERROR) goto finish;break;}}finish:if (err != NO_ERROR) {if (acquireResult) *acquireResult = err;if (reply) reply->setError(err);mLastError = err;}return err;
}
4.7.4 IPCThreadState::talkWithDriver()
talkWithDriver()用来不停的和Binder驱动进行通信,ioctl()函数在传递BINDER_WRITE_READ语义时,既会使用“输入buffer”,也会使用“输出buffer”,所以IPCThreadState专门搞了两个Parcel类型的成员变量:mIn和mOut。mOut中的内容发出去,发送后的reply写进mIn。
BINDER_WRITE_READ的命令发给Binder驱动后,HwServiceManager的epoll_wait()一直在等待事务处理,HwServiceManager从mRequests中取出原先注册的handleEvent处理,例如HwBinderCallback::handleEvent,HwServiceManager和hwbinder进行通信,取出BR_TRANSACTION的内容,最后调用到BnHwServiceManager::onTransact进行解析,根据之前传入的code=12,走入_hidl_addWithChain进行服务注册,接着把服务端的name和对象,插入到mServiceMap表中,最终把reply的数据发送出去,client在talkWithDriver()中填入mIn中,waitForResponse()进行最终的语义处理,发送出去。
[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::talkWithDriver(bool doReceive)
{if (mProcess->mDriverFD <= 0) {return -EBADF;}binder_write_read bwr;// Is the read buffer empty?const bool needRead = mIn.dataPosition() >= mIn.dataSize();//如果仍在读取输入缓冲区中剩余的数据,并且调用方已请求读取下一个数据,则不希望写入任何内容。const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;bwr.write_size = outAvail;//1.把mOut的数据存入 write_buffer中bwr.write_buffer = (uintptr_t)mOut.data(); // This is what we'll read.if (doReceive && needRead) {//接收数据缓冲区信息的填充。如果以后收到数据,就直接填在mIn中了bwr.read_size = mIn.dataCapacity();bwr.read_buffer = (uintptr_t)mIn.data();} else {//没有收到数据时,把read置空,hwbinder只进行write处理bwr.read_size = 0;bwr.read_buffer = 0;}...//当读缓冲和写缓冲都为空,则直接返回if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;bwr.write_consumed = 0;bwr.read_consumed = 0;status_t err;do {...
#if defined(__ANDROID__)//2.通过ioctl不停的读写操作,跟Binder Driver进行通信if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)err = NO_ERROR;elseerr = -errno;
#elseerr = INVALID_OPERATION;
#endifif (mProcess->mDriverFD <= 0) {err = -EBADF;}...} while (err == -EINTR); //当被中断,则继续执行...if (err >= NO_ERROR) {if (bwr.write_consumed > 0) {if (bwr.write_consumed < mOut.dataSize())mOut.remove(0, bwr.write_consumed);else {mOut.setDataSize(0);processPostWriteDerefs();}}if (bwr.read_consumed > 0) {mIn.setDataSize(bwr.read_consumed);mIn.setDataPosition(0);}...return NO_ERROR;}return err;
}
4.7.5 IPCThreadState::executeCommand()
waitForResponse()收到BR_TRANSACTION响应码后,调用BHwBinder的transact()进行处理。
[/system/libhwbinder/IPCThreadState.cpp]
status_t IPCThreadState::executeCommand(int32_t cmd)
{...switch ((uint32_t)cmd) {...case BR_TRANSACTION:{...if (tr.target.ptr) {// 服务管理器不会走这个分支,camera、audio服务提供者才会走这个分支if (reinterpret_cast<RefBase::weakref_type*>(tr.target.ptr)->attemptIncStrong(this)) {error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags, reply_callback);reinterpret_cast<BHwBinder*>(tr.cookie)->decStrong(this);} else {error = UNKNOWN_TRANSACTION;}} else {//mContextObject 就是我们前面设置的 BnHwServiceManager,BnHwServiceManager没有transact,因此调用其父类BHwBinder的transact(),参考[4.7.6]error = mContextObject->transact(tr.code, buffer, &reply, tr.flags, reply_callback);}...}break;...}...return result;
}
4.7.6 BHwBinder::transact()
[/system/libhwbinder/Binder.cpp]
status_t BHwBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
{data.setDataPosition(0);status_t err = NO_ERROR;switch (code) {default://调用onTransact()进行code处理err = onTransact(code, data, reply, flags,[&](auto &replyParcel) {replyParcel.setDataPosition(0);if (callback != nullptr) {callback(replyParcel);}});break;}return err;
}
BHwBinder->transact() 中最重要的就是onTransact(),BHwBinder本身的onTransact()没有任何实现内容, binder实体在本质上都是继承于BHwBinder的,而且我们一般都会重载onTransact()函数,所以上面这句onTransact()实际上调用的是具体binder实体的onTransact()成员函数,所以最终调用的是BnHwServiceManager::onTransact()。
BnHwServiceManager的继承关系如下图所示:
4.8 BnHwServiceManager::onTransact()
onTransact()中,根据传入的hidl_code,调用相应的接口执行,从[4.6]可知,注册服务时,传入的hidl_code为12,因此会调用_hidl_addWithChain进行操作。
[/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::onTransact(uint32_t _hidl_code,const ::android::hardware::Parcel &_hidl_data,::android::hardware::Parcel *_hidl_reply,uint32_t _hidl_flags,TransactCallback _hidl_cb) {::android::status_t _hidl_err = ::android::OK;switch (_hidl_code) {case 1 /* get */:{bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;if (_hidl_is_oneway != false) {return ::android::UNKNOWN_ERROR;}_hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_get(this, _hidl_data, _hidl_reply, _hidl_cb);break;}case 2 /* add */:{bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;if (_hidl_is_oneway != false) {return ::android::UNKNOWN_ERROR;}_hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_add(this, _hidl_data, _hidl_reply, _hidl_cb);break;}...case 4 /* list */:{bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;if (_hidl_is_oneway != false) {return ::android::UNKNOWN_ERROR;}_hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_list(this, _hidl_data, _hidl_reply, _hidl_cb);break;}...case 12 /* addWithChain */:{bool _hidl_is_oneway = _hidl_flags & 1u /* oneway */;if (_hidl_is_oneway != false) {return ::android::UNKNOWN_ERROR;}//参考[4.9]_hidl_err = ::android::hidl::manager::V1_2::BnHwServiceManager::_hidl_addWithChain(this, _hidl_data, _hidl_reply, _hidl_cb);break;}...}...return _hidl_err;
}
4.9 BnHwServiceManager::_hidl_addWithChain()
_hidl_addWithChain()主要步骤如下:
1.读取注册的Service Name
2. 读取注册的hidl_binder
3.通过hidl_binder,转换得到,注册时的服务实体
4.读取传入的chain数据
5.调用ServiceManager::addWithChain(),进行服务注册
6.向_hidl_reply中写入OK
7.把服务注册的结构,写入_hidl_reply
8.返回replay数据
[/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_addWithChain(::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* name;::android::sp<::android::hidl::base::V1_0::IBase> service;const ::android::hardware::hidl_vec<::android::hardware::hidl_string>* chain;size_t _hidl_name_parent;//1.读取注册的Service 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; }{//2. 读取注册的hidl_binder::android::sp<::android::hardware::IBinder> _hidl_binder;_hidl_err = _hidl_data.readNullableStrongBinder(&_hidl_binder);if (_hidl_err != ::android::OK) { return _hidl_err; }//3.通过hidl_binder,转换得到,注册时的服务实体service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_binder);}size_t _hidl_chain_parent;//4.读取传入的chain数据_hidl_err = _hidl_data.readBuffer(sizeof(*chain), &_hidl_chain_parent, reinterpret_cast<const void **>(&chain));if (_hidl_err != ::android::OK) { return _hidl_err; }size_t _hidl_chain_child;_hidl_err = ::android::hardware::readEmbeddedFromParcel(const_cast<::android::hardware::hidl_vec<::android::hardware::hidl_string> &>(*chain),_hidl_data,_hidl_chain_parent,0 /* parentOffset */, &_hidl_chain_child);if (_hidl_err != ::android::OK) { return _hidl_err; }for (size_t _hidl_index_0 = 0; _hidl_index_0 < chain->size(); ++_hidl_index_0) {_hidl_err = ::android::hardware::readEmbeddedFromParcel(const_cast<::android::hardware::hidl_string &>((*chain)[_hidl_index_0]),_hidl_data,_hidl_chain_child,_hidl_index_0 * sizeof(::android::hardware::hidl_string));if (_hidl_err != ::android::OK) { return _hidl_err; }}atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::addWithChain::server");...//5.调用ServiceManager::addWithChain(),进行服务注册,参考[4.9.1]bool _hidl_out_success = static_cast<IServiceManager*>(_hidl_this->getImpl().get())->addWithChain(*name, service, *chain);//6.向_hidl_reply中写入OK::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);//7.把服务注册的结构,写入_hidl_reply_hidl_err = _hidl_reply->writeBool(_hidl_out_success);/* _hidl_err ignored! */atrace_end(ATRACE_TAG_HAL);...//8.返回replay数据_hidl_cb(*_hidl_reply);return _hidl_err;
}
4.9.1 ServiceManager::addWithChain()
[/system/hwservicemanager/ServiceManager.cpp]
Return<bool> ServiceManager::addWithChain(const hidl_string& name,const sp<IBase>& service,const hidl_vec<hidl_string>& chain) {if (service == nullptr) {return false;}//1.获取 CallingContext的的sid\pid信息auto callingContext = getBinderCallingContext();//2.调用addImpl进行注册return addImpl(name, service, chain, callingContext);
}
4.9.2 ServiceManager::addImpl()
获取当前binder调用的pid、sid 上下文信息后,开始注册服务,即把Demo对象注册到mServiceMap中。
在过程中,要进行selinux检查,确认该进程有权限添加service后,再检查是否有重复注册,而且如果子类在父类上注册,则注销它,
排除一切问题后,把需要注册的服务,注册到mServiceMap中,最后建立一个死亡连接,当服务挂掉时会接收到通知,做一些清理工作。
[/system/hwservicemanager/ServiceManager.cpp]
bool ServiceManager::addImpl(const std::string& name,const sp<IBase>& service,const hidl_vec<hidl_string>& interfaceChain,const AccessControl::CallingContext& callingContext) {//传入的interfaceChain size大于0if (interfaceChain.size() == 0) {LOG(WARNING) << "Empty interface chain for " << name;return false;}//1.首先,检查是否有权限来否允许add()整个接口层次结构,最终调用的是selinux_check_access来检查,是否有 hwservice_manager的权限for(size_t i = 0; i < interfaceChain.size(); i++) {const std::string fqName = interfaceChain[i];if (!mAcl.canAdd(fqName, callingContext)) {return false;}}// 2.检查是否有重复注册if (interfaceChain.size() > 1) {// 倒数第二的条目应该是除IBase之外的最高基类。const std::string baseFqName = interfaceChain[interfaceChain.size() - 2];const HidlService *hidlService = lookup(baseFqName, name);if (hidlService != nullptr && hidlService->getService() != nullptr) {// This shouldn't occur during normal operation. Here are some cases where// it might get hit:// - bad configuration (service installed on device multiple times)// - race between death notification and a new service being registered// (previous logs should indicate a separate problem)const std::string childFqName = interfaceChain[0];pid_t newServicePid = IPCThreadState::self()->getCallingPid();pid_t oldServicePid = hidlService->getDebugPid();LOG(WARNING) << "Detected instance of " << childFqName << " (pid: " << newServicePid<< ") registering over instance of or with base of " << baseFqName << " (pid: "<< oldServicePid << ").";}}// 3.如果子类在父类上注册,则注销它{// For IBar extends IFoo if IFoo/default is being registered, remove// IBar/default. This makes sure the following two things are equivalent// 1). IBar::castFrom(IFoo::getService(X))// 2). IBar::getService(X)// assuming that IBar is declared in the device manifest and there// is also not an IBaz extends IFoo and there is no race.const std::string childFqName = interfaceChain[0];const HidlService *hidlService = lookup(childFqName, name);if (hidlService != nullptr) {const sp<IBase> remove = hidlService->getService();if (remove != nullptr) {const std::string instanceName = name;removeService(remove, &instanceName /* restrictToInstanceName */);}}}// 4.排除问题后,把需要注册的服务,注册到mServiceMap中for(size_t i = 0; i < interfaceChain.size(); i++) {const std::string fqName = interfaceChain[i];PackageInterfaceMap &ifaceMap = mServiceMap[fqName];HidlService *hidlService = ifaceMap.lookup(name);if (hidlService == nullptr) {//服务插入 mServiceMap,以后从这取出服务,参考 [4.9.3]ifaceMap.insertService(std::make_unique<HidlService>(fqName, name, service, callingContext.pid));} else {hidlService->setService(service, callingContext.pid);}ifaceMap.sendPackageRegistrationNotification(fqName, name);}//建立一个死亡连接,当服务挂掉时会接收到通知,做一些清理工作bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);if (!linkRet) {LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;}return true;
}
4.9.3 ServiceManager::insertService()
把传入的hidlservice插入到mInstanceMap 中,即 mServiceMap的value--PackageInterfaceMap 中。
[/system/hwservicemanager/ServiceManager.cpp]
void ServiceManager::PackageInterfaceMap::insertService(std::unique_ptr<HidlService> &&service) {mInstanceMap.insert({service->getInstanceName(), std::move(service)});
}
mServiceMap的结构如下图所示:
至此,我们的IDemo服务注册完成,注册步骤分为以下几个步骤:
1.服务进程先获得一个 ProcessState()的对象
2.获取HwServiceManager的代理对象HwBpServiceManager,主要通过new BpHwBinder(0)得到。
3.调用HwBpServiceManager的addWithChain,组装一个Parce数据,传入服务名称、服务实体对象--BHwBinder、执行12 /* addWithChain */
4.先通过IPCThreadThread的writeTransactionData()把上面的Parcel数据写入mOut,用来进行发送
5.通过IPCThreadThread的talkWithDriver()与HwBinder驱动通信,传递语义BINDER_WRITE_READ
6.HwServiceManager有个for循环,调用epoll_wait()监控hwbinder的变化
7.waitForResponse()收到BR_TRANSACTION响应码后,最终后调用executeCommand()进行命令执行,根据逻辑处理,最终会调用到BnHwServiceManager::onTransact(),根据传入的code=12,调用addWithChain,最终把服务名称和实体对象插入到mServiceMap这个map中
8.注册成功后,把注册结果写入reply,返回reply信息
9.最终完成服务的注册流程
下一节,我们一起来看看《Native层HIDL服务的获取原理》
我的微信公众号:IngresGe
Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)相关推荐
- JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的注册原理 阅读本文大约需要花费22分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...
- Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
摘要:本节主要来讲解Android10.0 Native层HIDL服务的获取原理 阅读本文大约需要花费23分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...
- JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的获取原理 阅读本文大约需要花费19分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...
- HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
摘要:本节主要来讲解Android10.0 JAVA层的HIDL服务创建和JAVA层的Client验证 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...
- HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
摘要:本节主要来讲解Android10.0 Native层的HIDL服务创建和Native层的Client验证 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Androi ...
- nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)
阅读本文大约需要花费34分钟. 原创不易,如果您觉得有点用,希望可以随手转发或者点击右下角的 "在看".""分享"",拜谢! <And ...
- HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
摘要:本节主要来进行Android10.0 HwBinder的原理总结 阅读本文大约需要花费14分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...
- HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
摘要:本节主要来讲解Android10.0 HwBinder驱动的流程 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...
- HwServiceManager篇-Android10.0 HwBinder通信原理(五)
摘要:本节主要来讲解Android10.0 HwServiceManager的通信原理 阅读本文大约需要花费34分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,And ...
最新文章
- JMeter测试TCP/IP Socket应用的性能
- rabbitmq常用配置
- Lession 14 Do you speak Englist?
- 君威u0073故障码解决_顽疾修复过程,君威没倒挡的变速箱故障就是这样修好
- 通过ceph-deploy搭建ceph 13.2.5 mimic
- hiveql函数笔记(二)
- springboot 多数据源 读写分离 AOP方式
- 多线程编程学习笔记——线程池(二)
- 骨骼动画编辑器Spine的纹理打包器(texture packer)
- KITTI数据集下载
- CSS基础知识10-两种CSS布局
- mybatis传递pojo类学习
- api多版本方案(URL)
- 计算机无法正常更新,无法完成更新正在撤销更改请不要关闭你的计算机的解决方法...
- 在服务器上安装tensorflow-gpu版本及其使用
- SPSS创建数据文件
- 用python对S曲线加减速建模
- 计算机远程桌面软件,手把手教你远程控制电脑软件推荐
- 如何在家赚钱,盘点5个方法,让你足不出户也能挣钱
- 一个剪切shader 液体水
热门文章
- oracle11g dataguard windows,Oracle11g 搭建DataGuard(笔记)
- python有关迭代器和生成器的面试题_【面试题 | Python中迭代器和生成器的区别?】- 环球网校...
- 自调用匿名函数(匿名闭包)解析与调用
- 阿里云云市场全新升级 瞄准需求拓生态
- kafka之四:Kafka集群搭建
- 图像抠图算法学习 - Shared Sampling for Real-Time Alpha Matting
- WebClient 请求 https 页面出错:未能创建 SSL/TLS 安全通道
- mini2440系统引导(四)存储控制器
- 软件工程概论作业:返回一个整数数组中最大子数组的和
- XML学习笔记之XML的简介