Android 14 AIDL HAL 使用指南-获取服务流程解析

前言

接上篇 Android 14 AIDL HAL 使用指南-注册服务流程解析 讲了 AIDL HAL 服务的注册流程,这篇文章接着解析 AIDL HAL 服务的获取流程。

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_getService() API
  • 标准 BBinder/BpBinder:不再使用 HIDL 专属的 BHwBinder/BpHwBinder

整体获取流程的架构如下图所示:

┌─────────────────────────────────────────────────────────┐
│                Client (Framework / VTS / App)            │
│  AServiceManager_getService("xxx.IUsb/default")         │
│           → AIBinder* → fromBinder() → shared_ptr<IUsb> │
└──────────────────────┬──────────────────────────────────┘
                       │ BpBinder(0).transact(getService)
┌──────────────────────▼──────────────────────────────────┐
│              /dev/vndbinder (或 /dev/binder)              │
└──────────────────────┬──────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────┐
│                  servicemanager                          │
│          mNameToService["xxx.IUsb/default"]              │
│                 → IBinder (服务端的引用)                   │
└──────────────────────┬──────────────────────────────────┘
                       │ 返回 BpBinder(handle → HAL 进程)
┌──────────────────────▼──────────────────────────────────┐
│            Client 拿到 BpBinder → 封装为 BpUsb           │
│              调用接口方法 → 透明 IPC                      │
└─────────────────────────────────────────────────────────┘

流程分析

废话不多说,继续以 USB HAL 为例(AIDL 版本),解析一下客户端获取服务的流程。

注意:与 HIDL 不同,AIDL NDK 生成的 IUsb.h 不包含 getService() 静态方法。客户端需要手动组合 AServiceManager_getService + fromBinder 两步。

获取流程

1. 客户端入口代码

以 VTS 测试为参考,客户端获取服务的典型代码:

// 使用 NDK 后端获取 AIDL HAL 服务
#include <android/binder_manager.h>
#include <aidl/android/hardware/usb/IUsb.h>

using ::aidl::android::hardware::usb::IUsb;
using ::ndk::SpAIBinder;

// 第一步:通过 ServiceManager 拿到 AIBinder*
AIBinder* aiBinder = AServiceManager_getService("android.hardware.usb.IUsb/default");

if (aiBinder == nullptr) {
    ALOGE("Failed to get USB HAL service");
    return;
}

// 第二步:将 AIBinder* 转换为类型安全的接口指针
std::shared_ptr<IUsb> usb = IUsb::fromBinder(SpAIBinder(aiBinder));

AServiceManager_getService 声明在 frameworks/native/libs/binder/ndk/include/android/binder_manager.h

/**
 * 根据实例名获取服务。
 * 如果服务未注册,返回 nullptr。
 *
 * @param instance 服务实例名,如 "android.hardware.usb.IUsb/default"
 * @return AIBinder*,失败或不存在时返回 nullptr
 */
AIBinder* AServiceManager_getService(const char* instance);

与 HIDL 的区别:HIDL 生成代码自带 IUsb::getService("default"),内部调用 getServiceInternal<BpHwUsb>()。AIDL NDK 不再生成这个便捷方法,调用方直接使用 AServiceManager_getService,签名是直接返回 AIBinder*(nullptr 表示失败),非常简洁。

2. frameworks/native/libs/binder/ndk/binder_manager.cpp

AServiceManager_getService 的实现:

AIBinder* AServiceManager_getService(const char* instance) {
    if (instance == nullptr) {
        return nullptr;
    }

    // 1. 获取 servicemanager 的 BpBinder
    sp<IServiceManager> sm = defaultServiceManager();
    if (sm == nullptr) {
        return nullptr;
    }

    // 2. 通过 BpServiceManager 查找服务
    sp<IBinder> binder = sm->checkService(String16(instance));
    if (binder == nullptr) {
        binder = sm->getService(String16(instance));
    }

    // 3. 将 sp<IBinder> 转换为 NDK 的 AIBinder*
    if (binder != nullptr) {
        return AIBinder_fromPlatformBinder(binder);
    }
    return nullptr;
}

核心调用是 defaultServiceManager(),实现仍然在 frameworks/native/libs/binder/IServiceManager.cpp

3. 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;
}

这段代码与 HIDL 时代的逻辑完全一致:获取 handle=0 的 BpBinder,包装成 BpServiceManager 代理对象。唯一的区别是——这里的 IServiceManager 现在也是用 AIDL 定义的。

3.1 IServiceManager 的 AIDL 接口

路径:frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl

