register hidl service(omx)
frameworks/av/services/mediacodec/main_codecservice.cpp
// Default codec services using namespace ::android::hardware::media::omx::V1_0; sp<IOmxStore> omxStore = new implementation::OmxStore(); if (omxStore == nullptr) { LOG(ERROR) << "Cannot create IOmxStore HAL service."; } else if (omxStore->registerAsService() != OK) { LOG(ERROR) << "Cannot register IOmxStore HAL service."; } sp<IOmx> omx = new implementation::Omx(); if (omx == nullptr) { LOG(ERROR) << "Cannot create IOmx HAL service."; } else if (omx->registerAsService() != OK) { LOG(ERROR) << "Cannot register IOmx HAL service.";
omxall.cpp
registerAsService()
-->
servicemanagerall.cpp
BpHwServiceManager::_hidl_add()
if (service == nullptr) { _hidl_err = _hidl_data.writeStrongBinder(nullptr); } else { ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::toBinder< ::android::hidl::base::V1_0::IBase>(service); if (_hidl_binder.get() != nullptr) { _hidl_err = _hidl_data.writeStrongBinder(_hidl_binder); } else { _hidl_err = ::android::UNKNOWN_ERROR; } }
关键是上面的toBinder(),它是定义在hidlbindersupport.h中的宏:
sp<IBinder> toBinder(sp<IType> iface) { IType *ifacePtr = iface.get(); if (ifacePtr == nullptr) { return nullptr; } if (ifacePtr->isRemote()) { return ::android::hardware::IInterface::asBinder( static_cast<BpInterface<IType>*>(ifacePtr)); } else { std::string myDescriptor = details::getDescriptor(ifacePtr); if (myDescriptor.empty()) { // interfaceDescriptor fails return nullptr; } // for get + set std::unique_lock<std::mutex> _lock = details::gBnMap.lock(); wp<BHwBinder> wBnObj = details::gBnMap.getLocked(ifacePtr, nullptr); sp<IBinder> sBnObj = wBnObj.promote(); if (sBnObj == nullptr) { auto func = details::getBnConstructorMap().get(myDescriptor, nullptr); if (!func) { func = details::gBnConstructorMap.get(myDescriptor, nullptr); if (!func) { return nullptr; } } sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr))); if (sBnObj != nullptr) { details::gBnMap.setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get())); } } return sBnObj; } }
对于implementation::Omx,对应在omxall.cpp里,isRemote()会返回false,所以上面ifacePtr->isRemote()条件不成立,所以会跑else cae。
所以然后是details::gBnMap.getLocked(ifacePtr, nullptr)
这里是拿到一个BnHwOmx对象,然后将其转化为一个sp<IBinder>
__attribute__((constructor)) static void static_constructor() { ::android::hardware::details::getBnConstructorMap().set(IOmx::descriptor, [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> { return new BnHwOmx(static_cast<IOmx *>(iIntf)); }); ::android::hardware::details::getBsConstructorMap().set(IOmx::descriptor, [](void *iIntf) -> ::android::sp<::android::hidl::base::V1_0::IBase> { return new BsOmx(static_cast<IOmx *>(iIntf)); }); };
所以上面toBinder拿到的是一个BnHwOmx sp
然后是call writeStrongBinder()将这个BnHwOmx sp写到Parcel中,这个函数会call到flatten_binder(),在这个函数中,这时binder->localBinder()为非null,所以type为被设置为BINDER_TYPE_BINDER
system/libhwbinder/Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/, const sp<IBinder>& binder, Parcel* out) { flat_binder_object obj; if (binder != NULL) { BHwBinder *local = binder->localBinder(); if (!local) { BpHwBinder *proxy = binder->remoteBinder(); if (proxy == NULL) { ALOGE("null proxy"); } const int32_t handle = proxy ? proxy->handle() : 0; obj.hdr.type = BINDER_TYPE_HANDLE; obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS; obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ obj.handle = handle; obj.cookie = 0; } else { // Get policy and convert it int policy = local->getMinSchedulingPolicy(); int priority = local->getMinSchedulingPriority(); obj.flags = priority & FLAT_BINDER_FLAG_PRIORITY_MASK; obj.flags |= FLAT_BINDER_FLAG_ACCEPTS_FDS | FLAT_BINDER_FLAG_INHERIT_RT; obj.flags |= (policy & 3) << FLAT_BINDER_FLAG_SCHEDPOLICY_SHIFT; obj.hdr.type = BINDER_TYPE_BINDER; obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); obj.cookie = reinterpret_cast<uintptr_t>(local); } } else { obj.hdr.type = BINDER_TYPE_BINDER; obj.binder = 0; obj.cookie = 0; } return finish_flatten_binder(binder, obj, out); }
之后就是由hwservciemanager来处理这个add的请求,在BnHwServiceManager::_hidl_add()中。
在这个函数中,会call readNullableStrongBinder(),这个函数会call到unflatten_binder()
status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out) { const flat_binder_object* flat = in.readObject<flat_binder_object>(); if (flat) { switch (flat->hdr.type) { case BINDER_TYPE_BINDER: *out = reinterpret_cast<IBinder*>(flat->cookie); return finish_unflatten_binder(NULL, *flat, in); case BINDER_TYPE_HANDLE: *out = proc->getStrongProxyForHandle(flat->handle); return finish_unflatten_binder( static_cast<BpHwBinder*>(out->get()), *flat, in); } } return BAD_TYPE; }
注意这时type是BINDER_TYPE_HANDLE。那为什么之前flatten_binder时,设置的type为BINDER_TYPE_BINDER,而这里却变成了BINDER_TYPE_HANDLE?这是因为在binder driver里将这个type改为了BINDER_TYPE_HANDLE:
drivers/staging/android/binder.c
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, int reply)
{
if (fp->type == BINDER_TYPE_BINDER)
fp->type = BINDER_TYPE_HANDLE;
else
fp->type = BINDER_TYPE_WEAK_HANDLE;
fp->handle = ref->desc;
上面的ref->desc被设置的地方如下,这个desc看起来是依次加1的:
static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
struct binder_node *node)
{
new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1;
for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
ref = rb_entry(n, struct binder_ref, rb_node_desc);
if (ref->desc > new_ref->desc)
break;
new_ref->desc = ref->desc + 1;
}
getStrongProxyForHandle(),这个函数的参数handle在binder driver里被赋值为desc。然后会根据handle创建一个BpHwBinder对象。
system/libhwbinder/ProcessState.cpp
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { // We need to create a new BpHwBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { b = new BpHwBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn't have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } } return result; }
BnHwServcieManager::_hidl_add()函数接下来会call fromBinder(),在这个函数中,binderIface->localBinder()会return false,原因是binderIface是BpHwBinder,而BpHwBinder没有override IBinder的localBinder(),而IBinder的localBinder()会返回null。
所以这里会new一个ProxyType对象,即new一个BpHwBase对象
system/libhidl/transport/include/hidl/HidlBinderSupport.h
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; } if (binderIface->localBinder() == nullptr) { return new ProxyType(binderIface); }
BnHwServcieManager::_hidl_add()函数接下来就是call add(),即为Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service),它定义在如下文件里:
system/hwservicemanager/ServiceManger.cpp
至此,registerAsService() flow走完。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析