# 整体框架
有的 HAL 模块有性能需求,调用它们不能太慢了,有的 hal 模块,是给当前进程提供某种功能,需要在当前进程下执行,跨进程通信的方式不能满足其需求。这类 HAL 以 so 库的形式存在,Framework 层会直接链接这些 so 库,以保证调用的性能。这类 Hal 称之为 Same-Process HALs,整体架构如下:
android.hardware.graphics.mapper
hal 模块就是一个 Same-Process HALs
其源码在 hardware/interfaces/graphics/mapper
目录下:
这里有三个版本,我们以 2.0 为基础来做分析(模拟器使用的是 2.0)
# HAL 层实现
我们从 hardware/interfaces/graphics/mapper/2.0/default/Android.bp
下手:
cc_library_shared {
name: "android.hardware.graphics.mapper@2.0-impl",
defaults: ["hidl_defaults"],
vendor: true,
relative_install_path: "hw",
srcs: ["passthrough.cpp"],
header_libs: [
"android.hardware.graphics.mapper@2.0-passthrough"
],
shared_libs: [
"android.hardware.graphics.mapper@2.0",
"libbase",
"libcutils",
"libhardware",
"libhidlbase",
"libhidltransport",
"liblog",
"libsync",
"libutils",
],
cflags: ["-DLOG_TAG=\"MapperHal\""],
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
区别于前面讲的 hal 都有一个可执行程序和 so 共享库,这里只有一个 so 共享库。
库对应的源码是:
// hardware/interfaces/graphics/mapper/2.0/default/passthrough.cpp
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <mapper-passthrough/2.0/GrallocLoader.h>
using android::hardware::graphics::mapper::V2_0::IMapper;
using android::hardware::graphics::mapper::V2_0::passthrough::GrallocLoader;
extern "C" IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
return GrallocLoader::load();
}
2
3
4
5
6
7
8
9
10
11
就一个函数 HIDL_FETCH_IMapper,具体实现我们等下来看。
我们接着看模拟器对应的 vintf 配置文件 device/generic/goldfish/manifest.xml
中配置了 mapper 的 vintf 信息:
<hal format="hidl">
<name>android.hardware.graphics.mapper</name>
<transport arch="32+64">passthrough</transport>
<version>2.0</version>
<interface>
<name>IMapper</name>
<instance>default</instance>
</interface>
</hal>
2
3
4
5
6
7
8
9
注意一下,这里 transport 类型是 passthrough。
# 谁来链接 hal 库
在 SurfaceFlinger 中,在分配图形缓存内存的过程中会构建一个 Gralloc2Mapper 对象:
// frameworks/native/libs/ui/Gralloc2.cpp
Gralloc2Mapper::Gralloc2Mapper() {
mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
if (mMapper == nullptr) {
ALOGW("mapper 2.x is not supported");
return;
}
if (mMapper->isRemote()) {
LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
}
// IMapper 2.1 is optional
mMapperV2_1 = IMapper::castFrom(mMapper);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
这里调用 getService 函数获取 mapper 服务。
getService 定义在 hidl 生成的代码 out/soong/.intermediates/hardware/interfaces/graphics/mapper/2.0/android.hardware.graphics.mapper@2.0_genc++_headers/gen/android/hardware/graphics/mapper/2.0/IMapper.h
static ::android::sp<IMapper> getService(const std::string &serviceName="default", bool getStub=false);
IMapper::getService 实现在 hidl 生成的代码 out/soong/.intermediates/hardware/interfaces/graphics/mapper/2.0/android.hardware.graphics.mapper@2.0_genc++/gen/android/hardware/graphics/mapper/2.0/MapperAll.cpp
中:
::android::sp<IMapper> IMapper::getService(const std::string &serviceName, const bool getStub) {
return ::android::hardware::details::getServiceInternal<BpHwMapper>(serviceName, true, getStub);
}
2
3
4
这里调用没传参数,就是使用默认参数 "default" 和 false。
接着调用 getServiceInternal
函数:
// system/libhidl/transport/include/hidl/HidlTransportSupport.h
template <typename BpType, typename IType = typename BpType::Pure,
typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;
sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
if (base == nullptr) {
return nullptr;
}
if (base->isRemote()) {
// getRawServiceInternal guarantees we get the proper class
return sp<IType>(new BpType(getOrCreateCachedBinder(base.get())));
}
return IType::castFrom(base);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
接着调用 getRawServiceInternal
:
// system/libhidl/transport/ServiceManagement.cpp
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
using ::android::hidl::manager::V1_0::IServiceManager;
sp<Waiter> waiter;
sp<IServiceManager1_1> sm;
Transport transport = Transport::EMPTY;
if (kIsRecovery) {
transport = Transport::PASSTHROUGH;
} else {
sm = defaultServiceManager1_1();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}
// passthrough
Return<Transport> transportRet = sm->getTransport(descriptor, instance);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s",
transportRet.description().c_str());
return nullptr;
}
transport = transportRet;
}
// false
const bool vintfHwbinder = (transport == Transport::HWBINDER);
// true
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
#ifdef ENFORCE_VINTF_MANIFEST
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
#else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
const bool trebleTestingOverride = false;
const bool vintfLegacy = false;
#endif // LIBHIDL_TARGET_DEBUGGABLE
#else // not ENFORCE_VINTF_MANIFEST
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY);
#endif // ENFORCE_VINTF_MANIFEST
// 不走这儿
for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
if (waiter == nullptr && tries > 0) {
waiter = new Waiter(descriptor, instance, sm);
}
if (waiter != nullptr) {
waiter->reset(); // don't reorder this -- see comments on reset()
}
Return<sp<IBase>> ret = sm->get(descriptor, instance);
if (!ret.isOk()) {
ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
ret.description().c_str(), descriptor.c_str(), instance.c_str());
break;
}
sp<IBase> base = ret;
if (base != nullptr) {
Return<bool> canCastRet =
details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
if (canCastRet.isOk() && canCastRet) {
if (waiter != nullptr) {
waiter->done();
}
return base; // still needs to be wrapped by Bp class.
}
if (!handleCastError(canCastRet, descriptor, instance)) break;
}
// In case of legacy or we were not asked to retry, don't.
if (vintfLegacy || !retry) break;
if (waiter != nullptr) {
ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
waiter->wait(true /* timeout */);
}
}
if (waiter != nullptr) {
waiter->done();
}
// 走这儿
if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
接着调用 getPassthroughServiceManager
:
// system/libhidl/transport/ServiceManagement.cpp
sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
return manager;
}
2
3
4
5
6
7
8
就是 new 一个 PassthroughServiceManager,PassthroughServiceManager 实现了 IServiceManager 接口。
接着调用 PassthroughServiceManager 的 get 函数:
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> 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
}
// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});
return ret;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
调用 openlib 并传入一个 lamda:
// fqName:android.hardware.graphics.mapper@2.0::IMapper
static void openLibs(
const std::string& fqName,
const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
const std::string& /* sym */)>& eachLib) {
//fqName looks like android.hardware.foo@1.0::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;
}
// android.hardware.graphics.mapper@2.0
std::string packageAndVersion = fqName.substr(0, idx);
// IMapper
std::string ifaceName = fqName.substr(idx + strlen("::"));
// android.hardware.graphics.mapper@2.0-impl
const std::string prefix = packageAndVersion + "-impl";
// HIDL_FETCH_IMapper
const std::string sym = "HIDL_FETCH_" + ifaceName;
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
static std::string halLibPathVndkSp = android::base::StringPrintf(
HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
// 从固定的几个目录查找 so 库
std::vector<std::string> paths = {
HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, halLibPathVndkSp,
#ifndef __ANDROID_VNDK__
HAL_LIBRARY_PATH_SYSTEM,
#endif
};
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
if (trebleTestingOverride) {
// Load HAL implementations that are statically linked
handle = dlopen(nullptr, dlMode);
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen self: "
<< (error == nullptr ? "unknown error" : error);
} else if (!eachLib(handle, "SELF", sym)) {
return;
}
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.insert(paths.begin(), halLibraryPathVtsOverride);
}
}
#endif
// 从固定的几个目录查找 android.hardware.graphics.mapper@2.0-impl.so 库
for (const std::string& path : paths) {
std::vector<std::string> libs = findFiles(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
// dlopen 打开 so 库
handle = dlopen(fullPath.c_str(), dlMode);
} else {
#if !defined(__ANDROID_RECOVERY__)
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
}
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;
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
再看 lamda 回调:
openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
IBase* (*generator)(const char* name);
// 加载 HIDL_FETCH_IVibrator 符号
*(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;
}
// 调用 HIDL_FETCH_IMapper 函数
ret = (*generator)(name.c_str());
if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}
// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
HIDL_FETCH_IMapper 函数实现在 hardware/interfaces/graphics/mapper/2.0/default/passthrough.cpp
:
extern "C" IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
return GrallocLoader::load();
}
2
3
这里接着调用 load 方法:
// hardware/interfaces/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
static IMapper* load() {
// 加载到 mmaper 传统 hal 的 hw_module_t
const hw_module_t* module = loadModule();
if (!module) {
return nullptr;
}
auto hal = createHal(module);
if (!hal) {
return nullptr;
}
return createMapper(std::move(hal));
}
2
3
4
5
6
7
8
9
10
11
12
13
调用 loadModule 加载传统 hal:
// hardware/interfaces/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
// 加载传统 hal
static const hw_module_t* loadModule() {
const hw_module_t* module;
int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
if (error) {
ALOGE("failed to get gralloc module");
return nullptr;
}
return module;
}
2
3
4
5
6
7
8
9
10
11
12
13
传统的 HAL 一般由芯片/厂商提供,比如 hardware/qcom/display/msm8909/libgralloc/gralloc.cpp
就是高通针对 msm8909
芯片提供的传统 mapper hal。
接着调用 createHal 创建一个 MapperHal 对象返回,MapperHal 就是对 hw_module_t
接口的包装。
static std::unique_ptr<hal::MapperHal> createHal(const hw_module_t* module) {
int major = getModuleMajorApiVersion(module);
switch (major) {
case 1: {
auto hal = std::make_unique<Gralloc1Hal>();
return hal->initWithModule(module) ? std::move(hal) : nullptr;
}
case 0: {
auto hal = std::make_unique<Gralloc0Hal>();
return hal->initWithModule(module) ? std::move(hal) : nullptr;
}
default:
ALOGE("unknown gralloc module major version %d", major);
return nullptr;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
接着调用 createMapper 创建一个 GrallocMapper 对象返回,GrallocMapper 实现了 IMapper 接口:
// hardware/interfaces/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
static IMapper* createMapper(std::unique_ptr<hal::MapperHal> hal) {
auto mapper = std::make_unique<GrallocMapper<hal::Mapper>>();
return mapper->init(std::move(hal)) ? mapper.release() : nullptr;
}
2
3
4
5
层层返回后,Gralloc2Mapper 中 getService 拿到的就是 GrallocMapper 对象,实际的功能调用是通过加载 so 库,调用具体符号实现的,并没有跨进程调用,减少调用 hal 过程的性能损耗。
// frameworks/native/libs/ui/Gralloc2.cpp
Gralloc2Mapper::Gralloc2Mapper() {
//拿到的是 GrallocMapper 对象
mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
if (mMapper == nullptr) {
ALOGW("mapper 2.x is not supported");
return;
}
if (mMapper->isRemote()) {
LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
}
// IMapper 2.1 is optional
mMapperV2_1 = IMapper::castFrom(mMapper);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15