interface IServiceManager {
    @nullable IBinder getService(in String name);
    @nullable IBinder checkService(in String name);
    void addService(in String name, in IBinder service, boolean allowIsolated, int dumpPriority);
    String[] listServices(int dumpPriority);
    void registerForNotifications(in String name, in IServiceCallback callback);
    // ...
}
4. frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) {
    return getStrongProxyForHandle(0);  // handle=0 → servicemanager
}

getStrongProxyForHandle(0) 返回 BpBinder(0),handle=0 是 servicemanager 在 Binder 驱动中的固定句柄。

4.1 frameworks/native/libs/binder/BpBinder.cpp
BpBinder::BpBinder(int32_t handle)
    : mHandle(handle), mAlive(1), mObitsSent(0), mObituaries(nullptr) {
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    IPCThreadState::self()->incWeakHandle(handle, this);
}

与 HIDL 的对比:HIDL 时代 getContextObject(nullptr) 拿到的是 BpHwBinder(0),对应 hwservicemanager。AIDL HAL 统一使用 BpBinder(0),对应 servicemanager。去掉了 Hw 前缀,本质回归到了标准 Binder。

5. ServiceManagerShim — checkService 与 getService

defaultServiceManager() 返回的实际上是 ServiceManagerShim(封装了 AIDL 版的 IServiceManager)。

回到第二节,sm->checkService(instance) 的调用链:

// ServiceManagerShim::checkService
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const {
    // 通过 AIDL 生成的 BpServiceManager 发起 binder 调用
    std::string serviceName = String8(name).string();
    sp<IBinder> outBinder;
    auto status = mServiceManager->checkService(serviceName.c_str(), &outBinder);
    if (status.isOk() && outBinder != nullptr) {
        return outBinder;
    }
    return nullptr;
}

如果 checkService 没有找到,还会走 getService(带重试):

sp<IBinder> ServiceManagerShim::getService(const String16& name) const {
    sp<IBinder> svc = checkService(name);
    if (svc != nullptr) return svc;

    const bool isVendorService =
        strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;

    // 重试循环,最多等 5 秒
    int64_t startTime = uptimeMillis();
    while (uptimeMillis() - startTime < 5000) {
        usleep(isVendorService ? 100000 : 1000000);  // vendor 100ms, 系统 1000ms

        sp<IBinder> ret = checkService(name);
        if (ret != nullptr) return ret;
    }
    return nullptr;
}
6. AIDL 生成的 BpServiceManager — transact

mServiceManager->checkService(...) 最终走到 AIDL 生成的 BpServiceManager 代码:

// out/soong/.intermediates/frameworks/native/libs/binder/.../IServiceManager.cpp
::android::binder::Status BpServiceManager::checkService(
        const std::string& name, ::android::sp<::android::IBinder>* _aidl_return) {
    ::android::Parcel _data;
    ::android::Parcel _reply;
    
    _data.writeInterfaceToken(IServiceManager::descriptor);
    _data.writeUtf8AsUtf16(name);
    
    // ★ 向 handle=0 (servicemanager) 发起 transact
    status_t _status = remote()->transact(
        BnServiceManager::TRANSACTION_checkService, _data, &_reply);
    
    if (_status != ::android::OK) {
        return ::android::binder::Status::fromStatusT(_status);
    }
    
    // ★ 从 reply 中读取返回的 IBinder
    _reply.readStrongBinder(_aidl_return);
    return ::android::binder::Status::ok();
}
7. frameworks/native/libs/binder/BpBinder.cpp — transact

remote() 返回 BpBinder(0)(handle=0 即 servicemanager):

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;
}
8. frameworks/native/libs/binder/IPCThreadState.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);  // ★ 阻塞等待 servicemanager 回复
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
    } else {
        err = waitForResponse(nullptr, nullptr);
    }
    return err;
}

writeTransactionDataBC_TRANSACTION 命令写入 mOut

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_checkService
    tr.flags = binderFlags;
    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 驱动:

status_t IPCThreadState::talkWithDriver(bool doReceive) {
    binder_write_read bwr;
    // ...
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();
    bwr.read_size = mIn.dataCapacity();
    bwr.read_buffer = (uintptr_t)mIn.data();

    do {
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
    } while (err == -EINTR);

    return err;
}
9. Binder 驱动处理

驱动收到 BC_TRANSACTION,目标 handle=0 即 servicemanager。驱动找到 servicemanager 进程的 binder_proc,将事务放入其 todo 队列。

servicemanager 进程在 looper 中收到 BR_TRANSACTION,回调 BBinder::transact(),再通过 AIDL 生成的 BnServiceManager::onTransact() 分发:

10. frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
    // 1. 权限检查:调用方是否有权限查询
    pid_t pid = IPCThreadState::self()->getCallingPid();
    if (!mAcl->canFind(name, pid)) {
        return Status::fromExceptionCode(Status::EX_SECURITY);
    }

    // 2. ★ 在注册表中查找
    auto it = mNameToService.find(name);
    if (it == mNameToService.end()) {
        *outBinder = nullptr;
        return Status::ok();
    }

    // 3. ★ 返回之前 addService 存进去的 IBinder 引用
    *outBinder = it->second.binder;
    return Status::ok();
}

与 HIDL 的对比:HIDL 的 hwservicemanager 使用嵌套 map(mServiceMap[fqName] → PackageInterfaceMap → HidlService),还需要先调用 getTransport 从 VINTF manifest 查传输方式。AIDL HAL 直接使用扁平 mNameToService,key 是完整的 "android.hardware.usb.IUsb/default",一步到位。

11. 返回路径:Binder 驱动把引用传回客户端

servicemanager 返回的 IBinder 在驱动中对应一个 binder_ref,驱动会将这个 ref 转换为客户端进程中的 handle,并把 BINDER_TYPE_HANDLE 写入 reply parcel。

客户端的 waitForResponse(reply) 收到 BR_REPLY,从 reply 中读出 handle:

// 回到步骤 6 的 BpServiceManager::checkService
_reply.readStrongBinder(_aidl_return);  // 根据 handle 创建 BpBinder

readStrongBinder 内部会调用 ProcessState::getStrongProxyForHandle(handle),创建一个指向 HAL 服务进程的 BpBinder

12. 回到客户端:BpBinder 转类型安全接口

回到步骤 1 的客户端代码:

AIBinder* aiBinder = AServiceManager_getService("android.hardware.usb.IUsb/default");
std::shared_ptr<IUsb> usb = IUsb::fromBinder(SpAIBinder(aiBinder));

fromBinder 是 AIDL NDK 生成的代码,将 AIBinder* 包装为 BpUsbIUsb 的 Binder 代理实现):

// 生成的代码
std::shared_ptr<IUsb> IUsb::fromBinder(const SpAIBinder& binder) {
    if (binder.get() == nullptr) return nullptr;
    return std::make_shared<BpUsb>(binder);
}

至此,客户端拿到了 BpUsb 对象,之后调用 usb->openDevice(...) 等方法时,BpUsb 内部会自动将调用序列化为 Binder 事务,发给 HAL 服务进程。

获取流程图

servicemanager          Binder 驱动            IPCThreadState         客户端 (Client)
(ServiceManager.cpp)    (binder.c)             (libbinder)            (binder_manager.cpp
                                                                      + IUsb::fromBinder)
     │                       │                      │                       │
     │                       │                      │  AServiceManager_     │
     │                       │                      │  getService(          │
     │                       │                      │  "xxx.IUsb/default")  │
     │                       │                      │       │               │
     │                       │                      │  defaultServiceManager│
     │                       │                      │  → BpServiceManager   │
     │                       │                      │    (BpBinder(0))      │
     │                       │                      │       │               │
     │                       │                      │  checkService(name)   │
     │                       │                      │       │               │
     │                       │    BC_TRANSACTION    │       │               │
     │                       │   handle=0, code=   ─┼───────┘               │
     │                       │   TRANSACTION_       │                       │
     │                       │   checkService       │                       │
     │                       │◄─────────────────────│                       │
     │                       │                      │                       │
     │                       │   BR_TRANSACTION     │                       │
     │   BBinder::transact() │──────────────────────│                       │
     │◄──────────────────────│                      │                       │
     │                       │                      │                       │
     │ mNameToService[name]  │                      │                       │
     │ → IBinder (HAL 服务的 │                      │                       │
     │   binder_ref)         │                      │                       │
     │                       │                      │                       │
     │   BC_REPLY            │                      │                       │
     │   (含 BINDER_TYPE_   ──────────────────────►│                       │
     │    HANDLE, handle=X)  │                      │                       │
     │                       │                      │  BR_REPLY             │
     │                       │                      │  → readStrongBinder   │
     │                       │                      │  → BpBinder(X)        │
     │                       │                      │       │               │
     │                       │                      │  AIBinder_fromPlatform│
     │                       │                      │  Binder → AIBinder*   │
     │                       │                      │       │               │
     │                       │                      │  IUsb::fromBinder()   │
     │                       │                      │  → BpUsb(binder)      │
     │                       │                      │       │               │
     │                       │                      │  ★ 获取完成!          │
     │                       │                      │       │               │
     ▼                       ▼                      ▼       ▼               ▼

