摘要:本节主要来讲解Android10.0 Native层HIDL服务的注册原理
阅读本文大约需要花费23分钟。
文章首发微信公众号:IngresGe
专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!
[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析
[Android取经之路] 系列文章:
《系统启动篇》
《日志系统篇》
《Binder通信原理》:
《HwBinder通信原理》
在上一节中,我们知道了HwServiceManager的启动过程,注册、获取服务的细节处理。服务的信息都存在于一个mServiceMap的map容器中。
mServiceMap对应的key为package interface 名称,例如"[email protected]::IServiceManager", 对应的value为一个PackageInterfaceMap结构体,其中包含了lookup()、insertService()等方法,
service的对象最终被插入到 InstanceMap 这个map容器中。
前面我们已经写了一个HIDL实例,来展示了Native层的服务注册和获取调用流程,但是Native层的服务注册、获取流程是如何实现的,现在还不清楚。
这一节,我们深度分析Native层的HAL服务的注册和获取。
在真正看代码前,需要先了解两个类-ProcessState和IPCThreadState 这两个很重要类的概念。
ProcessState从字面意思可以理解,表示是“进程状态”,代表了这个进程的行为,Android中,每个进程都是独立的,所以每个进程都要有一个“进程状态”--ProcessState.
在Binder通信机制中,ProcessState使用了单例模式,即一个进程只有个ProcessState对象,一个进程中有很多个线程,不能每个线程都来new一个新的ProcessState(),采用单例模式后,每个线程都可以使用同一个ProcessState来和Binder驱动通信。
ProcessState作为进程状态的记录器,主要用来打开Binder驱动获取句柄,mmap申请一块(1M-8K)的内存空间,设置Binder线程最大个数。
IPCThreadState从字面意思可以理解,表示是“进程间通信的线程状态”,有了进程状态后,自然需要有线程状态。
ProcessState代表了进程,IPCThreadState代表了线程。Android系统中有很多进程,进程间相互隔离,每个进程内部又有很多线程,线程之间也是相互独立的。所以说一个进程会存在很多个线程,每个线程都有自己的“线程状态”--IPCThreadState对象.这个对象存储在线程的本地存储区(TLS:Thread local storage)中,每个线程都拥有自己的TLS,并且是私有空间,线程之间不会共享。
IPCThreadState对象根据key:gTLS去进行存储。通过pthread_getspecific/pthread_setspecific函数可以获取/设置这些空间中的内容。
IPCThreadState负责与Binder驱动进行数据交互。
BpHwBinder 展开后就是Binder Proxy,也就是Binder代理的含义。BpHwBinder 是客户端用来与服务交互的代理类,负责实现跨进程传输的传输机制,不关心具体的传输内容。通信功能由其它类和函数实现,但由于这些类和函数被BpHwBinder代理,所以客户端需要通过BpHwBinder来发送Binder通信数据。
BHwBinder代表服务端,可以理解为服务的Binder实体,当服务端从Binder驱动中读取到数据后,由BHwBinder类进行处理。
IDemo的HIDL服务注册流程如下图所示:
[\vendor\ingres\interfaces\demo\1.0\default\Service.cpp]
int main() {
configureRpcThreadpool(4, true); //和"dev/hwbinder" 进行通信,设置最大的线程个数为4
Demo 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()进一步分析
开始HIDL服务注册,DemoAll.cpp 在编译的时候生成,源对象为IDemo.hal
[\out\soong\.intermediates\vendor\ingres\interfaces\demo\1.0\[email protected]_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);
}
[/system/libhidl/transport/ServiceManagement.cpp]
status_t registerAsServiceInternal(const sp& service, const std::string& name) {
if (service == nullptr) {
return UNEXPECTED_NULL;
}
//1.获取HwServiceManager代理对象:BpHwServiceManager,fromBinder最终为 new BpHwServiceManager(new BpHwBinder(0))
//参考[4.5]
sp sm = defaultServiceManager1_2();
if (sm == nullptr) {
return INVALID_OPERATION;
}
bool registered = false;
Return 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服务的注册
defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager
[/system/libhidl/transport/ServiceManagement.cpp]
sp defaultServiceManager1_2() {
using android::hidl::manager::V1_2::BnHwServiceManager;
using android::hidl::manager::V1_2::BpHwServiceManager;
static std::mutex gDefaultServiceManagerLock;
static sp gDefaultServiceManager;
{
std::lock_guard _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(
ProcessState::self()->getContextObject(nullptr));
if (gDefaultServiceManager == nullptr) {
LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
sleep(1);
}
}
}
return gDefaultServiceManager;
}
[/system/libhwbinder/ProcessState.cpp]
sp ProcessState::getContextObject(const sp& /*caller*/)
{
return getStrongProxyForHandle(0); //传入handle = 0, HwServiceManager的handle就为0
}
获取一个BpHwBinder的对象,即当Service向HwServiceManager进行注册时,Service变成了Client,HwServiceManager变成了Server,需要先把Service 转换成一个BpHwBinder对象,作为Binder代理进行通信
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder;
//handle = 0传入的binder在lookupHandleLocked()中赋值为nullptr
if (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;
}
根据BpHwBinder 这个远程对象,拿到HwServiceManager的对象,这里是远程对象,所以返回一个BpHwServiceManager 对象。
BpHwBinder负责数据传输,而BpHwServiceManager服务数据业务,业务数据在BpHwServiceManager层打包好后,转交给BpHwBinder发送。
[/system/libhidl/transport/ServiceManagement.cpp]
template
sp fromBinder(const sp& 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 base = static_cast(binderIface.get())->getImpl();
if (details::canCastInterface(base.get(), IType::descriptor)) {
StubType* stub = static_cast(binderIface.get());
return stub->getImpl();
} else {
return nullptr;
}
}
BpHwServiceManager的类继承关系如下图所示:
[\out\soong\.intermediates\system\libhidl\transport\manager\1.2\[email protected]_genc++\gen\android\hidl\manager\1.2\ServiceManagerAll.cpp]
::android::hardware::Return 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 _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头信息"[email protected]::IServiceManager"
4.写入服务名称,如果没有配置的话,name为"default"
5.写入服务的实体对象--new Demo()
6.调用remote的transact,发送 12 /* addWithChain */ 的命令进行服务的注册
7.得到返回的reply数据
::android::hardware::Return 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 _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头信息"[email protected]::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 _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(_hidl_out_success);
_hidl_error:
_hidl_status.setFromStatusT(_hidl_err);
return ::android::hardware::Return(_hidl_status);
}
asBinder的转换后,得到的对象是BpHwBinder,asBinder转换如下图所示:
[/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() 进行处理
[/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进行通信,传送内容,等待响应
[/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(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 写入mOut
mOut.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对象的具体位置。
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;
}
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;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
if (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;
}
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(
tr.target.ptr)->attemptIncStrong(this)) {
error = reinterpret_cast(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags, reply_callback);
reinterpret_cast(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;
}
[/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的继承关系如下图所示:
onTransact()中,根据传入的hidl_code,调用相应的接口执行,从[4.6]可知,注册服务时,传入的hidl_code为12,因此会调用_hidl_addWithChain进行操作。
[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/[email protected]_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;
}
_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/[email protected]_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(&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(&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(_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;
}
[/system/hwservicemanager/ServiceManager.cpp]
Return ServiceManager::addWithChain(const hidl_string& name,
const sp& service,
const hidl_vec& chain) {
if (service == nullptr) {
return false;
}
//1.获取 CallingContext的的sid\pid信息
auto callingContext = getBinderCallingContext();
//2.调用addImpl进行注册
return addImpl(name, service, chain, callingContext);
}
获取当前binder调用的pid、sid 上下文信息后,开始注册服务,即把Demo对象注册到mServiceMap中。
在过程中,要进行selinux检查,确认该进程有权限添加service后,再检查是否有重复注册,而且如果子类在父类上注册,则注销它,
排除一切问题后,把需要注册的服务,注册到mServiceMap中,最后建立一个死亡连接,当服务挂掉时会接收到通知,做一些清理工作。
[/system/hwservicemanager/ServiceManager.cpp]
bool ServiceManager::addImpl(const std::string& name,
const sp& service,
const hidl_vec& interfaceChain,
const AccessControl::CallingContext& callingContext) {
//传入的interfaceChain size大于0
if (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 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(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;
}
把传入的hidlservice插入到mInstanceMap 中,即 mServiceMap的value--PackageInterfaceMap 中。
[/system/hwservicemanager/ServiceManager.cpp]
void ServiceManager::PackageInterfaceMap::insertService(
std::unique_ptr &&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