Android O开始,Google为了将framework和HAL层分割开来,使得framework可以独立于HAL层更新,设计了HIDL。有了HIDL,HAL模块可以以一个独立的Service启动,framework可以通过Binder来和HAL模块进行通信,厂家实现的HAL模块将会被放到设备的/vendor目录下。
HIDL分为两种模式:Passthrough模式和Binderized模式。Passthrough模式是为了兼容Android O以前打开HAL的模式:首次调用该HAL接口时会调用hw_get_module打开HAL模块。但是Passthrough模式仅能用于C++层,Java层值能使用Binderized模式。而Binderized模式会启动一个Service进程,里面已经加载好HAL的so库,framework直接通过Binder和该HAL service通信。
系统定义的所有的.hal接口,都是通过hidl-gen工具转换成对应的代码。hidl-gen源码路径:system/tools/hidl,是在ubuntu上可执行的二进制文件。
使用方法(可执行文件位于源码的out/host/linux-x86/bin/hidl-gen):`
usage: ./host/linux-x86/bin/hidl-gen [-p ] -o
在Android的frameworks/hardware(对应包前缀android.frameworks.),hardware/interfaces(对应包前缀android.hardware.),system/libhidl(对应包前缀android.hidl.),system/hardware/interfaces(对应包前缀android.system.)目录下均放置有update-makefiles.sh脚本,执行这个脚本就会在上述目录下找到*.hal文件的位置,自动生成对应的mk(只在hardware/interfaces才生成)和bp文件。Google设计使用hidl-gen工具编译*.hal文件来自动生成对应的java,cpp,.h等文件,通过*.hal来描述所有的HIDL接口和类型。在对应的mk和bp文件可以看到具体的hidl-gen生成规则和输出路径。本文将以IBootControl.hal为例讲HIDL的框架,不再讨论这个HAL的具体功能。使用hidl-gen工具后,在out目录生成的文件主要有IBootControl.java(Java层对HIDL的封装),BpHwBootControl.h(Binder Bp端头文件),BnHwBootControl.h(Binder Bn端头文件),BsBootControl.h(Passthrough模式的封装),BootControlAll.cpp(包含Binder Bp端函数实现,Binder Bn端函数实现,BsBootControl部分函数实现还有IBootControl的getService实现等)。
可以看到*.hal文件的内容很简单,package指明了这个IBootControl.hal文件所属的包,interface声明了IBootControl.hal的接口。所有的IXXX.hal的接口均隐式继承自IBase.hal的接口,类比Java所有类都继承自java.lang.Object。IBase.hal包含了一些体现HAL接口共性的接口,类比Java所有的实例对象都能使用Obejct类的notify()方法。
IBootControl.hal和types.hal编译自动生成出来的cpp,.h等文件会被放到[email protected]里面,java文件会被放到android.hidl.base-V1.0-java.jar动态库和android.hardware.boot-V1.0-java-static静态库里面。这些so和jar会被放在设备的/system下面,然而default目录下service.cpp则被编译成[email protected],跟HAL具体实现的so一起被放在/vendor下。Bootcontol模块的目录结构如下:
├── 1.0
│ ├── Android.bp
│ ├── Android.mk
│ ├── default
│ │ ├── [email protected]
│ │ ├── Android.mk
│ │ ├── BootControl.cpp
│ │ ├── BootControl.h
│ │ └── service.cpp
│ ├── IBootControl.hal
│ ├── types.hal
│ └── vts
│ ├── Android.bp
│ ├── Android.mk
│ └── functional
│ ├── Android.bp
│ └── VtsHalBootV1_0TargetTest.cpp
└── Android.bp
hardware/interfaces/boot/1.0/IBootControl.hal
package [email protected];
/**
* The Boot Control HAL is designed to allow for managing sets of redundant
* partitions, called slots, that can be booted from independently. Slots
* are sets of partitions whose names differ only by a given suffix.
* They are identified here by a 0 indexed number and associated with their
* suffix, which is appended to the base name for any particular partition
* to find the one associated with that slot.
* The primary use of this set up is to allow for background updates while
* the device is running, and to provide a fallback in the event that the
* update fails.
*/
interface IBootControl {
/**
* getNumberSlots() returns the number of available slots.
* For instance, a system with a single set of partitions must return
* 1, a system with A/B must return 2, A/B/C -> 3 and so on. A system with
* less than two slots doesn't support background updates, for example if
* running from a virtual machine with only one copy of each partition for the
* purpose of testing.
*/
getNumberSlots() generates (uint32_t numSlots);
...
getSuffix(Slot slot) generates (string slotSuffix);
};
hardware/interfaces/boot/1.0/types.hal
package [email protected];
/**
* A command result encapsulating whether the command succeeded and
* an error string.
*/
struct CommandResult {
bool success;
string errMsg;
};
/**
* An identifier for a slot number.
*/
typedef uint32_t Slot;
/**
* A result encapsulating whether a function returned true, false or
* failed due to an invalid slot number
*/
enum BoolResult : int32_t {
FALSE = 0,
TRUE = 1,
INVALID_SLOT = -1
};
再看看同级目录下的Android.bp和Android.m k。
以types.hal和IBootControl.hal作为一个名为"[email protected]_hal"的filegroup,通过genrule定义的hidl-gen规则生成相应的文件。hidl-gen的-L参数为“c++source”时,生成的是cpp文件;-L参数为“c+±headers”时,生成的是头文件;-o参数为genDir的变量,一般位于./soong/.intermediates下面,根据编译出来的文件类型个模块所处的源码位置有所不同,例如IBootControl.h位于./soong/.intermediates/hardware/interfaces/boot/1.0/[email protected]_genc++_headers/gen/android/hardware/boot/1.0/IBootControl.h,BootControlAll.cpp位于./soong/.intermediates/hardware/interfaces/boot/1.0/[email protected]_genc++/gen/android/hardware/boot/1.0/BootControlAll.cpp,“hardware/interfaces/boot/1.0”这部分为源码的位置,“[email protected]_gencxxx”由模块的全限定名加生成文件类型确定,剩下的部分则可以参考genrule规则的out选项。
最后的cc_library选项将之前genrule产生的头文件和源文件编译成一个so。
Android.m k则用于编译出对应的Java动态库,静态库和Java文件,不再详细叙述。
hardware/interfaces/boot/1.0/Android.bp
// This file is autogenerated by hidl-gen. Do not edit manually.
filegroup {
name: "[email protected]_hal",
srcs: [
"types.hal",
"IBootControl.hal",
],
}
genrule {
name: "[email protected]_genc++",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport [email protected]",
srcs: [
":[email protected]_hal",
],
out: [
"android/hardware/boot/1.0/types.cpp",
"android/hardware/boot/1.0/BootControlAll.cpp",
],
}
genrule {
name: "[email protected]_genc++_headers",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport [email protected]",
srcs: [
":[email protected]_hal",
],
out: [
"android/hardware/boot/1.0/types.h",
"android/hardware/boot/1.0/hwtypes.h",
"android/hardware/boot/1.0/IBootControl.h",
"android/hardware/boot/1.0/IHwBootControl.h",
"android/hardware/boot/1.0/BnHwBootControl.h",
"android/hardware/boot/1.0/BpHwBootControl.h",
"android/hardware/boot/1.0/BsBootControl.h",
],
}
cc_library {
name: "[email protected]",
defaults: ["hidl-module-defaults"],
generated_sources: ["[email protected]_genc++"],
generated_headers: ["[email protected]_genc++_headers"],
export_generated_headers: ["[email protected]_genc++_headers"],
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
"libutils",
"libcutils",
],
export_shared_lib_headers: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"libutils",
],
}
在default文件夹下,有一个rc文件,用来启动HAL服务进程的:
hardware/interfaces/boot/1.0/default/[email protected]
service boot-hal-1-0 /vendor/bin/hw/[email protected]
class early_hal
user root
group root
再看看这个服务的来历。可以看到service.cpp被编译成[email protected],其main函数也是该服务的入口。
hardware/interfaces/boot/1.0/default
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := [email protected]
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SRC_FILES := \
BootControl.cpp \
LOCAL_SHARED_LIBRARIES := \
liblog \
libhidlbase \
libhidltransport \
libhardware \
libutils \
[email protected] \
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE := [email protected]
LOCAL_INIT_RC := [email protected]
LOCAL_SRC_FILES := \
service.cpp
LOCAL_SHARED_LIBRARIES := \
liblog \
libhardware \
libhidlbase \
libhidltransport \
libutils \
[email protected] \
include $(BUILD_EXECUTABLE)
启动服务:
hardware/interfaces/boot/1.0/default/service.cpp
int main (int /* argc */, char * /* argv */ []) {
return defaultPassthroughServiceImplementation();
}
首先是调用IBootControl::getService获取服务,这时候会首次加载底层HAL的so,然后调用IBootControl::registerAsService向HwServiceManager注册服务,这样,framework就可以通过Binder跟[email protected]这个厂商Service进程进行通信了。
system/libhidl/transport/include/hidl/LegacySupport.h
template
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(std::string name,
size_t maxThreads = 1) {
configureRpcThreadpool(maxThreads, true);
status_t result = registerPassthroughServiceImplementation(name);
if (result != OK) {
return result;
}
joinRpcThreadpool();
return 0;
}
system/libhidl/transport/include/hidl/LegacySupport.h
template
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
std::string name = "default") {
sp service = Interface::getService(name, true /* getStub */);
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);
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;
}
out/soong/.intermediates/hardware/interfaces/boot/1.0/[email protected]_genc++/gen/android/hardware/boot/1.0/BootControlAll.cpp
::android::status_t IBootControl::registerAsService(const std::string &serviceName) {
::android::hardware::details::onRegistration("[email protected]", "IBootControl", serviceName);
const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
= ::android::hardware::defaultServiceManager();
if (sm == nullptr) {
return ::android::INVALID_OPERATION;
}
::android::hardware::Return ret = sm->add(serviceName.c_str(), this);
return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
}
ProcessState::self()->getContextObject(NULL))会返回一个跟HwServiceManager的BpBinder,然后使用fromBinder将其转换为一个BpHwServiceManager对象。接着和以前AIDL的方式一样,调用IServiceManager::add添加服务。
HIDL框架有几个函数要注意一下:fromBinder接受一个Binder对象参数,如果该参数是Bp端的Binder对象,就会返回对应的BpHwXXXX对象;如果是Bn端的Binder对象,就会返回对应的BnHwXXXX对象的_hidl_mImpl成员。toBinder接受一个IXXXX接口对象参数,如果该参数是Bp端的Binder对象,就会返回内置的IBinder对象;如果是Bn端的Binder对象,’就返回对应的BnHwXXXX对象。可以看到,BpHwXXXX并不直接继承自IBinder,但是其拥有的mImpl成员就是一个IBinder对象。BnHwXXXX直接继承自IBinder,但是不继承自所有HAL节后的父类IBase,所以只能用IBase类型的_hidl_mImpl成员实现IXXXX接口。
system/libhidl/transport/ServiceManagement.cpp
sp defaultServiceManager() {
return defaultServiceManager1_1();
}
sp defaultServiceManager1_1() {
{
AutoMutex _l(details::gDefaultServiceManagerLock);
if (details::gDefaultServiceManager != NULL) {
return details::gDefaultServiceManager;
}
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;
}
waitForHwServiceManager();
while (details::gDefaultServiceManager == NULL) {
details::gDefaultServiceManager =
fromBinder(
ProcessState::self()->getContextObject(NULL));
if (details::gDefaultServiceManager == NULL) {
LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
sleep(1);
}
}
}
return details::gDefaultServiceManager;
}
在C++层,我们只需调用IXXX::getService便能获取到对应HAL的功能。
值得注意的是,我们在启动BootControl服务时调用IBootControl::getService的第二个参数getStub参数为true,这意味着启动BootControl的时候使用的是Passthrough模式,这既是启动HAL服务的函数被命名为defaultPassthroughServiceImplementation的原因。目测除了首次启动HAL服务,其他情况下
getStub参数都是false,例如应用程序获取HAL服务时。
out/soong/.intermediates/hardware/interfaces/boot/1.0/[email protected]_genc++/gen/android/hardware/boot/1.0/BootControlAll.cpp
// static
::android::sp IBootControl::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(IBootControl::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, IBootControl::descriptor, serviceName.c_str());
sleep(1);
}
if (vintfHwbinder && tries > 0) {
waitForHwService(IBootControl::descriptor, serviceName);
}
Return> ret =
sm->get(IBootControl::descriptor, serviceName);
if (!ret.isOk()) {
ALOGE("IBootControl: 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("IBootControl: found null hwbinder interface");
}continue;
}
Return> castRet = IBootControl::castFrom(base, true /* emitError */);
if (!castRet.isOk()) {
if (castRet.isDeadObject()) {
ALOGW("IBootControl: found dead hwbinder service");
continue;
} else {
ALOGW("IBootControl: cannot call into hwbinder service: %s; No permission? Check for selinux denials.", castRet.description().c_str());
break;
}
}
iface = castRet;
if (iface == nullptr) {
ALOGW("IBootControl: received incompatible service; bug in hwservicemanager?");
break;
}
return iface;
}
if (getStub || vintfPassthru || vintfLegacy) {
const sp<::android::hidl::manager::V1_0::IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
Return> ret =
pm->get(IBootControl::descriptor, serviceName);
if (ret.isOk()) {
sp<::android::hidl::base::V1_0::IBase> baseInterface = ret;
if (baseInterface != nullptr) {
iface = IBootControl::castFrom(baseInterface);
if (!getStub || trebleTestingOverride) {
iface = new BsBootControl(iface);
}
}
}
}
}
return iface;
}
defaultServiceManager返回一个BpHwServiceManager对象,getTransport会决定获取服务是通过Passthrough模式还是Binderized模式。getTransport接受两个参数,第一个是HAL服务的全限定名,本文中是[email protected]::IBootControl;第二个是instance名,通过先后匹配/system/manifest.xml和/vendor/manifest.xml来决定使用哪种方式。
manifest.xml的每一项如下所示。android.hardware.boot对应< name>项,1.0对应< version>项,IBootControl对应< interface>项里面的< name>项,启动服务的函数defaultPassthroughServiceImplementation的第一个参数,如果没有,默认参数为"default"。getTransport会按上述的项去寻找符合要求的项,根据< transport>的值决定返回值,其中hwbinder是Binderized模式,passthrough是PassThrough模式。
/system/manifest.xml
android.hardware.graphics.composer
hwbinder
2.1
IComposer
vr
回到IBootControl::getService函数。下面几个参数将决定走的是Binderized模式还是Passthrough模式:1.getStub参数,目前我看到只在首次启动服务时是true,在其他情况为false;2.vintfHwbinder在getTransport函数返回的是Binderized模式时为true;3.vintfPassthru在getTransport函数返回的是PassThrough模式为true;4.vintfLegacy在Android Treble架构下且未开启__ANDROID_DEBUGGABLE__宏时为false,即默认为false。下面情况均按vintfLegacy为false来说明。
当getStub参数为false且vintfHwbinder为true时,使用Binderized模式;当getStub参数为true或者vintfPassthru为true时,使用PassThrough模式。也就是说这个[email protected]服务时以PassThrough模式启动的,但是跟[email protected]服务通信时用的是Binderized模式。
可见PassThrough模式时通过PassthroughServiceManager进行的。
system/libhidl/transport/ServiceManagement.cpp
sp getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp getPassthroughServiceManager1_1() {
static sp manager(new PassthroughServiceManager());
return manager;
}
PassthroughServiceManager::get函数的任务是使用dlopen打开对应的*-impl的so库,本文中是[email protected],找到其中HIDL_FETCH_XXX函数执行并返回执行后的返回值,本文中是BootControl.cpp中的HIDL_FETCH_IBootControl函数。
system/libhidl/transport/ServiceManagement.cpp
struct PassthroughServiceManager : IServiceManager1_1 {
static void openLibs(const std::string& fqName,
std::function eachLib) {
//fqName looks like [email protected]::IFoo
size_t idx = fqName.find("::");
if (idx == std::string::npos ||
idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
return;
}
std::string packageAndVersion = fqName.substr(0, idx);
std::string ifaceName = fqName.substr(idx + strlen("::"));
const std::string prefix = packageAndVersion + "-impl";
const std::string sym = "HIDL_FETCH_" + ifaceName;
const int dlMode = RTLD_LAZY;
void *handle = nullptr;
dlerror(); // clear
std::vector paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
HAL_LIBRARY_PATH_VNDK_SP, HAL_LIBRARY_PATH_SYSTEM};
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
if (trebleTestingOverride) {
const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
if (vtsRootPath && strlen(vtsRootPath) > 0) {
const std::string halLibraryPathVtsOverride =
std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
paths.push_back(halLibraryPathVtsOverride);
}
}
#endif
for (const std::string& path : paths) {
std::vector libs = search(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
if (path != HAL_LIBRARY_PATH_SYSTEM) {
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
} else {
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;
}
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
Return> get(const hidl_string& fqName,
const hidl_string& name) override {
sp ret = nullptr;
openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
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);
return true;
}
ret = (*generator)(name.c_str());
if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}
registerReference(fqName, name);
return false;
});
return ret;
}
HIDL_FETCH_IBootControl的作用就是hw_get_module加载对应HAL的实现了,最后用一个BootControl对象封装好HAL的实现并将其返回。BootControl继承自IBootControl。IBootControl::getService在最后用该BootControl对象为参数构建一个BsBootControl返回。
hardware/interfaces/boot/1.0/default/BootControl.cpp
IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) {
int ret = 0;
boot_control_module_t* module = NULL;
hw_module_t **hwm = reinterpret_cast(&module);
ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast(hwm));
if (ret)
{
ALOGE("hw_get_module %s failed: %d", BOOT_CONTROL_HARDWARE_MODULE_ID, ret);
return nullptr;
}
module->init(module);
return new BootControl(module);
}
Binderized模式就是通过BpHwServiceManager::get来获取HAL服务。
out/soong/.intermediates/system/libhidl/transport/manager/1.1/[email protected]_genc++/gen/android/hidl/manager/1.1/ServiceManagerAll.cpp
::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;
}
在这里便可以看到明显的Binder框架了:Bp端的transact对应Bn端的onTransact,进而调用到BnHwServiceManager::_hidl_get。
out/soong/.intermediates/system/libhidl/transport/manager/1.1/[email protected]_genc++/gen/android/hidl/manager/1.1/ServiceManagerAll.cpp
// Methods from IServiceManager follow.
::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);
}
之前提到,BnHwXXXX的_hidl_mImpl为对应的IXXXX接口实现。BnHwServiceManager::_hidl_get调用了其_hidl_mImpl的get函数。
out/soong/.intermediates/system/libhidl/transport/manager/1.1/[email protected]_genc++/gen/android/hidl/manager/1.1/ServiceManagerAll.cpp
// Methods from IServiceManager follow.
::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的_hidl_mImpl来自ServiceManager,这个ServiceManager区别于Android O以前的ServiceManager,这是一个HAL服务。所有通过Binderized模式添加或者获取服务都是通过ServiceManager进行的。
system/hwservicemanager/service.cpp
int main() {
configureRpcThreadpool(1, true /* callerWillJoin */);
ServiceManager *manager = new ServiceManager();
if (!manager->add(serviceName, manager)) {
ALOGE("Failed to register hwservicemanager with itself.");
}
TokenManager *tokenManager = new TokenManager();
if (!manager->add(serviceName, tokenManager)) {
ALOGE("Failed to register ITokenManager with hwservicemanager.");
}
sp looper(Looper::prepare(0 /* opts */));
int binder_fd = -1;
IPCThreadState::self()->setupPolling(&binder_fd);
if (binder_fd < 0) {
ALOGE("Failed to aquire binder FD. Aborting...");
return -1;
}
// Flush after setupPolling(), to make sure the binder driver
// knows about this thread handling commands.
IPCThreadState::self()->flushCommands();
sp cb(new BinderCallback);
if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
nullptr) != 1) {
ALOGE("Failed to add hwbinder FD to Looper. Aborting...");
return -1;
}
// Tell IPCThreadState we're the service manager
sp service = new BnHwServiceManager(manager);
IPCThreadState::self()->setTheContextObject(service);
// Then tell binder kernel
ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);
// Only enable FIFO inheritance for hwbinder
// FIXME: remove define when in the kernel
#define BINDER_SET_INHERIT_FIFO_PRIO _IO('b', 10)
int rc = ioctl(binder_fd, BINDER_SET_INHERIT_FIFO_PRIO);
if (rc) {
ALOGE("BINDER_SET_INHERIT_FIFO_PRIO failed with error %d\n", rc);
}
rc = property_set("hwservicemanager.ready", "true");
if (rc) {
ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\
"HAL services will not start!\n", rc);
}
while (true) {
looper->pollAll(-1 /* timeoutMillis */);
}
return 0;
}
ServiceManager服务的添加和获取是通过内部的mServiceMap的map数据结构进行的,这个map键值为服务的全限定名,对应的是PackageInterfaceMap对象。其中PackageInterfaceMap又包含一个InstanceMap的map数据结构,其以服务的instance名为键值,对应的是HidlService对象。HidlService对象包含了IXXXX的实现,可以通过HidlService::getService函数获取。
所以,跟Android O以前的ServiceManager不同的是,以往的ServiceManager会将服务信息保存到内核中,而HAL的ServiceManager把HAL服务的信息保存在map数据结构中。
可以看到如果IBootControl::getService使用的是PassThrough模式,返回的是一个BsBootControl,也就是跟HAL服务位于同一进程,跟Android O之前的调用方式兼容;如果使用的是Binderized,返回的是一个BpHwBootControl,具备跨进程通信的能力。
system/hwservicemanager/ServiceManager.cpp
// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
Return> ServiceManager::get(const hidl_string& fqName,
const hidl_string& name) {
pid_t pid = IPCThreadState::self()->getCallingPid();
if (!mAcl.canGet(fqName, pid)) {
return nullptr;
}
auto ifaceIt = mServiceMap.find(fqName);
if (ifaceIt == mServiceMap.end()) {
return nullptr;
}
const PackageInterfaceMap &ifaceMap = ifaceIt->second;
const HidlService *hidlService = ifaceMap.lookup(name);
if (hidlService == nullptr) {
return nullptr;
}
return hidlService->getService();
}
Java层获取HAL服务是通过HwBinder#getService获取的。这是个native方法。
可以看到getTransport返回的不是Binderized模式时,便会抛出异常。而当getTransport返回的是Binderized模式时,在后续的流程就会走BpHwServiceManager::get函数。所以说,Java要使用HIDL的前提是这个HAL服务是使用Binderized模式的(PassThrough模式不支持Java)。
frameworks/base/core/jni/android_os_HwBinder.cpp
static jobject JHwBinder_native_getService(
JNIEnv *env,
jclass /* clazzObj */,
jstring ifaceNameObj,
jstring serviceNameObj) {
using ::android::hidl::base::V1_0::IBase;
using ::android::hidl::manager::V1_0::IServiceManager;
if (ifaceNameObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
return NULL;
}
if (serviceNameObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
return NULL;
}
auto manager = hardware::defaultServiceManager();
if (manager == nullptr) {
LOG(ERROR) << "Could not get hwservicemanager.";
signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
return NULL;
}
const char *ifaceNameCStr = env->GetStringUTFChars(ifaceNameObj, NULL);
if (ifaceNameCStr == NULL) {
return NULL; // XXX exception already pending?
}
std::string ifaceName(ifaceNameCStr);
env->ReleaseStringUTFChars(ifaceNameObj, ifaceNameCStr);
::android::hardware::hidl_string ifaceNameHStr;
ifaceNameHStr.setToExternal(ifaceName.c_str(), ifaceName.size());
const char *serviceNameCStr = env->GetStringUTFChars(serviceNameObj, NULL);
if (serviceNameCStr == NULL) {
return NULL; // XXX exception already pending?
}
std::string serviceName(serviceNameCStr);
env->ReleaseStringUTFChars(serviceNameObj, serviceNameCStr);
::android::hardware::hidl_string serviceNameHStr;
serviceNameHStr.setToExternal(serviceName.c_str(), serviceName.size());
LOG(INFO) << "Looking for service "
<< ifaceName
<< "/"
<< serviceName;
Return transportRet =
manager->getTransport(ifaceNameHStr, serviceNameHStr);
if (!transportRet.isOk()) {
signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
return NULL;
}
IServiceManager::Transport transport = transportRet;
#ifdef __ANDROID_TREBLE__
#ifdef __ANDROID_DEBUGGABLE__
const char* testingOverride = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY)
&& testingOverride && !strcmp(testingOverride, "true");
#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__
const bool vintfLegacy = false;
#endif // __ANDROID_DEBUGGABLE__
#else // not __ANDROID_TREBLE__
const bool vintfLegacy = (transport == IServiceManager::Transport::EMPTY);
#endif // __ANDROID_TREBLE__";
if (transport != IServiceManager::Transport::HWBINDER && !vintfLegacy) {
LOG(ERROR) << "service " << ifaceName << " declares transport method "
<< toString(transport) << " but framework expects hwbinder.";
signalExceptionForError(env, NAME_NOT_FOUND, true /* canThrowRemoteException */);
return NULL;
}
Return> ret = manager->get(ifaceNameHStr, serviceNameHStr);
if (!ret.isOk()) {
signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
return NULL;
}
sp service = hardware::toBinder(ret);
if (service == NULL) {
signalExceptionForError(env, NAME_NOT_FOUND);
return NULL;
}
LOG(INFO) << "Starting thread pool.";
::android::hardware::ProcessState::self()->startThreadPool();
return JHwRemoteBinder::NewObject(env, service);
}