AIDL HAL vs HIDL HAL 获取流程对比

对比项 HIDL HAL (Android 9) AIDL HAL (Android 14)
入口函数 IUsb::getService("default")(HIDL 生成) AServiceManager_getService("xxx.IUsb/default")(NDK API)
SM 获取 defaultServiceManager1_1()BpHwServiceManager defaultServiceManager()BpServiceManager
Binder 设备 /dev/hwbinder /dev/binder/dev/vndbinder
Binder 基类 BHwBinder / BpHwBinder BBinder / BpBinder(标准 Binder)
服务管理器 hwservicemanager(独立进程) servicemanager(统一进程)
Transport 查询 需要:sm->getTransport() → manifest.xml 不需要,直接查 mNameToService
服务查找 mServiceMap[fqName].lookup(instance) 两层 map mNameToService.find(name) 扁平 map
代理对象 BpHwUsbBpType 模板参数) BpUsbfromBinder 生成)
智能指针 android::sp<T> std::shared_ptr<T>(NDK)
生成代码含 getService ✅ 是 ❌ 否,需手动组合
重试机制 Waiter 类 + sm->get() 循环 ServiceManagerShim::getService() while + usleep

关键源码文件索引

文件 作用
frameworks/native/libs/binder/ndk/include/android/binder_manager.h AServiceManager_getService 声明
frameworks/native/libs/binder/ndk/binder_manager.cpp AServiceManager_getService 实现
frameworks/native/libs/binder/IServiceManager.cpp defaultServiceManager()ServiceManagerShim
frameworks/native/libs/binder/ProcessState.cpp getContextObject(nullptr) → handle=0
frameworks/native/libs/binder/BpBinder.cpp BpBinder 构造函数、transact
frameworks/native/libs/binder/IPCThreadState.cpp transactwriteTransactionDatatalkWithDriver
frameworks/native/cmds/servicemanager/ServiceManager.cpp checkService 服务端实现
frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl IServiceManager 的 AIDL 接口定义
out/soong/.intermediates/.../IServiceManager.cpp AIDL 生成的 BpServiceManager / BnServiceManager

总结

AIDL HAL Service 的获取流程核心路径为:

Client
  → AServiceManager_getService("android.hardware.usb.IUsb/default")   # NDK Binder API
  → defaultServiceManager()                                            # 获取 BpBinder(0)
  → ServiceManagerShim::checkService() / getService()                 # 查找服务
  → BpServiceManager::checkService()                                  # AIDL 生成
  → BpBinder(0)::transact(TRANSACTION_checkService)                  # 向 handle=0 发送
  → IPCThreadState::transact()                                        # BC_TRANSACTION
  → ioctl(BINDER_WRITE_READ)                                          # 进入驱动
  → servicemanager 收到 BR_TRANSACTION                                # 回调 BBinder::transact
  → BnServiceManager::onTransact()                                    # AIDL 分发
  → ServiceManager::checkService(name)                                # mNameToService.find()
  → 返回 IBinder (HAL 服务的 binder_ref)                              # BC_REPLY
  → Client 收到 BR_REPLY                                              # readStrongBinder
  → IUsb::fromBinder(SpAIBinder(aiBinder))                            # BpBinder → BpUsb

相比 HIDL 的获取流程,AIDL HAL 的获取流程有以下显著简化:

  1. 不再需要 getTransport 查询:HIDL 需要先通过 VINTF manifest 确定 transport 类型(HWBINDER/PASSTHROUGH),AIDL HAL 统一走 /dev/vndbinder,直接查表即可;
  2. 不再使用 hwservicemanager:AIDL HAL 服务注册到统一的 servicemanager,与系统服务共用同一套管理机制;
  3. 不再使用 BHwBinder/BpHwBinder:回归标准 BBinder/BpBinder,去掉了 HIDL 专属的 Binder 派生子类;
  4. 服务名扁平化"android.hardware.usb.IUsb/default" 一个字符串搞定,代替了 HIDL 的 fqName + instance 两层嵌套查询;
  5. 生成代码不含 getService:AIDL NDK 生成的接口类只有 descriptorfromBinder,客户端通过 AServiceManager_getService 直接获取 AIBinder*,调用链更短、更显式;
  6. 统一 C++ 内存模型:NDK 后端使用 std::shared_ptr,与标准 C++ 生态对接更自然。

整体来看,AIDL HAL 获取流程更加简洁、扁平,这也是 Google 坚定推进 AIDL 化的重要原因之一。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