通过前面的分析我们知道,Hal进程启动时,会向hwservicemanager进程注册hidl服务,那么当Framework Server需要通过hal访问硬件设备时,首先需要查询对应的hidl服务,那么Client进程是如何查询hidl服务的呢?这篇文章将展开分析,这里再次以IComposer为例进行展开。
frameworks\native\services\surfaceflinger\DisplayHardware\ComposerHal.cpp
Composer::Composer(bool useVrComposer)
: mWriter(kWriterInitialSize),
mIsUsingVrComposer(useVrComposer)
{
if (mIsUsingVrComposer) {
mComposer = IComposer::getService("vr");
} else {
mComposer = IComposer::getService(); // use default name
}
if (mComposer == nullptr) {
LOG_ALWAYS_FATAL("failed to get hwcomposer service");
}
mComposer->createClient(
[&](const auto& tmpError, const auto& tmpClient)
{
if (tmpError == Error::NONE) {
mClient = tmpClient;
}
});
if (mClient == nullptr) {
LOG_ALWAYS_FATAL("failed to create composer client");
}
}
这里通过IComposer::getService()函数来查询IComposer这个HIDL服务,由于这里没有传递任何参数,因此函数最终会调用:
composer\2.1\[email protected]_genc++_headers\gen\android\hardware\graphics\composer\2.1\IComposer.h
static ::android::sp getService(const std::string &serviceName="default", bool getStub=false);
注意,这里的getStub为false,说明加载hidl服务方式是由当前hidl服务的transport类型决定。
android.hardware.graphics.composer
hwbinder
2.1
IComposer
vr
由于IComposer的transport是hwbinder类型,那么将从hwservicemanager中查询hidl服务。
composer\2.1\[email protected]_genc++\gen\android\hardware\graphics\composer\2.1\ComposerAll.cpp
::android::sp IComposer::getService(const std::string &serviceName, const bool getStub) {
using ::android::hardware::defaultServiceManager;
using ::android::hardware::details::waitForHwService;
using ::android::hardware::getPassthroughServiceManager;
using ::android::hardware::Return;
using ::android::sp;
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
sp iface = nullptr;
const sp<::android::hidl::manager::V1_0::IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}
Return transportRet = sm->getTransport(IComposer::descriptor, serviceName);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s", transportRet.description().c_str());
return nullptr;
}
Transport transport = transportRet;
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
#ifdef __ANDROID_TREBLE__
#ifdef __ANDROID_DEBUGGABLE__
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__
const bool trebleTestingOverride = false;
const bool vintfLegacy = false;
#endif // __ANDROID_DEBUGGABLE__
#else // not __ANDROID_TREBLE__
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY);
#endif // __ANDROID_TREBLE__
for (int tries = 0; !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)); tries++) {
if (tries > 1) {
ALOGI("getService: Will do try %d for %s/%s in 1s...", tries, IComposer::descriptor, serviceName.c_str());
sleep(1);
}
if (vintfHwbinder && tries > 0) {
waitForHwService(IComposer::descriptor, serviceName);
}
Return> ret =
sm->get(IComposer::descriptor, serviceName);
if (!ret.isOk()) {
ALOGE("IComposer: defaultServiceManager()->get returns %s", ret.description().c_str());
break;
}
sp<::android::hidl::base::V1_0::IBase> base = ret;
if (base == nullptr) {
if (tries > 0) {
ALOGW("IComposer: found null hwbinder interface");
}continue;
}
Return> castRet = IComposer::castFrom(base, true /* emitError */);
if (!castRet.isOk()) {
if (castRet.isDeadObject()) {
ALOGW("IComposer: found dead hwbinder service");
continue;
} else {
ALOGW("IComposer: cannot call into hwbinder service: %s; No permission? Check for selinux denials.", castRet.description().c_str());
break;
}
}
iface = castRet;
if (iface == nullptr) {
ALOGW("IComposer: received incompatible service; bug in hwservicemanager?");
break;
}
return iface;
}
return iface;
}
这里通过sm->get(IComposer::descriptor, serviceName)查询IComposer这个hidl服务,得到IBase对象后,在通过IComposer::castFrom转换为IComposer对象。
::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>> BpHwServiceManager::get(const ::android::hardware::hidl_string& fqName, const ::android::hardware::hidl_string& name){
::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>> _hidl_out = ::android::hidl::manager::V1_0::BpHwServiceManager::_hidl_get(this, this, fqName, name);
return _hidl_out;
}
::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>> BpHwServiceManager::_hidl_get(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_string& fqName, const ::android::hardware::hidl_string& name) {
#ifdef __ANDROID_DEBUGGABLE__
bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();
const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();
#else
(void) _hidl_this_instrumentor;
#endif // __ANDROID_DEBUGGABLE__
atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::get::client");
#ifdef __ANDROID_DEBUGGABLE__
if (UNLIKELY(mEnableInstrumentation)) {
std::vector _hidl_args;
_hidl_args.push_back((void *)&fqName);
_hidl_args.push_back((void *)&name);
for (const auto &callback: mInstrumentationCallbacks) {
callback(InstrumentationEvent::CLIENT_API_ENTRY, "android.hidl.manager", "1.0", "IServiceManager", "get", &_hidl_args);
}
}
#endif // __ANDROID_DEBUGGABLE__
::android::hardware::Parcel _hidl_data;
::android::hardware::Parcel _hidl_reply;
::android::status_t _hidl_err;
::android::hardware::Status _hidl_status;
::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service;
_hidl_err = _hidl_data.writeInterfaceToken(BpHwServiceManager::descriptor);
if (_hidl_err != ::android::OK) { goto _hidl_error; }
size_t _hidl_fqName_parent;
_hidl_err = _hidl_data.writeBuffer(&fqName, sizeof(fqName), &_hidl_fqName_parent);
if (_hidl_err != ::android::OK) { goto _hidl_error; }
_hidl_err = ::android::hardware::writeEmbeddedToParcel(
fqName,
&_hidl_data,
_hidl_fqName_parent,
0 /* parentOffset */);
if (_hidl_err != ::android::OK) { goto _hidl_error; }
size_t _hidl_name_parent;
_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; }
_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(1 /* get */, _hidl_data, &_hidl_reply);
if (_hidl_err != ::android::OK) { goto _hidl_error; }
_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);
if (_hidl_err != ::android::OK) { goto _hidl_error; }
if (!_hidl_status.isOk()) { return _hidl_status; }
{
::android::sp<::android::hardware::IBinder> _hidl__hidl_out_service_binder;
_hidl_err = _hidl_reply.readNullableStrongBinder(&_hidl__hidl_out_service_binder);
if (_hidl_err != ::android::OK) { goto _hidl_error; }
_hidl_out_service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl__hidl_out_service_binder);
}
atrace_end(ATRACE_TAG_HAL);
#ifdef __ANDROID_DEBUGGABLE__
if (UNLIKELY(mEnableInstrumentation)) {
std::vector _hidl_args;
_hidl_args.push_back((void *)&_hidl_out_service);
for (const auto &callback: mInstrumentationCallbacks) {
callback(InstrumentationEvent::CLIENT_API_EXIT, "android.hidl.manager", "1.0", "IServiceManager", "get", &_hidl_args);
}
}
#endif // __ANDROID_DEBUGGABLE__
_hidl_status.setFromStatusT(_hidl_err);
return ::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>>(_hidl_out_service);
_hidl_error:
_hidl_status.setFromStatusT(_hidl_err);
return ::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>>(_hidl_status);
}
整个调用过程和hidl服务过程完全一致,就是一个从BpHwServiceManager --> BnHwServiceManager --> ServiceManager的过程。但需要注意,BpHwServiceManager得到BnHwServiceManager返回过来的binder代理后,会通过fromBinder函数进行对象转换:
::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl__hidl_out_service_binder)
hwservicemanager将IComposer的binder代理BpHwBinder发给Framework Server进程,Framework Server进程拿到的依然是IComposer的binder代理BpHwBinder对象,因此在fromBinder函数中将创建BpHwBase对象来封装BpHwBinder。
::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) {
#ifdef __ANDROID_DEBUGGABLE__
bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();
const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();
#endif // __ANDROID_DEBUGGABLE__
::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;
_hidl_err = _hidl_data.readBuffer(sizeof(*fqName), &_hidl_fqName_parent, reinterpret_cast(&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;
_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; }
atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::get::server");
#ifdef __ANDROID_DEBUGGABLE__
if (UNLIKELY(mEnableInstrumentation)) {
std::vector _hidl_args;
_hidl_args.push_back((void *)fqName);
_hidl_args.push_back((void *)name);
for (const auto &callback: mInstrumentationCallbacks) {
callback(InstrumentationEvent::SERVER_API_ENTRY, "android.hidl.manager", "1.0", "IServiceManager", "get", &_hidl_args);
}
}
#endif // __ANDROID_DEBUGGABLE__
::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service = static_cast(_hidl_this)->_hidl_mImpl->get(*fqName, *name);
::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
if (_hidl_out_service == nullptr) {
_hidl_err = _hidl_reply->writeStrongBinder(nullptr);
} else {
::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::toBinder<
::android::hidl::base::V1_0::IBase>(_hidl_out_service);
if (_hidl_binder.get() != nullptr) {
_hidl_err = _hidl_reply->writeStrongBinder(_hidl_binder);
} else {
_hidl_err = ::android::UNKNOWN_ERROR;
}
}
/* _hidl_err ignored! */
atrace_end(ATRACE_TAG_HAL);
#ifdef __ANDROID_DEBUGGABLE__
if (UNLIKELY(mEnableInstrumentation)) {
std::vector _hidl_args;
_hidl_args.push_back((void *)&_hidl_out_service);
for (const auto &callback: mInstrumentationCallbacks) {
callback(InstrumentationEvent::SERVER_API_EXIT, "android.hidl.manager", "1.0", "IServiceManager", "get", &_hidl_args);
}
}
#endif // __ANDROID_DEBUGGABLE__
_hidl_cb(*_hidl_reply);
return _hidl_err;
}
BnHwServiceManager通过ServiceManager对象查询到对应的hidl服务,返回IBase对象后,会调用toBinder函数转换为IBinder类型对象:
::android::hardware::toBinder< ::android::hidl::base::V1_0::IBase>(_hidl_out_service)
由于在hwservicemanager这边,保存的是IComposer的BpHwBase对象,因此在toBinder函数中将调用IInterface::asBinder来得到BpHwBase的成员变量中的BpHwBinder对象。
if (ifacePtr->isRemote()) {
return ::android::hardware::IInterface::asBinder(static_cast(ifacePtr));
}
fromBinder和toBinder函数在之前的文章中已经详细分析了,这里就不再展开。
服务查询过程其实就是根据接口包名及服务名称,从hwservicemanager管理的表中查询对应的IBase服务对象,然后在Client进程空间分别创建BpHwBinder和BpHwBase对象。
Framework Server进程通过上述hidl服务查询,得到了BpHwBase对象后,需要将其转换为与业务相关的代理对象,这就是通过:Return
composer\2.1\[email protected]_genc++\gen\android\hardware\graphics\composer\2.1\ComposerAll.cpp
::android::hardware::Return<::android::sp> IComposer::castFrom(const ::android::sp<::android::hidl::base::V1_0::IBase>& parent, bool emitError) {
return ::android::hardware::details::castInterface(
parent, "[email protected]::IComposer", emitError);
}
system\libhidl\transport\include\hidl\HidlTransportSupport.h
// cast the interface IParent to IChild.
// Return nonnull if cast successful.
// Return nullptr if:
// 1. parent is null
// 2. cast failed because IChild is not a child type of IParent.
// 3. !emitError, calling into parent fails.
// Return an error Return object if:
// 1. emitError, calling into parent fails.
template
Return> castInterface(sp parent, const char *childIndicator, bool emitError) {
if (parent.get() == nullptr) {
// casts always succeed with nullptrs.
return nullptr;
}
Return canCastRet = details::canCastInterface(parent.get(), childIndicator, emitError);
if (!canCastRet.isOk()) {
// call fails, propagate the error if emitError
return emitError
? details::StatusOf>(canCastRet)
: Return>(sp(nullptr));
}
if (!canCastRet) {
return sp(nullptr); // cast failed.
}
// TODO b/32001926 Needs to be fixed for socket mode.
if (parent->isRemote()) {
// binderized mode. Got BpChild. grab the remote and wrap it.
return sp(new BpChild(toBinder(parent)));
}
// Passthrough mode. Got BnChild and BsChild.
return sp(static_cast(parent.get()));
}
} // namespace details
这个模板函数展开后如下:
Return> castInterface(sp parent, const char *childIndicator, bool emitError) {
if (parent.get() == nullptr) {
// casts always succeed with nullptrs.
return nullptr;
}
Return canCastRet = details::canCastInterface(parent.get(), childIndicator, emitError);
if (!canCastRet.isOk()) {
// call fails, propagate the error if emitError
return emitError
? details::StatusOf>(canCastRet)
: Return>(sp(nullptr));
}
if (!canCastRet) {
return sp(nullptr); // cast failed.
}
// TODO b/32001926 Needs to be fixed for socket mode.
if (parent->isRemote()) {
// binderized mode. Got BpChild. grab the remote and wrap it.
return sp(new BpHwComposer(toBinder(parent)));
}
// Passthrough mode. Got BnChild and BsChild.
return sp(static_cast(parent.get()));
}
因此最终会创建一个BpHwComposer对象。
new BpHwComposer(toBinder