前言
Android 14 Binderized HAL开发实战指南(AIDL版) 中介绍了如何创建一个自己的 AIDL Service。从 Android 11 开始,Google 引入了 Stable AIDL 来逐步替代 HIDL。到了 Android 14,越来越多的 HAL 模块已经迁移到 AIDL 接口。本文将详细分析 AIDL HAL Service 的注册流程。
AIDL HAL 的 Binder 框架
AIDL HAL 与 HIDL HAL 的核心区别在于:
- 统一 Binder 驱动 :AIDL HAL 使用
/dev/binder(或/dev/vndbinder),不再使用/dev/hwbinder - 统一 ServiceManager :AIDL HAL 注册到
servicemanager,而非hwservicemanager - NDK 后端 :推荐使用
libbinder_ndk,使用AServiceManager_addService()API - 标准 BBinder/BpBinder :不再使用 HIDL 专属的
BHwBinder/BpHwBinder
整体架构对比如下图所示:
AIDL HAL 架构 (Android 14)
BBinder
HAL Service 进程
/dev/vndbinder
或 /dev/binder
servicemanager
系统服务 + AIDL HAL
统一映射表
HIDL 架构 (Android ≤12)
BHwBinder
HAL Service 进程
/dev/hwbinder
hwservicemanager
HIDL 服务映射表
流程分析
下面以一个典型的 AIDL HAL Service(例如 android.hardware.vibrator)为例,分析 AIDL HAL 服务的注册流程。
注册流程
1. hardware/interfaces/<module>/aidl/default/service.cpp
首先看服务进程的入口。以下是一个典型的 AIDL HAL service.cpp 代码:
cpp
// hardware/interfaces/vibrator/aidl/default/service.cpp
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <aidl/android/hardware/vibrator/BnVibrator.h>
#include "Vibrator.h"
using aidl::android::hardware::vibrator::Vibrator;
using ndk::SharedRefBase;
int main() {
// 1. 配置 Binder 驱动为 vndbinder(vendor 分区使用)
ABinderProcess_setThreadPoolMaxThreadCount(0);
// 2. 创建服务实例
std::shared_ptr<Vibrator> vibrator = SharedRefBase::make<Vibrator>();
// 3. 获取描述符,拼接服务名
const std::string instance = std::string() + Vibrator::descriptor + "/default";
// 4. 注册服务到 ServiceManager
binder_status_t status =
AServiceManager_addService(vibrator->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
// 5. 加入线程池,等待客户端请求
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // 不应该走到这里
}
核心调用是 AServiceManager_addService(),它将服务实例注册到 ServiceManager 中。这个函数声明在 frameworks/native/libs/binder/ndk/include/binder_manager.h 中。
2. frameworks/native/libs/binder/ndk/binder_manager.cpp
cpp
// frameworks/native/libs/binder/ndk/binder_manager.cpp
binder_status_t AServiceManager_addService(AIBinder* binder, const char* instance_name) {
// 内部通过 libbinder IServiceManager AIDL 接口完成
sp<IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) {
return STATUS_UNEXPECTED_NULL;
}
// 将 AIBinder (NDK 层包装) 转为 sp<IBinder>
sp<IBinder> binderSp = sp<IBinder>::fromExisting(static_cast<BBinder*>(binder));
// 调用 BpServiceManager 的 addService
status_t status = sm->addService(String16(instance_name), binderSp, false);
if (status != OK) {
return STATUS_BAD_VALUE;
}
return STATUS_OK;
}
这里 defaultServiceManager() 返回的是 BpServiceManager 对象。IServiceManager 现在也用 AIDL 定义,在 Android 14 中路径为:
2.1 frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
java
// IServiceManager.aidl(简化)
interface IServiceManager {
void addService(in String name, in IBinder service, boolean allowIsolated, int dumpPriority);
@nullable IBinder getService(in String name);
@nullable IBinder checkService(in String name);
String[] listServices(int dumpPriority);
void registerForNotifications(in String name, in IServiceCallback callback);
void unregisterForNotifications(in String name, in IServiceCallback callback);
boolean isDeclared(in String name);
}
defaultServiceManager() 的实现仍然是经典模式:
cpp
// frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager() {
if (gDefaultServiceManager != nullptr) {
return gDefaultServiceManager;
}
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == nullptr) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(nullptr));
if (gDefaultServiceManager == nullptr) {
sleep(1);
}
}
}
return gDefaultServiceManager;
}
2.2 frameworks/native/libs/binder/ProcessState.cpp
cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) {
return getStrongProxyForHandle(0); // handle=0 对应 ServiceManager
}
getStrongProxyForHandle(0) 返回 BpBinder(0),handle=0 是 ServiceManager 在 Binder 驱动中的固定引用。
2.3 frameworks/native/libs/binder/BpBinder.cpp
cpp
BpBinder::BpBinder(int32_t handle)
: mHandle(handle), mAlive(1), mObitsSent(0), mObituaries(nullptr) {
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle, this);
}
defaultServiceManager() 返回的 gDefaultServiceManager 就是一个包装了 BpBinder(0) 的 BpServiceManager 代理对象。接着调用 sm->addService(),该方法进入 AIDL 自动生成的 BpServiceManager 代码。
3. out/soong/.intermediates/frameworks/native/libs/binder/.../IServiceManager.cpp
AIDL 生成的后端代码中,BpServiceManager::addService 大致如下:
cpp
::android::binder::Status BpServiceManager::addService(
const ::android::String16& name,
const ::android::sp<::android::IBinder>& service,
bool allowIsolated,
int32_t dumpPriority) {
::android::Parcel _data;
::android::Parcel _reply;
_data.writeInterfaceToken(IServiceManager::descriptor);
_data.writeString16(name);
_data.writeStrongBinder(service); // ★ 将服务对象写入 Parcel
_data.writeBool(allowIsolated);
_data.writeInt32(dumpPriority);
status_t _status = remote()->transact(BnServiceManager::TRANSACTION_addService,
_data, &_reply);
if (_status != ::android::OK) {
return ::android::binder::Status::fromStatusT(_status);
}
return ::android::binder::Status::fromStatusT(_reply.readInt32());
}
核心在于 _data.writeStrongBinder(service),它将 vibrator HAL 服务对象(BBinder 类型)写入 Parcel。
4. frameworks/native/libs/binder/Parcel.cpp
cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val) {
return flatten_binder(ProcessState::self(), val, this);
}
cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out) {
flat_binder_object obj;
if (binder != nullptr) {
BBinder *local = binder->localBinder(); // ★ 获取本地 BBinder
if (!local) {
// 远程代理 BpBinder,写入 handle
BpBinder *proxy = binder->remoteBinder();
const int32_t handle = proxy ? proxy->handle() : 0;
obj.hdr.type = BINDER_TYPE_HANDLE;
obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
obj.binder = 0;
obj.handle = handle;
obj.cookie = 0;
} else {
// ★ 本地 BBinder,写入 binder 指针和 cookie
obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
obj.hdr.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
} else {
obj.hdr.type = BINDER_TYPE_BINDER;
obj.binder = 0;
obj.cookie = 0;
}
return finish_flatten_binder(binder, obj, out);
}
对于 vibrator HAL 服务来说,binder 是本地 BBinder 对象(因为服务是 BnVibrator,继承自 BBinder)。因此走 else 分支:obj.hdr.type = BINDER_TYPE_BINDER,obj.cookie 指向 BBinder 对象本身。
5. frameworks/native/libs/binder/BpBinder.cpp --- transact
接着回到第 3 章中的 remote()->transact() 调用,remote() 返回 BpBinder(0)(handle=0 即 ServiceManager):
cpp
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
if (mAlive) {
status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
6. frameworks/native/libs/binder/IPCThreadState.cpp
cpp
status_t IPCThreadState::transact(int32_t handle, uint32_t code,
const Parcel& data, Parcel* reply, uint32_t flags) {
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
if (err == NO_ERROR) {
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
} else {
err = waitForResponse(nullptr, nullptr);
}
return err;
}
writeTransactionData 将命令和数据写入 mOut:
cpp
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) {
binder_transaction_data tr;
tr.target.ptr = 0;
tr.target.handle = handle; // handle = 0(ServiceManager)
tr.code = code; // TRANSACTION_addService
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount() * sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
mOut.writeInt32(cmd); // BC_TRANSACTION
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
最终通过 ioctl 写入 Binder 驱动:
cpp
status_t IPCThreadState::talkWithDriver(bool doReceive) {
binder_write_read bwr;
// ...
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
bwr.write_consumed = 0;
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
bwr.read_consumed = 0;
do {
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
} while (err == -EINTR);
return err;
}
7. drivers/android/binder.c(Binder 驱动)
驱动层的处理与原文类似,关键路径为:
binder_ioctl_write_read()
→ binder_thread_write() // 处理 BC_TRANSACTION
→ binder_transaction()
→ binder_translate_binder() // ★ 处理 BINDER_TYPE_BINDER
在 binder_translate_binder 中:
c
static int binder_translate_binder(struct flat_binder_object *fp,
struct binder_transaction *t,
struct binder_thread *thread) {
struct binder_node *node;
struct binder_ref *ref;
node = binder_get_node(proc, fp->binder, fp->cookie);
if (node == nullptr) {
node = binder_new_node(proc, fp); // ★ 为 HAL 服务创建 binder_node
}
// ★ 在目标进程(servicemanager)中创建引用
ret = binder_inc_ref_for_node(target_proc, node,
fp->hdr.type == BINDER_TYPE_BINDER,
&thread->todo, &rdata);
// ★ 类型从 BINDER_TYPE_BINDER 改为 BINDER_TYPE_HANDLE
if (fp->hdr.type == BINDER_TYPE_BINDER)
fp->hdr.type = BINDER_TYPE_HANDLE;
else
fp->hdr.type = BINDER_TYPE_WEAK_HANDLE;
fp->binder = 0;
fp->handle = rdata.desc; // ★ 分配 handle
fp->cookie = 0;
done:
binder_put_node(node);
return ret;
}
再看 binder_get_ref_for_node_olocked --- handle 的分配逻辑:
c
static struct binder_ref *binder_get_ref_for_node_olocked(
struct binder_proc *proc,
struct binder_node *node,
struct binder_ref *new_ref) {
// ...
// ★ 如果是 ServiceManager 自己,handle = 0;否则从 1 开始递增
new_ref->data.desc = (node == context->binder_context_mgr_node) ? 0 : 1;
for (n = rb_first(&proc->refs_by_desc); n != nullptr; n = rb_next(n)) {
ref = rb_entry(n, struct binder_ref, rb_node_desc);
if (ref->data.desc > new_ref->data.desc)
break;
new_ref->data.desc = ref->data.desc + 1;
}
// ...
}
关键点:
- 驱动中为 HAL 服务创建了
binder_node(表示服务端实体) - 在目标进程(servicemanager)中创建了
binder_ref引用 fp->hdr.type从BINDER_TYPE_BINDER改为BINDER_TYPE_HANDLE,并分配了 handle- 这样 servicemanager 拿到的是 handle,而非原始的 BBinder 指针
8. ServiceManager 收到 BR_TRANSACTION
驱动返回后,servicemanager 进程在 looper 中收到读事件,IPCThreadState 读取 BR_TRANSACTION 命令,然后回调 BBinder::transact(),最终通过 AIDL 生成的 BnServiceManager::onTransact 分发到:
9. frameworks/native/cmds/servicemanager/ServiceManager.cpp
cpp
// ServiceManager::addService(简化)
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder,
bool allowIsolated, int dumpPriority) {
// 检查 SELinux 权限
if (!multiuser_get_app_id(AIBinder_getCallingUid()).has_value()) {
return Status::fromExceptionCode(Status::EX_SECURITY);
}
// 检查是否在白名单中(VINTF 声明)
if (!mAcl->canAdd(Service::FQName::from(name), AIBinder_getCallingPid())) {
return Status::fromExceptionCode(Status::EX_SECURITY);
}
// ★ 将服务存入 map 中
auto entry = std::make_unique<Service>(binder);
mNameToService[name] = std::move(entry);
// 注册死亡通知
binder->linkToDeath(this);
return Status::ok();
}
至此,AIDL HAL Service 就成功注册到了 servicemanager 的 map 中。
注册流程图
servicemanager (ServiceManager.cpp) Binder 驱动 (binder.c) IPCThreadState Parcel (flatten_binder) BpServiceManager (AIDL 生成) libbinder_ndk (binder_manager.cpp) HAL Service 进程 (service.cpp) servicemanager (ServiceManager.cpp) Binder 驱动 (binder.c) IPCThreadState Parcel (flatten_binder) BpServiceManager (AIDL 生成) libbinder_ndk (binder_manager.cpp) HAL Service 进程 (service.cpp) 收到 BC_TRANSACTION handle=0 → servicemanager 向目标发送 BR_TRANSACTION 创建服务实例 SharedRefBase::make<Vibrator>() AServiceManager_addService( binder, "xxx/default") asBinder() → BBinder defaultServiceManager() → BpServiceManager(BpBinder(0)) writeStrongBinder(service) 本地 BBinder,type = BINDER_TYPE_BINDER remote()->>transact( TRANSACTION_addService, ...) writeTransactionData( BC_TRANSACTION, handle=0) ioctl(BINDER_WRITE_READ) binder_translate_binder() 创建 binder_node 分配 handle type: BINDER_TYPE_BINDER → BINDER_TYPE_HANDLE BR_TRANSACTION_COMPLETE (服务端收到回复) BR_TRANSACTION → BBinder::transact() BnServiceManager::onTransact() → addService() 检查 SELinux + VINTF 权限 map[name] = Service ★ 注册完成! BC_REPLY BR_REPLY → 注册成功返回
AIDL HAL vs HIDL HAL 注册流程对比
| 对比项 | HIDL HAL | AIDL HAL (Android 14) |
|---|---|---|
| Binder 设备 | /dev/hwbinder |
/dev/binder 或 /dev/vndbinder |
| 服务管理器 | hwservicemanager |
servicemanager(统一) |
| 注册函数 | service->registerAsService()(HIDL 生成) |
AServiceManager_addService()(NDK API) |
| Binder 基类 | BHwBinder / BpHwBinder |
BBinder / BpBinder(标准 Binder) |
| 接口定义语言 | .hal 文件 |
.aidl 文件 + @VintfStability 注解 |
| 服务实例创建 | new Usb()(C++ sp) |
SharedRefBase::make<T>()(NDK shared_ptr) |
| 线程池 API | configureRpcThreadpool() / joinRpcThreadpool() |
ABinderProcess_setThreadPoolMaxThreadCount() / ABinderProcess_joinThreadPool() |
| VINTF 绑定 | 需要 manifest.xml 声明 |
需要 manifest.xml 声明 + VINTF 稳定性冻结 |
总结
AIDL HAL Service 的注册流程核心路径为:
service.cpp
→ AServiceManager_addService() # NDK Binder API
→ defaultServiceManager() # 获取 BpBinder(0)
→ BpServiceManager::addService() # AIDL 生成
→ Parcel::writeStrongBinder() # BBinder → flat_binder_object
→ BpBinder(0)::transact() # 向 handle=0 发送
→ IPCThreadState::transact() # BC_TRANSACTION
→ ioctl(BINDER_WRITE_READ) # 进入驱动
→ binder_translate_binder() # type: BINDER → HANDLE, 分配 handle
→ ServiceManager::addService() # 存入 map
相比 HIDL 的 hwservicemanager,AIDL HAL 回归到了统一的 servicemanager,使用标准的 Binder 机制。这种统一化减少了代码维护成本,也让 HAL 开发与 Android Framework 开发使用同一套 IPC 语言和工具链。