Android 14 AIDL HAL 使用指南-注册服务流程解析

前言

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_BINDERobj.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.typeBINDER_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 语言和工具链。

相关推荐
阿亮爱学代码5 天前
Service
运维·服务器·service·aidl·跨进程通信
哈哈,柳暗花明5 天前
Framework开发专题系列四:Binder基础
framework·binder·aidl·messenger·hidl·native binder·asyncchannel
小书房1 个月前
Android Binder机制
binder·aidl
【 STM32开发 】2 个月前
【STM32 + CubeMX 教程】RTC 实时时钟 之 日历 -- F407篇
stm32·cubemx·rtc·hal·实时时钟·f407
星马梦缘3 个月前
驱动层开发——蜂鸣器驱动
stm32·单片机·嵌入式硬件·hal·驱动
【 STM32开发 】3 个月前
【STM32 + CubeMX】 CAN 通信
stm32·cubemx·can·hal·通信·f407
henysugar3 个月前
Android studio编译aidl若干问题记录
android·ide·android studio·aidl
似霰4 个月前
AIDL Hal 开发笔记7----AIDL HAL 的升级
android·framework·hal
似霰4 个月前
AIDL Hal 开发笔记5----实现AIDL HAL
android·framework·hal