王锐
王锐
发布于 2026-09-13 / 1 阅读
0
0

AOSP源码方式实现一个aidl服务

创建一个aidl demo工程

创建的目录结构如下:

root@2f9414cb61fd:/aosp/packages/modules/DemoAidl# tree
.
|-- Android.bp
|-- aidl
|   `-- com
|       `-- example
|           `-- demo
|               |-- IDemo.aidl
|               `-- IDemoCallback.aidl
|-- client
|   `-- main.cpp
|-- demo_service.rc
`-- service
    |-- DemoService.cpp
    |-- DemoService.h
    `-- main.cpp

IDemo.aidl内容如下:

package com.example.demo;

import com.example.demo.IDemoCallback;

interface IDemo {

    int add(int a, int b);

    void registerCallback(IDemoCallback callback);

    void unregisterCallback(IDemoCallback callback);

    void triggerCallback(int value);
}

IDemoCallback.aidl内容如下:

package com.example.demo;

interface IDemoCallback {
    void onValueChanged(int value);
}

client/main.cpp内容如下:

#include <aidl/com/example/demo/BnDemoCallback.h>
#include <aidl/com/example/demo/IDemo.h>

#include <android/binder_manager.h>
#include <android/binder_process.h>

#include <log/log.h>

#include <iostream>
#include <memory>
#include <string>

using aidl::com::example::demo::BnDemoCallback;
using aidl::com::example::demo::IDemo;

class DemoCallback : public BnDemoCallback {
public:

    ndk::ScopedAStatus onValueChanged(
            int32_t value) override {

        ALOGI(
                "Callback received value=%d",
                value);

        std::cout
                << "[Callback] value = "
                << value
                << std::endl;

        return ndk::ScopedAStatus::ok();
    }
};

int main() {

    std::cout << "Demo client starting..."
              << std::endl;

    // ------------------------------------------------
    // 1. 获取 service
    // ------------------------------------------------

    std::string instance =
            std::string(IDemo::descriptor) +
            "/default";

    std::cout
            << "Waiting for service: "
            << instance
            << std::endl;

    ndk::SpAIBinder binder =
            ndk::SpAIBinder(
                    AServiceManager_waitForService(
                            instance.c_str()));

    if (binder == nullptr) {

        std::cerr
                << "Failed to get service"
                << std::endl;

        return 1;
    }

    // ------------------------------------------------
    // 2. 转换成 AIDL interface
    // ------------------------------------------------

    std::shared_ptr<IDemo> service =
            IDemo::fromBinder(binder);

    if (service == nullptr) {

        std::cerr
                << "Failed to create IDemo"
                << std::endl;

        return 1;
    }

    std::cout
            << "Connected to service"
            << std::endl;

    // ------------------------------------------------
    // 3. 普通函数调用
    // ------------------------------------------------

    int32_t result = 0;

    auto status =
            service->add(
                    10,
                    20,
                    &result);

    if (!status.isOk()) {

        std::cerr
                << "add() failed: "
                << status.getDescription()
                << std::endl;

        return 1;
    }

    std::cout
            << "add(10, 20) = "
            << result
            << std::endl;

    // ------------------------------------------------
    // 4. 创建 callback
    // ------------------------------------------------

    auto callback =
            ndk::SharedRefBase::make<DemoCallback>();

    // ------------------------------------------------
    // 5. 注册 callback
    // ------------------------------------------------

    status =
            service->registerCallback(
                    callback);

    if (!status.isOk()) {

        std::cerr
                << "registerCallback failed: "
                << status.getDescription()
                << std::endl;

        return 1;
    }

    std::cout
            << "Callback registered"
            << std::endl;

    // ------------------------------------------------
    // 6. 触发 callback
    // ------------------------------------------------

    for (int i = 0; i < 5; ++i) {

        int value = i * 100;

        std::cout
                << "Trigger callback: "
                << value
                << std::endl;

        status =
                service->triggerCallback(
                        value);

        if (!status.isOk()) {

            std::cerr
                    << "triggerCallback failed: "
                    << status.getDescription()
                    << std::endl;
        }
    }

    // ------------------------------------------------
    // 7. 注销 callback
    // ------------------------------------------------

    status =
            service->unregisterCallback(
                    callback);

    if (!status.isOk()) {

        std::cerr
                << "unregisterCallback failed"
                << std::endl;

        return 1;
    }

    std::cout
            << "Callback unregistered"
            << std::endl;

    return 0;
}

DemoService.cpp内容如下:

#include "DemoService.h"

#include <android/binder_ibinder.h>

#include <log/log.h>

namespace aidl::com::example::demo {

ndk::ScopedAStatus DemoService::add(
        int32_t a,
        int32_t b,
        int32_t* _aidl_return) {

    *_aidl_return = a + b;

    ALOGI("add(%d, %d) = %d",
          a,
          b,
          *_aidl_return);

    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus DemoService::registerCallback(
        const std::shared_ptr<IDemoCallback>& callback) {

    if (callback == nullptr) {
        ALOGE("registerCallback: callback is null");
        return ndk::ScopedAStatus::fromExceptionCode(
                EX_NULL_POINTER);
    }

    std::lock_guard<std::mutex> lock(mMutex);

    mCallbacks.push_back(callback);

    ALOGI("callback registered, total=%zu",
          mCallbacks.size());

    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus DemoService::unregisterCallback(
        const std::shared_ptr<IDemoCallback>& callback) {

    if (callback == nullptr) {
        return ndk::ScopedAStatus::fromExceptionCode(
                EX_NULL_POINTER);
    }

    std::lock_guard<std::mutex> lock(mMutex);

    for (auto it = mCallbacks.begin();
         it != mCallbacks.end();
         ++it) {

        if ((*it)->asBinder() == callback->asBinder()) {
            mCallbacks.erase(it);

            ALOGI("callback unregistered, total=%zu",
                  mCallbacks.size());

            return ndk::ScopedAStatus::ok();
        }
    }

    ALOGW("callback not found");

    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus DemoService::triggerCallback(
        int32_t value) {

    std::vector<std::shared_ptr<IDemoCallback>> callbacks;

    {
        std::lock_guard<std::mutex> lock(mMutex);
        callbacks = mCallbacks;
    }

    ALOGI("triggerCallback(%d), callback count=%zu",
          value,
          callbacks.size());

    for (const auto& callback : callbacks) {

        if (callback == nullptr) {
            continue;
        }

        auto status = callback->onValueChanged(value);

        if (!status.isOk()) {
            ALOGE("callback failed: %s",
                  status.getDescription().c_str());
        }
    }

    return ndk::ScopedAStatus::ok();
}

}  // namespace aidl::com::example::demo

DemoService.h内容如下:

#pragma once

#include <aidl/com/example/demo/BnDemo.h>
#include <aidl/com/example/demo/IDemoCallback.h>

#include <memory>
#include <mutex>
#include <vector>

namespace aidl::com::example::demo {

class DemoService : public BnDemo {
public:
    DemoService() = default;
    ~DemoService() override = default;

    ndk::ScopedAStatus add(
            int32_t a,
            int32_t b,
            int32_t* _aidl_return) override;

    ndk::ScopedAStatus registerCallback(
            const std::shared_ptr<IDemoCallback>& callback) override;

    ndk::ScopedAStatus unregisterCallback(
            const std::shared_ptr<IDemoCallback>& callback) override;

    ndk::ScopedAStatus triggerCallback(
            int32_t value) override;

private:
    std::mutex mMutex;

    std::vector<std::shared_ptr<IDemoCallback>> mCallbacks;
};

}  // namespace aidl::com::example::demo

service/main.cpp 内容如下:

#include "DemoService.h"

#include <aidl/com/example/demo/IDemo.h>

#include <android/binder_manager.h>
#include <android/binder_process.h>

#include <log/log.h>

using aidl::com::example::demo::DemoService;
using aidl::com::example::demo::IDemo;

int main() {

    ALOGI("Starting demo service");

    // 设置 Binder 线程池
    ABinderProcess_setThreadPoolMaxThreadCount(4);

    // 创建 service
    auto service = ndk::SharedRefBase::make<DemoService>();

    // 服务名
    std::string instance =
            std::string(IDemo::descriptor) + "/default";

    ALOGI("Register service: %s",
          instance.c_str());

    // 注册到 servicemanager
    binder_status_t status =
            AServiceManager_addService(
                    service->asBinder().get(),
                    instance.c_str());

    if (status != STATUS_OK) {

        ALOGE("Failed to register service: %d",
              status);

        return 1;
    }

    ALOGI("Demo service registered");

    // 进入 Binder 线程池
    ABinderProcess_joinThreadPool();

    return 0;
}

Android.bp内容如下:

aidl_interface {
    name: "demo-aidl",

    srcs: [
        "aidl/com/example/demo/*.aidl",
    ],

    local_include_dir: "aidl",

    unstable: true,

    vendor_available: true,

    backend: {
        java: {
            enabled: false,
        },

        cpp: {
            enabled: false,
        },

        ndk: {
            enabled: true,
        },
    },
}

cc_binary {
    name: "demo_service",

    srcs: [
        "service/DemoService.cpp",
        "service/main.cpp",
    ],

    shared_libs: [
        "libbinder_ndk",
        "liblog",
    ],

    static_libs: [
        "demo-aidl-ndk",
    ],

    vendor: true,

    init_rc: [
        "demo_service.rc",
    ],

    cflags: [
        "-Wall",
        "-Wextra",
    ],
}

cc_binary {
    name: "demo_client",

    srcs: [
        "client/main.cpp",
    ],

    shared_libs: [
        "libbinder_ndk",
        "liblog",
    ],

    static_libs: [
        "demo-aidl-ndk",
    ],

    vendor: true,

    cflags: [
        "-Wall",
        "-Wextra",
    ],
}

demo_service.rc内容如下

service demo_service /vendor/bin/demo_service
    class main
    user system
    group system

将创建的服务加入系统服务中

打开 device_vendor.mk 文件,在文件末尾添加创建的服务


# 1. 进入工程目录
cd /aosp

# 2. 修改 device_vendor.mk,末尾添加 demo_service 加入自启动服务中
vim device/google/cuttlefish/shared/auto/device_vendor.mk


PRODUCT_PACKAGES += CarServiceOverlayCuttleFish
GOOGLE_CAR_SERVICE_OVERLAY += CarServiceOverlayCuttleFishGoogle

PRODUCT_PACKAGES += ConnectivityOverlayCuttleFish
GOOGLE_CAR_SERVICE_OVERLAY += ConnectivityOverlayCuttleFishGoogle

TARGET_BOARD_INFO_FILE ?= device/google/cuttlefish/shared/auto/android-info.txt

[++++++] PRODUCT_PACKAGES += \
[++++++]    demo_service

SELinux 策略层问题解决

打开

cd /aosp
cd device/google/cuttlefish/shared/sepolicy/vendor

# 1. 修改 service_contexts
vim service_contexts
[++++++] com.example.demo.IDemo          u:object_r:demo_service_service:s0
[++++++] com.example.demo.IDemo/default  u:object_r:demo_service_service:s0

# 2. 修改 demo_service.te
vim demo_service.te
[++++++] type demo_service, domain;
[++++++] type demo_service_exec, exec_type, vendor_file_type, file_type;
[++++++] type demo_service_service, service_manager_type;

[++++++] init_daemon_domain(demo_service)

[++++++] binder_use(demo_service)
[++++++] allow demo_service demo_service:binder { call transfer };
[++++++] allow demo_service servicemanager:binder { call transfer };
[++++++] allow demo_service demo_service_service:service_manager { add find };

# 3. 修改 file_contexts
vim file_contexts
/vendor/lib(64)?/hw/android\.hardware\.health@2\.0-impl-2\.1-cuttlefish\.so  u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libcuttlefish_fs.so  u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/vsoc_lib.so  u:object_r:same_process_hal_file:s0
[++++++] /vendor/bin/demo_service        u:object_r:demo_service_exec:s0

开始测试

进入aosp环境,执行编译操作

source build/envsetup.sh

lunch aosp_cf_x86_64_auto-trunk_staging-userdebug

编译成功后,打开 cuttlefish docker 环境,进入其中进行测试,cuttlefish docker的部署可参照: 使用cuttlefish虚拟机测试AOSP程序

# 1. 进入 cuttlefish 容器中
sudo docker compose exec cuttlefish-common bash

# 2. 启动虚拟机
launch_cvd --system_image_dir=/aosp-out/target/product/vsoc_x86_64_only

# 3. 启动成功后,在另外一个终端执行,即可看到服务正常启动运行
adb connect 127.0.0.1:6520
adb root
adb shell getprop init.svc.demo_service
adb shell service list | grep -i demo
adb shell dmesg | grep -i avc | grep demo


评论