通過前面對Treble架構的介紹,我們知道,Android Framework進程和Hal分離,每個Hal獨立運行在自己的進程地址空間,那麼這些Hal進程是如何啓動的呢?本文以composer hal爲例展開分析。
在以下路徑有composer hal的rc啓動腳本:
hardware/interfaces/graphics/composer/2.1/default/[email protected]
-
service hwcomposer-2-1 /vendor/bin/hw/[email protected]
-
class hal animation
-
user system
-
group graphics drmrpc
-
capabilities SYS_NICE
-
onrestart restart surfaceflinger
編譯後,會將該腳本文件copy到vendor/etc/init目錄,在開機時,init進程會讀取並解析這個腳本,然後啓動[email protected]進程:
system 661 1 32288 7832 0 0 S [email protected]
該進程的可執行文件是:vendor/bin/hw/[email protected],
該可執行文件對應的源碼爲:hardware/interfaces/graphics/composer/2.1/default/service.cpp
composer Hal啓動過程
hardware/interfaces/graphics/composer/2.1/default/service.cpp
-
int main() {
-
// the conventional HAL might start binder services
-
android::ProcessState::initWithDriver("/dev/vndbinder");
-
android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
-
android::ProcessState::self()->startThreadPool();
-
// same as SF main thread
-
struct sched_param param = {0};
-
param.sched_priority = 2;
-
if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK,
-
¶m) != 0) {
-
ALOGE("Couldn't set SCHED_FIFO: %d", errno);
-
}
-
return defaultPassthroughServiceImplementation<IComposer>(4);
-
}
前面我們分析了Treble架構下的binder通信變化,在Treble架構下,存在了3個binder設備,分別是/dev/binder、/dev/vndbinder、/dev/hwbinder,上層需要通過binder庫來訪問這些binder設備,而/dev/binder和/dev/vndbinder都是由libbinder來訪問,因此需要指定打開的binder設備。
android::ProcessState::initWithDriver("/dev/vndbinder");
這句說明composer hal通過vndbinder來通信的,接下來就是設置binder線程個數爲4,並啓動binder線程池,然後調用
defaultPassthroughServiceImplementation<IComposer>(4)
完成composer hal的啓動。
system\libhidl\transport\include\hidl\LegacySupport.h
-
template<class Interface>
-
__attribute__((warn_unused_result))
-
status_t defaultPassthroughServiceImplementation(std::string name,
-
size_t maxThreads = 1) {
-
configureRpcThreadpool(maxThreads, true); //配置binder線程個數
-
status_t result = registerPassthroughServiceImplementation<Interface>(name);
-
if (result != OK) {
-
return result;
-
}
-
joinRpcThreadpool();
-
return 0;
-
}
-
template<class Interface>
-
__attribute__((warn_unused_result))
-
status_t registerPassthroughServiceImplementation(
-
std::string name = "default") {
-
sp<Interface> service = Interface::getService(name, true /* getStub */); //從當前進程空間中拿到IComposer接口類對象
-
if (service == nullptr) {
-
ALOGE("Could not get passthrough implementation for %s/%s.",
-
Interface::descriptor, name.c_str());
-
return EXIT_FAILURE;
-
}
-
LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
-
Interface::descriptor, name.c_str());
-
status_t status = service->registerAsService(name);//將IComposer註冊到hwservicemanager中
-
if (status == OK) {
-
ALOGI("Registration complete for %s/%s.",
-
Interface::descriptor, name.c_str());
-
} else {
-
ALOGE("Could not register service %s/%s (%d).",
-
Interface::descriptor, name.c_str(), status);
-
}
-
return status;
-
}
Hal進程獲取IComposer類對象
在composer hal進程啓動時,首先調用IComposer 的getService(“default”,true)來獲取IComposer的類對象。
composer\2.1\[email protected]_genc++\gen\android\hardware\graphics\composer\2.1\ComposerAll.cpp
-
::android::sp<IComposer> 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<IComposer> iface = nullptr;
-
const sp<::android::hidl::manager::V1_0::IServiceManager> sm = defaultServiceManager(); //獲取hwservicemanager的代理
-
if (sm == nullptr) {
-
ALOGE("getService: defaultServiceManager() is null");
-
return nullptr;
-
}
-
Return<Transport> transportRet = sm->getTransport(IComposer::descriptor, serviceName);//查詢IComposer的Transport
-
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); //Transport類型判斷
-
#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__
-
//hwbinder方式下獲取IComposer對象
-
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<sp<::android::hidl::base::V1_0::IBase>> 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<sp<IComposer>> 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;
-
}
-
//passthrough方式下獲取IComposer對象
-
if (getStub || vintfPassthru || vintfLegacy) {
-
const sp<::android::hidl::manager::V1_0::IServiceManager> pm = getPassthroughServiceManager();
-
if (pm != nullptr) {
-
Return<sp<::android::hidl::base::V1_0::IBase>> ret =
-
pm->get(IComposer::descriptor, serviceName);
-
if (ret.isOk()) {
-
sp<::android::hidl::base::V1_0::IBase> baseInterface = ret;
-
if (baseInterface != nullptr) {
-
iface = IComposer::castFrom(baseInterface);
-
if (!getStub || trebleTestingOverride) {
-
iface = new BsComposer(iface);
-
}
-
}
-
}
-
}
-
}
-
return iface;
-
}
這裏通過hwservicemanager獲取當前服務的Tranport類型,Treble中定義的Tranport包括passthrough和binderized,每個hidl服務都在/system/manifest.xml或者/vendor/manifest.xml中指定了對應的Tranport類型:
manifest.xml文件的讀取和解析都是由hwservicemanager來完成的,此時[email protected]作爲hwservicemanager的client端,通過hwservicemanager的binder代理對象來請求hwservicemanager進程查詢IComposer的Transport類型,從上圖可以看出IComposer的Transport被定義爲hwbinder,因此:
vintfHwbinder=true
vintfPassthru=false
vintfLegacy=false
hidl服務對象獲取方式包括2中:
1. 通過查詢hwservicemanager來獲取;
2.通過PassthroughServiceManager從本進程地址空間中獲取;
那如何選擇獲取方式呢? 其實就是vintfHwbinder、vintfPassthru、vintfLegacy、getStub這4個變量值來決定hidl服務的獲取方式。
1. 當getStub爲true時,不管hal屬於什麼傳輸模式,都採用PassthroughServiceManager獲取接口對象;
2.當getStub爲false時,則根據hal傳輸模式來選擇接口獲取方式;
《1》 當hal模式爲Hwbinder時,則從hwservicemanager中查詢;
《2》當hal傳輸模式爲Passthru或Legacy時,則採用PassthroughServiceManager來獲取;
那什麼是Hwbinder,什麼是Passthru及Legacy呢?下圖是google提供的hal的roadmap圖:
-
if (getStub || vintfPassthru || vintfLegacy) {
-
const sp<::android::hidl::manager::V1_0::IServiceManager> pm = getPassthroughServiceManager();
-
if (pm != nullptr) {
-
Return<sp<::android::hidl::base::V1_0::IBase>> ret =
-
pm->get(IComposer::descriptor, serviceName);
-
if (ret.isOk()) {
-
sp<::android::hidl::base::V1_0::IBase> baseInterface = ret;
-
if (baseInterface != nullptr) {
-
iface = IComposer::castFrom(baseInterface);
-
if (!getStub || trebleTestingOverride) {
-
iface = new BsComposer(iface);
-
}
-
}
-
}
-
}
-
}
sp<Interface> service = Interface::getService(name, true /* getStub */)所以getStub=true. 這裏通過PassthroughServiceManager來獲取IComposer對象。其實所有的Hal 進程都是通過PassthroughServiceManager來得到hidl服務對象的,而作爲Hal進程的Client端Framework進程在獲取hidl服務對象時,需要通過hal的Transport類型來選擇獲取方式。
system\libhidl\transport\ServiceManagement.cpp
-
sp<IServiceManager> getPassthroughServiceManager() {
-
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
-
return manager;
-
}
這裏只是簡單的創建了一個PassthroughServiceManager對象。PassthroughServiceManager也實現了IServiceManager接口。然後通過PassthroughServiceManager詢服務:
-
Return<sp<IBase>> get(const hidl_string& fqName,
-
const hidl_string& name) override {
-
std::string stdFqName(fqName.c_str());
-
//fqName looks like [email protected]::IFoo
-
size_t idx = stdFqName.find("::");
-
if (idx == std::string::npos ||
-
idx + strlen("::") + 1 >= stdFqName.size()) {
-
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
-
return nullptr;
-
}
-
std::string packageAndVersion = stdFqName.substr(0, idx);
-
std::string ifaceName = stdFqName.substr(idx + strlen("::"));
-
const std::string prefix = packageAndVersion + "-impl";
-
const std::string sym = "HIDL_FETCH_" + ifaceName;
-
const android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
-
const int dlMode = RTLD_LAZY;
-
void *handle = nullptr;
-
// TODO: lookup in VINTF instead
-
// TODO(b/34135607): Remove HAL_LIBRARY_PATH_SYSTEM
-
dlerror(); // clear
-
for (const std::string &path : {
-
HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM
-
}) {
-
std::vector<std::string> libs = search(path, prefix, ".so");
-
for (const std::string &lib : libs) {
-
const std::string fullPath = path + lib;
-
// If sphal namespace is available, try to load from the
-
// namespace first. If it fails, fall back to the original
-
// dlopen, which loads from the current namespace.
-
if (sphal_namespace != nullptr && path != HAL_LIBRARY_PATH_SYSTEM) {
-
const android_dlextinfo dlextinfo = {
-
.flags = ANDROID_DLEXT_USE_NAMESPACE,
-
// const_cast is dirty but required because
-
// library_namespace field is non-const.
-
.library_namespace = const_cast<android_namespace_t*>(sphal_namespace),
-
};
-
handle = android_dlopen_ext(fullPath.c_str(), dlMode, &dlextinfo);
-
if (handle == nullptr) {
-
const char* error = dlerror();
-
LOG(WARNING) << "Failed to dlopen " << lib << " from sphal namespace:"
-
<< (error == nullptr ? "unknown error" : error);
-
} else {
-
LOG(DEBUG) << lib << " loaded from sphal namespace.";
-
}
-
}
-
if (handle == nullptr) {
-
handle = dlopen(fullPath.c_str(), dlMode);
-
}
-
if (handle == nullptr) {
-
const char* error = dlerror();
-
LOG(ERROR) << "Failed to dlopen " << lib << ": "
-
<< (error == nullptr ? "unknown error" : error);
-
continue;
-
}
-
IBase* (*generator)(const char* name);
-
*(void **)(&generator) = dlsym(handle, sym.c_str());
-
if(!generator) {
-
const char* error = dlerror();
-
LOG(ERROR) << "Passthrough lookup opened " << lib
-
<< " but could not find symbol " << sym << ": "
-
<< (error == nullptr ? "unknown error" : error);
-
dlclose(handle);
-
continue;
-
}
-
IBase *interface = (*generator)(name.c_str());
-
if (interface == nullptr) {
-
dlclose(handle);
-
continue; // this module doesn't provide this instance name
-
}
-
registerReference(fqName, name);
-
return interface;
-
}
-
}
-
return nullptr;
-
}
根據傳入的fqName=([email protected]::IComposer")獲取當前的接口名IComposer,拼接出後面需要查找的函數名HIDL_FETCH_IComposer和庫名字[email protected],然後查找"/system/lib64/hw/"、"/vendor/lib64/hw/"、"/odm/lib64/hw/"下是否有對應的so庫。接着通過dlopen載入/vendor/lib/hw/[email protected],然後通過dlsym查找並調用HIDL_FETCH_IComposer函數,最後調用registerReference(fqName, name)向hwservicemanager註冊。
hardware/interfaces/graphics/composer/2.1/default/Android.bp
-
cc_library_shared {
-
name: "[email protected]",
-
defaults: ["hidl_defaults"],
-
proprietary: true,
-
relative_install_path: "hw",
-
srcs: ["Hwc.cpp"],
-
static_libs: ["libhwcomposer-client"],
-
shared_libs: [
-
"libbase",
-
"libcutils",
-
"libfmq",
-
"libhardware",
-
"libhidlbase",
-
"libhidltransport",
-
"liblog",
-
"libsync",
-
"libutils",
-
"libhwc2on1adapter"
-
],
-
}
從上面的編譯腳本可知,[email protected]的源碼文件爲Hwc.cpp:
hardware/interfaces/graphics/composer/2.1/default/Hwc.cpp
-
IComposer* HIDL_FETCH_IComposer(const char*)
-
{
-
const hw_module_t* module = nullptr;
-
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
-
if (err) {
-
ALOGE("failed to get hwcomposer module");
-
return nullptr;
-
}
-
return new HwcHal(module);
-
}
hw_get_module就和AndroidO以前的Hal模式一致,這正是Passthrough複用原有hal的原理。加載hal庫後,得到hw_module_t,然後使用HwcHal來包裹hw_module_t,而HwcHal實現了IComposer接口。
registerPassthroughClient
得到IComposer接口對象HwcHal後,需要註冊相關信息到hwservicemanager中。
system\libhidl\transport\ServiceManagement.cpp
-
static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) {
-
sp<IServiceManager> binderizedManager = defaultServiceManager();
-
if (binderizedManager == nullptr) {
-
LOG(WARNING) << "Could not registerReference for "
-
<< interfaceName << "/" << instanceName
-
<< ": null binderized manager.";
-
return;
-
}
-
auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName);
-
if (!ret.isOk()) {
-
LOG(WARNING) << "Could not registerReference for "
-
<< interfaceName << "/" << instanceName
-
<< ": " << ret.description();
-
return;
-
}
-
LOG(VERBOSE) << "Successfully registerReference for "
-
<< interfaceName << "/" << instanceName;
-
}
這裏通過hwservicemanager的代理對象跨進程調用registerPassthroughClient。
[email protected]_genc++\gen\android\hidl\manager\1.0\ServiceManagerAll.cpp
-
::android::hardware::Return<void> BpHwServiceManager::registerPassthroughClient(const ::android::hardware::hidl_string& fqName, const ::android::hardware::hidl_string& name){
-
::android::hardware::Return<void> _hidl_out = ::android::hidl::manager::V1_0::BpHwServiceManager::_hidl_registerPassthroughClient(this, this, fqName, name);
-
return _hidl_out;
-
}
-
::android::hardware::Return<void> BpHwServiceManager::_hidl_registerPassthroughClient(::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::registerPassthroughClient::client");
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _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", "registerPassthroughClient", &_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;
-
_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(8 /* registerPassthroughClient */, _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; }
-
atrace_end(ATRACE_TAG_HAL);
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::CLIENT_API_EXIT, "android.hidl.manager", "1.0", "IServiceManager", "registerPassthroughClient", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
_hidl_status.setFromStatusT(_hidl_err);
-
return ::android::hardware::Return<void>();
-
_hidl_error:
-
_hidl_status.setFromStatusT(_hidl_err);
-
return ::android::hardware::Return<void>(_hidl_status);
-
}
這裏和普通binder通信相同,先就需要傳輸的函數參數打包到Parcel對象中,然後調用binder代理對象的transact函數將函數參數,函數調用碼發送到Server端進程,這裏的_hidl_this其實指向的是BpHwServiceManager,這個是與業務相關的代理對象,通過asBinder函數得到與傳輸相關的binder代理,那這個binder代理是什麼類型呢? 其實就是BpHwBinder,關於hwservicemanager代理對象的獲取,asBinder函數的實現,在後續的章節中進行分析。經過BpHwServiceManager的請求,最終位於hwservicemanager進程中的BnHwServiceManager將接收函數調用請求:
[email protected]_genc++\gen\android\hidl\manager\1.0\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 8 /* registerPassthroughClient */:
-
{
-
_hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_registerPassthroughClient(this, _hidl_data, _hidl_reply, _hidl_cb);
-
break;
-
}
-
default:
-
{
-
return ::android::hidl::base::V1_0::BnHwBase::onTransact(
-
_hidl_code, _hidl_data, _hidl_reply, _hidl_flags, _hidl_cb);
-
}
-
}
BnHwServiceManager將調用_hidl_registerPassthroughClient來執行Client端的註冊。
-
::android::status_t BnHwServiceManager::_hidl_registerPassthroughClient(
-
::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<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;
-
_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::registerPassthroughClient::server");
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _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", "registerPassthroughClient", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
static_cast<BnHwServiceManager*>(_hidl_this)->_hidl_mImpl->registerPassthroughClient(*fqName, *name);
-
(void) _hidl_cb;
-
atrace_end(ATRACE_TAG_HAL);
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::SERVER_API_EXIT, "android.hidl.manager", "1.0", "IServiceManager", "registerPassthroughClient", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
-
return _hidl_err;
-
}
BnHwServiceManager首先讀取BpHwServiceManager發送過來的函數參數,然後將registerPassthroughClient的執行轉交個其成員變量的_hidl_mImpl對象,然後將執行結果返回給BpHwServiceManager,那麼_hidl_mImpl保存的是什麼對象呢? 其實_hidl_mImpl指向的是ServiceManager對象,這個是在構造BnHwServiceManager對象時傳入的,在後續分析hwservicemanager啓動過程時,會進行詳細分析。
system\hwservicemanager\ServiceManager.cpp
-
Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
-
const hidl_string &name) {
-
pid_t pid = IPCThreadState::self()->getCallingPid();
-
if (!mAcl.canGet(fqName, pid)) { //根據Client端的pid及註冊接口的包名,判斷是否有權限註冊
-
/* We guard this function with "get", because it's typically used in
-
* the getService() path, albeit for a passthrough service in this
-
* case
-
*/
-
return Void();
-
}
-
LOG(INFO) << "registerPassthroughClient " << fgName.c_str() << " of "
-
<< name.c_str()
-
PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
-
if (name.empty()) {
-
LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
-
<< fqName.c_str();
-
return Void();
-
}
-
HidlService *service = ifaceMap.lookup(name);
-
if (service == nullptr) {
-
auto adding = std::make_unique<HidlService>(fqName, name);
-
adding->registerPassthroughClient(pid);
-
ifaceMap.insertService(std::move(adding));
-
} else {
-
service->registerPassthroughClient(pid);
-
}
-
return Void();
-
}
首先根據fqName從mServiceMap中查找對應的PackageInterfaceMap,然後根據name從PackageInterfaceMap中查找HidlService,如果找不到對應的HidlService對象,那麼就調用std::make_unique<HidlService>(fqName,name)創建一個新的HidlService對象,並ifaceMap.insertService(std::move(adding))添加到PackageInterfaceMap中。如果查找到了HidlService對象,那麼僅僅將Client進程的pid保存到HidlService的mPassthroughClients變量中。
system\hwservicemanager\HidlService.h
-
HidlService(const std::string &interfaceName,
-
const std::string &instanceName)
-
: HidlService(
-
interfaceName,
-
instanceName,
-
nullptr,
-
static_cast<pid_t>(IServiceManager::PidConstant::NO_PID))
-
{}
因此registerPassthroughClient在hwservicemanager中插入一個HidlService對象而已,並沒有註冊對應的IBase對象。getService最後將HwcHal對象返回給registerPassthroughServiceImplementation()函數,然後再次調用registerAsService註冊該IBase對象。
registerAsService註冊
registerAsService用於向hwservicemanager註冊IBase對象,由於前面通過PassthroughServiceManager得到的HwcHal繼承於IBase,因此可以調用registerAsService函數來註冊。
composer\2.1\[email protected]_genc++\gen\android\hardware\graphics\composer\2.1\ComposerAll.cpp
-
::android::status_t IComposer::registerAsService(const std::string &serviceName) {
-
::android::hardware::details::onRegistration("[email protected]", "IComposer", serviceName);
-
const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
-
= ::android::hardware::defaultServiceManager();
-
if (sm == nullptr) {
-
return ::android::INVALID_OPERATION;
-
}
-
::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);
-
return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
-
}
首先執行onRegistration函數,然後調用hwservicemanager的代理對象的add函數。
system\libhidl\transport\ServiceManagement.cpp
-
void onRegistration(const std::string &packageName,
-
const std::string& /* interfaceName */,
-
const std::string& /* instanceName */) {
-
tryShortenProcessName(packageName);
-
}
-
void tryShortenProcessName(const std::string &packageName) {
-
std::string processName = binaryName();
-
if (!startsWith(processName, packageName)) {
-
return;
-
}
-
// e.x. [email protected] -> [email protected]
-
size_t lastDot = packageName.rfind('.');
-
size_t secondDot = packageName.rfind('.', lastDot - 1);
-
if (secondDot == std::string::npos) {
-
return;
-
}
-
std::string newName = processName.substr(secondDot + 1,
-
16 /* TASK_COMM_LEN */ - 1);
-
ALOGI("Removing namespace from process name %s to %s.",
-
processName.c_str(), newName.c_str());
-
int rc = pthread_setname_np(pthread_self(), newName.c_str());
-
ALOGI_IF(rc != 0, "Removing namespace from process name %s failed.",
-
processName.c_str());
-
}
這裏只是簡單的修改了當前進程的名稱。
[email protected]_genc++\gen\android\hidl\manager\1.0\ServiceManagerAll.cpp
-
::android::hardware::Return<bool> BpHwServiceManager::add(const ::android::hardware::hidl_string& name, const ::android::sp<::android::hidl::base::V1_0::IBase>& service){
-
::android::hardware::Return<bool> _hidl_out = ::android::hidl::manager::V1_0::BpHwServiceManager::_hidl_add(this, this, name, service);
-
return _hidl_out;
-
}
-
::android::hardware::Return<bool> BpHwServiceManager::_hidl_add(::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) {
-
#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::add::client");
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
_hidl_args.push_back((void *)&name);
-
_hidl_args.push_back((void *)&service);
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::CLIENT_API_ENTRY, "android.hidl.manager", "1.0", "IServiceManager", "add", &_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;
-
bool _hidl_out_success;
-
_hidl_err = _hidl_data.writeInterfaceToken(BpHwServiceManager::descriptor);
-
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; }
-
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;
-
}
-
}
-
if (_hidl_err != ::android::OK) { goto _hidl_error; }
-
::android::hardware::ProcessState::self()->startThreadPool();
-
_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(2 /* add */, _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; }
-
_hidl_err = _hidl_reply.readBool(&_hidl_out_success);
-
if (_hidl_err != ::android::OK) { goto _hidl_error; }
-
atrace_end(ATRACE_TAG_HAL);
-
#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.0", "IServiceManager", "add", &_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);
-
}
這裏的步驟和前面的registerPassthroughClient基本一致,唯一不同的是,此時需要向Server端hwservicemanager傳輸一個IBase對象。
-
::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);
-
}
這裏首先通過toBinder函數將IBase對象,其實就是HwcHal對象轉換爲IBinder對象,然後通過writeStrongBinder將IBinder對象序列化到Parcel中,toBinder函數在後續進行分析,我們這裏只需要知道經過toBinder函數後,在Hal進程端會創建一個BnHwComposer本地binder對象,然後通過IPC調用發送給hwservicemanager。
[email protected]_genc++\gen\android\hidl\manager\1.0\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 2 /* add */:
-
{
-
_hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_add(this, _hidl_data, _hidl_reply, _hidl_cb);
-
break;
-
}
-
default:
-
{
-
return ::android::hidl::base::V1_0::BnHwBase::onTransact(
-
_hidl_code, _hidl_data, _hidl_reply, _hidl_flags, _hidl_cb);
-
}
-
}
-
if (_hidl_err == ::android::UNEXPECTED_NULL) {
-
_hidl_err = ::android::hardware::writeToParcel(
-
::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),
-
_hidl_reply);
-
}return _hidl_err;
-
}
-
::android::status_t BnHwServiceManager::_hidl_add(
-
::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* name;
-
::android::sp<::android::hidl::base::V1_0::IBase> service;
-
size_t _hidl_name_parent;
-
_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; }
-
{
-
::android::sp<::android::hardware::IBinder> _hidl_service_binder;
-
_hidl_err = _hidl_data.readNullableStrongBinder(&_hidl_service_binder);
-
if (_hidl_err != ::android::OK) { return _hidl_err; }
-
service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_service_binder);
-
}
-
atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::add::server");
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
_hidl_args.push_back((void *)name);
-
_hidl_args.push_back((void *)&service);
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::SERVER_API_ENTRY, "android.hidl.manager", "1.0", "IServiceManager", "add", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
bool _hidl_out_success = static_cast<BnHwServiceManager*>(_hidl_this)->_hidl_mImpl->add(*name, service);
-
::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
-
_hidl_err = _hidl_reply->writeBool(_hidl_out_success);
-
/* _hidl_err ignored! */
-
atrace_end(ATRACE_TAG_HAL);
-
#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::SERVER_API_EXIT, "android.hidl.manager", "1.0", "IServiceManager", "add", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
_hidl_cb(*_hidl_reply);
-
return _hidl_err;
-
}
hwservicemanager進程通過_hidl_err = _hidl_data.readNullableStrongBinder(&_hidl_service_binder);拿到client進程發送過來的BnHwComposer對象,binder實體到達目的端進程將變爲binder代理對象,然後通過fromBinder函數將binder代理對象轉換爲業務代理對象BpHwBase,這個過程在後續進行詳細分析,接下來繼續調用_hidl_mImpl的add函數,而我們知道_hidl_mImpl其實就是ServiceManager:
system\hwservicemanager\ServiceManager.cpp
-
Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
-
bool isValidService = false;
-
if (service == nullptr) {
-
return false;
-
}
-
LOG(INFO) << "register service " << name;
-
// TODO(b/34235311): use HIDL way to determine this
-
// also, this assumes that the PID that is registering is the pid that is the service
-
pid_t pid = IPCThreadState::self()->getCallingPid();
-
auto ret = service->interfaceChain([&](const auto &interfaceChain) {
-
if (interfaceChain.size() == 0) {
-
return;
-
}
-
...
-
});
-
if (!ret.isOk()) {
-
LOG(ERROR) << "Failed to retrieve interface chain.";
-
return false;
-
}
-
return isValidService;
-
}
接着調用interfaceChain函數並傳入一個函數回調,由於此時service是BpHwBase對象,BpHwBase的interfaceChain函數實現如下:
[email protected]_genc++\gen\android\hidl\base\1.0\BaseAll.cpp
-
::android::hardware::Return<void> BpHwBase::interfaceChain(interfaceChain_cb _hidl_cb){
-
::android::hardware::Return<void> _hidl_out = ::android::hidl::base::V1_0::BpHwBase::_hidl_interfaceChain(this, this, _hidl_cb);
-
return _hidl_out;
-
}
-
::android::hardware::Return<void> BpHwBase::_hidl_interfaceChain(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, interfaceChain_cb _hidl_cb) {
-
#ifdef __ANDROID_DEBUGGABLE__
-
bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();
-
const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();
-
#else
-
(void) _hidl_this_instrumentor;
-
#endif // __ANDROID_DEBUGGABLE__
-
if (_hidl_cb == nullptr) {
-
return ::android::hardware::Status::fromExceptionCode(
-
::android::hardware::Status::EX_ILLEGAL_ARGUMENT,
-
"Null synchronous callback passed.");
-
}
-
atrace_begin(ATRACE_TAG_HAL, "HIDL::IBase::interfaceChain::client");
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::CLIENT_API_ENTRY, "android.hidl.base", "1.0", "IBase", "interfaceChain", &_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;
-
const ::android::hardware::hidl_vec<::android::hardware::hidl_string>* _hidl_out_descriptors;
-
_hidl_err = _hidl_data.writeInterfaceToken(BpHwBase::descriptor);
-
if (_hidl_err != ::android::OK) { goto _hidl_error; }
-
_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(256067662 /* interfaceChain */, _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; }
-
size_t _hidl__hidl_out_descriptors_parent;
-
_hidl_err = _hidl_reply.readBuffer(sizeof(*_hidl_out_descriptors), &_hidl__hidl_out_descriptors_parent, reinterpret_cast<const void **>(&_hidl_out_descriptors));
-
if (_hidl_err != ::android::OK) { goto _hidl_error; }
-
size_t _hidl__hidl_out_descriptors_child;
-
_hidl_err = ::android::hardware::readEmbeddedFromParcel(
-
const_cast<::android::hardware::hidl_vec<::android::hardware::hidl_string> &>(*_hidl_out_descriptors),
-
_hidl_reply,
-
_hidl__hidl_out_descriptors_parent,
-
0 /* parentOffset */, &_hidl__hidl_out_descriptors_child);
-
if (_hidl_err != ::android::OK) { goto _hidl_error; }
-
for (size_t _hidl_index_0 = 0; _hidl_index_0 < _hidl_out_descriptors->size(); ++_hidl_index_0) {
-
_hidl_err = ::android::hardware::readEmbeddedFromParcel(
-
const_cast<::android::hardware::hidl_string &>((*_hidl_out_descriptors)[_hidl_index_0]),
-
_hidl_reply,
-
_hidl__hidl_out_descriptors_child,
-
_hidl_index_0 * sizeof(::android::hardware::hidl_string));
-
if (_hidl_err != ::android::OK) { goto _hidl_error; }
-
}
-
_hidl_cb(*_hidl_out_descriptors);
-
atrace_end(ATRACE_TAG_HAL);
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
_hidl_args.push_back((void *)_hidl_out_descriptors);
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::CLIENT_API_EXIT, "android.hidl.base", "1.0", "IBase", "interfaceChain", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
_hidl_status.setFromStatusT(_hidl_err);
-
return ::android::hardware::Return<void>();
-
_hidl_error:
-
_hidl_status.setFromStatusT(_hidl_err);
-
return ::android::hardware::Return<void>(_hidl_status);
-
}
這裏再次回到Hal進程空間,調用BnHwComposer的interfaceChain函數查詢_hidl_out_descriptors,
然後調用傳遞進來的回調函數_hidl_cb。因此BnHwComposer的onTransact將接收請求:
composer\2.1\[email protected]_genc++\gen\android\hardware\graphics\composer\2.1\ComposerAll.cpp
-
::android::status_t BnHwComposer::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 256067662 /* interfaceChain */:
-
{
-
_hidl_err = ::android::hidl::base::V1_0::BnHwBase::_hidl_interfaceChain(this, _hidl_data, _hidl_reply, _hidl_cb);
-
break;
-
}
-
default:
-
{
-
return ::android::hidl::base::V1_0::BnHwBase::onTransact(
-
_hidl_code, _hidl_data, _hidl_reply, _hidl_flags, _hidl_cb);
-
}
-
}
-
if (_hidl_err == ::android::UNEXPECTED_NULL) {
-
_hidl_err = ::android::hardware::writeToParcel(
-
::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),
-
_hidl_reply);
-
}return _hidl_err;
-
}
注意,onTransact的最後一個參數是一個回調函數,是由IPCThreadState傳遞進來的,該回調函數將傳入BnHwBase的interfaceChain中執行。這個實現由其父類BnHwBase來完成:
[email protected]_genc++\gen\android\hidl\base\1.0\BaseAll.cpp
-
::android::status_t BnHwBase::_hidl_interfaceChain(
-
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(BnHwBase::Pure::descriptor)) {
-
_hidl_err = ::android::BAD_TYPE;
-
return _hidl_err;
-
}
-
atrace_begin(ATRACE_TAG_HAL, "HIDL::IBase::interfaceChain::server");
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::SERVER_API_ENTRY, "android.hidl.base", "1.0", "IBase", "interfaceChain", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
bool _hidl_callbackCalled = false;
-
static_cast<BnHwBase*>(_hidl_this)->_hidl_mImpl->interfaceChain([&](const auto &_hidl_out_descriptors) {
-
...
-
});
-
if (!_hidl_callbackCalled) {
-
LOG_ALWAYS_FATAL("interfaceChain: _hidl_cb not called, but must be called once.");
-
}
-
return _hidl_err;
-
}
BnHwBase的interfaceChain實現又轉交給_hidl_mImpl,同時也傳入一個匿名的回調函數,而BnHwBase的_hidl_mImpl保存的是HwcHal對象,HwcHal並沒有實現該函數,該函數由其父類IComposer類實現。
composer\2.1\[email protected]_genc++\gen\android\hardware\graphics\composer\2.1\ComposerAll.cpp
-
::android::hardware::Return<void> IComposer::interfaceChain(interfaceChain_cb _hidl_cb){
-
_hidl_cb({
-
IComposer::descriptor,
-
::android::hidl::base::V1_0::IBase::descriptor,
-
});
-
return ::android::hardware::Void();}
這裏只是回調由BnHwBase傳進來的回調函數,且函數參數是IComposer::descriptor, IBase::descriptor。回調函數實現如下:
-
{
-
if (_hidl_callbackCalled) {
-
LOG_ALWAYS_FATAL("interfaceChain: _hidl_cb called a second time, but must be called once.");
-
}
-
_hidl_callbackCalled = true;
-
::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
-
size_t _hidl__hidl_out_descriptors_parent;
-
_hidl_err = _hidl_reply->writeBuffer(&_hidl_out_descriptors, sizeof(_hidl_out_descriptors), &_hidl__hidl_out_descriptors_parent);
-
/* _hidl_err ignored! */
-
size_t _hidl__hidl_out_descriptors_child;
-
_hidl_err = ::android::hardware::writeEmbeddedToParcel(
-
_hidl_out_descriptors,
-
_hidl_reply,
-
_hidl__hidl_out_descriptors_parent,
-
0 /* parentOffset */, &_hidl__hidl_out_descriptors_child);
-
/* _hidl_err ignored! */
-
for (size_t _hidl_index_0 = 0; _hidl_index_0 < _hidl_out_descriptors.size(); ++_hidl_index_0) {
-
_hidl_err = ::android::hardware::writeEmbeddedToParcel(
-
_hidl_out_descriptors[_hidl_index_0],
-
_hidl_reply,
-
_hidl__hidl_out_descriptors_child,
-
_hidl_index_0 * sizeof(::android::hardware::hidl_string));
-
/* _hidl_err ignored! */
-
}
-
atrace_end(ATRACE_TAG_HAL);
-
#ifdef __ANDROID_DEBUGGABLE__
-
if (UNLIKELY(mEnableInstrumentation)) {
-
std::vector<void *> _hidl_args;
-
_hidl_args.push_back((void *)&_hidl_out_descriptors);
-
for (const auto &callback: mInstrumentationCallbacks) {
-
callback(InstrumentationEvent::SERVER_API_EXIT, "android.hidl.base", "1.0", "IBase", "interfaceChain", &_hidl_args);
-
}
-
}
-
#endif // __ANDROID_DEBUGGABLE__
-
_hidl_cb(*_hidl_reply);
-
}
這裏只是將回調函數的參數IComposer::descriptor,IBase::descriptor打包到Parcel對象中,然後繼續調用由IPCThreadState傳進入的回調函數,該回調實現如下:
system\libhwbinder\IPCThreadState.cpp
-
auto reply_callback = [&] (auto &replyParcel) {
-
if (reply_sent) {
-
// Reply was sent earlier, ignore it.
-
ALOGE("Dropping binder reply, it was sent already.");
-
return;
-
}
-
reply_sent = true;
-
if ((tr.flags & TF_ONE_WAY) == 0) {
-
replyParcel.setError(NO_ERROR);
-
sendReply(replyParcel, 0);
-
} else {
-
ALOGE("Not sending reply in one-way transaction");
-
}
-
};
該回調函數只是將打包後的Parcel發送給hwservicemanager進程。
也就是說,hwservicemanager將得到IComposer::descriptor,IBase::descriptor,BpHwBase讀取到這些數據後,接着會回調由ServiceManager傳入進來的回調函數:
system\hwservicemanager\ServiceManager.cpp
-
{
-
if (interfaceChain.size() == 0) {
-
return;
-
}
-
// First, verify you're allowed to add() the whole interface hierarchy
-
for(size_t i = 0; i < interfaceChain.size(); i++) {
-
std::string fqName = interfaceChain[i];
-
if (!mAcl.canAdd(fqName, pid)) {
-
return;
-
}
-
}
-
for(size_t i = 0; i < interfaceChain.size(); i++) {
-
std::string fqName = interfaceChain[i];
-
LOG(INFO) << "add service of " << fqName;
-
PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
-
HidlService *hidlService = ifaceMap.lookup(name);
-
if (hidlService == nullptr) {
-
LOG(INFO) << "insertService " << name << " of " << fgName ;
-
ifaceMap.insertService(
-
std::make_unique<HidlService>(fqName, name, service, pid));
-
} else {
-
if (hidlService->getService() != nullptr) {
-
auto ret = hidlService->getService()->unlinkToDeath(this);
-
ret.isOk(); // ignore
-
}
-
LOG(INFO) << "setService " << " of " << fgName ;
-
hidlService->setService(service, pid);
-
}
-
ifaceMap.sendPackageRegistrationNotification(fqName, name);
-
}
-
auto linkRet = service->linkToDeath(this, 0 /*cookie*/);
-
linkRet.isOk(); // ignore
-
isValidService = true;
-
}
該回調函數的參數值其實就是從Hal進程傳遞過來的IComposer::descriptor,IBase::descriptor,這時就開始完成服務註冊了,整個服務註冊過程分爲三個步驟:
1. 服務校驗過程
2. 服務添加過程
3. 死亡通知註冊過程
服務校驗
AccessControl類主要負責權限檢查,包括SELinux權限。
system\hwservicemanager\AccessControl.cpp
-
AccessControl::AccessControl() {
-
mSeHandle = selinux_android_hw_service_context_handle();
-
LOG_ALWAYS_FATAL_IF(mSeHandle == NULL, "Failed to acquire SELinux handle.");
-
if (getcon(&mSeContext) != 0) {
-
LOG_ALWAYS_FATAL("Failed to acquire hwservicemanager context.");
-
}
-
selinux_status_open(true);
-
mSeCallbacks.func_audit = AccessControl::auditCallback;
-
selinux_set_callback(SELINUX_CB_AUDIT, mSeCallbacks);
-
mSeCallbacks.func_log = selinux_log_callback; /* defined in libselinux */
-
selinux_set_callback(SELINUX_CB_LOG, mSeCallbacks);
-
}
判斷是否有權限添加過程如下:
-
bool AccessControl::canAdd(const std::string& fqName, pid_t pid) {
-
FQName fqIface(fqName);
-
if (!fqIface.isValid()) {
-
return false;
-
}
-
const std::string checkName = fqIface.package() + "::" + fqIface.name();
-
return checkPermission(pid, kPermissionAdd, checkName.c_str());
-
}
system\tools\hidl\utils\FQName.cpp
-
FQName::FQName(const std::vector<std::string> &names)
-
: mValid(false),
-
mIsIdentifier(false) {
-
setTo(StringHelper::JoinStrings(names, "."));
-
}
-
bool FQName::setTo(const std::string &s) {
-
clearVersion();
-
mPackage.clear();
-
mName.clear();
-
mValid = true;
-
std::smatch match;
-
if (std::regex_match(s, match, kRE1)) {
-
CHECK_EQ(match.size(), 5u);
-
mPackage = match.str(1);
-
parseVersion(match.str(2), match.str(3));
-
mName = match.str(4);
-
} else if (std::regex_match(s, match, kRE2)) {
-
CHECK_EQ(match.size(), 4u);
-
parseVersion(match.str(1), match.str(2));
-
mName = match.str(3);
-
} else if (std::regex_match(s, match, kRE3)) {
-
CHECK_EQ(match.size(), 4u);
-
mPackage = match.str(1);
-
parseVersion(match.str(2), match.str(3));
-
} else if (std::regex_match(s, match, kRE4)) {
-
mName = match.str(0);
-
} else if (std::regex_match(s, match, kRE5)) {
-
mIsIdentifier = true;
-
mName = match.str(0);
-
} else if (std::regex_match(s, match, kRE6)) {
-
CHECK_EQ(match.size(), 6u);
-
mPackage = match.str(1);
-
parseVersion(match.str(2), match.str(3));
-
mName = match.str(4);
-
mValueName = match.str(5);
-
} else if (std::regex_match(s, match, kRE7)) {
-
CHECK_EQ(match.size(), 5u);
-
parseVersion(match.str(1), match.str(2));
-
mName = match.str(3);
-
mValueName = match.str(4);
-
} else if (std::regex_match(s, match, kRE8)) {
-
CHECK_EQ(match.size(), 3u);
-
mName = match.str(1);
-
mValueName = match.str(2);
-
} else {
-
mValid = false;
-
}
-
// mValueName must go with mName.
-
CHECK(mValueName.empty() || !mName.empty());
-
// package without version is not allowed.
-
CHECK(mPackage.empty() || !version().empty());
-
return isValid();
-
}
setTo函數其實就是使用正則表達式從[email protected]::IServiceManager字符串中取出包名,版本號,及服務類名,從而檢查包名是否符合命名規則,如果包名有效,則繼續調用checkPermission函數來檢查selinux權限。
-
bool AccessControl::checkPermission(pid_t sourcePid, const char *targetContext,
-
const char *perm, const char *interface) {
-
char *sourceContext = NULL;
-
bool allowed = false;
-
struct audit_data ad;
-
if (getpidcon(sourcePid, &sourceContext) < 0) {
-
ALOGE("SELinux: failed to retrieved process context for pid %d", sourcePid);
-
return false;
-
}
-
ad.pid = sourcePid;
-
ad.interfaceName = interface;
-
allowed = (selinux_check_access(sourceContext, targetContext, "hwservice_manager",
-
perm, (void *) &ad) == 0);
-
freecon(sourceContext);
-
return allowed;
-
}
服務註冊
如果服務註冊進程有權限向hwservicemanager註冊服務,接下來將完成服務添加。
每個服務接口對應多個實例,比如[email protected]::IServiceManager可以註冊多個實例,每個實例名稱不同。
-
PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
-
HidlService *hidlService = ifaceMap.lookup(name);
-
const HidlService *ServiceManager::PackageInterfaceMap::lookup(
-
const std::string &name) const {
-
auto it = mInstanceMap.find(name);
-
if (it == mInstanceMap.end()) {
-
return nullptr;
-
}
-
return it->second.get();
-
}
根據名稱查找HidlService,如果找不到,則新增一個HidlService,如果已經存在,則更新service。
-
if (hidlService == nullptr) {
-
LOG(INFO) << "insertService " << name << " of " << fgName ;
-
ifaceMap.insertService(
-
std::make_unique<HidlService>(fqName, name, service, pid));
-
} else {
-
if (hidlService->getService() != nullptr) {
-
auto ret = hidlService->getService()->unlinkToDeath(this);
-
ret.isOk(); // ignore
-
}
-
LOG(INFO) << "setService " << " of " << fgName ;
-
hidlService->setService(service, pid);
-
}
到此就完成了hidl服務註冊。