Android 11 创建自定义AIDL HAL

背景

项目中需要在Android 11中自定义HAL,由于从Android 11开始,可以使用AIDL定义HAL,本文简单记录了AIDL的HAL创建方法。

  • 注意:本文适用于Android 11,其他版本可能有不同的问题需要不同的解决方案。

步骤

1. 设置编译环境

source build/envsetup.sh
lunch aosp_trout_arm64-userdebug

2. 创建HAL目录
创建如下目录:
/hardware/interfaces/automotive/helloworld

  • 注意:后续所有目录均为上面目录下的相对路径。

3. 创建AIDL

  • 添加AIDL文件
    aidl/android/hardware/automotive/helloworld/IHelloworld.aidl:
package android.hardware.automotive.helloworld;
@VintfStability
interface IHelloworld {
	void sayHello(in String name);
}
  • 添加 Android.bp
    aidl/Android.bp:
aidl_interface {
    name: "android.hardware.automotive.helloworld",
    vendor_available: true,
    srcs: [
        "android/hardware/automotive/helloworld/*.aidl",
    ],
    stability: "vintf",
    owner: "mycompany",
    backend: {
        java: {
            platform_apis: true,
        }
    },
    versions: [],
}
  • 注意: 将owner设置为组织名称。

Android.bp:

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}

cc_defaults {
    name: "HelloworldiHalInterfaceDefaults",
    static_libs: [
        "android.hardware.automotive.helloworld-ndk_platform",
    ],
}

4. 生成 aidl_api
mm android.hardware.automotive.helloworld-update-api
此命令会生成如下目录结构:

aidl_api
└── android.hardware.automotive.helloworld
    └── current
        └── android
            └── hardware
                └── automotive
                    └── helloworld
                        └── IHelloworld.aidl
  • 注意: 如果Android.bp中未设置owner,此步骤会报如下错误:
TODO: 添加错误消息

随后运行

mm android.hardware.automotive.helloworld-freeze-api

此命令会添加如下目录结构:

aidl_api
└── android.hardware.automotive.vapi
    └── 1
        └── android
            └── hardware
                └── automotive
                    └── vapi
                        ├── IVapi.aidl
                        ├── IVapiCallback.aidl
                        └── StatusCode.aidl

Android.bp会被自动更新为:

aidl_interface {
    name: "android.hardware.automotive.helloworld",
    vendor_available: true,
    srcs: [
        "android/hardware/automotive/helloworld/*.aidl",
    ],
    stability: "vintf",
    owner: "mycompany",
    backend: {
        java: {
            platform_apis: true,
        }
    },
    versions: ["1"], // <== 添加版本1
}

5. 实现AIDL接口
添加impl目录及实现代码, 目录结构如下

impl
├── Android.bp
└── helloworldhal
    ├── Android.bp
    ├── include
    │   └── HelloworldHal.h
    └── src
        └── HelloworldHal.cpp

HelloworldHal.h

#ifndef android_hardware_automotive_vapi_aidl_impl_helloworldhal_include_HelloworldHal_H_
#define android_hardware_automotive_vapi_aidl_impl_helloworldhal_include_HelloworldHal_H_

#include <aidl/android/hardware/automotive/helloworld/BnHelloworld.h>
#include <android-base/expected.h>
#include <android-base/thread_annotations.h>
#include <android/binder_auto_utils.h>

namespace android {
namespace hardware {
namespace automotive {
namespace helloworld {

class HelloworldHal final : public aidl::android::hardware::automotive::helloworld::BnHelloworld {
public:
    ndk::ScopedAStatus sayHello(
        const std::string& name)
        override;
};

}  // namespace helloworld
}  // namespace automotive
}  // namespace hardware
}  // namespace android

#endif  // android_hardware_automotive_vapi_aidl_impl_helloworldhal_include_HelloworldHal_H_

HelloworldHal.cpp

#define ATRACE_TAG ATRACE_TAG_HAL

#include <HelloworldHal.h>

#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android/binder_ibinder.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <utils/Trace.h>

#include <inttypes.h>
#include <set>
#include <unordered_set>

namespace android {
namespace hardware {
namespace automotive {
namespace helloworld {

namespace {

using ::android::base::Error;
using ::android::base::expected;
using ::android::base::Result;
using ::android::base::StringPrintf;

using ::ndk::ScopedAIBinder_DeathRecipient;
using ::ndk::ScopedAStatus;

}  // namespace

ndk::ScopedAStatus HelloworldHal::sayHello(
    const std::string& name,
) {
    return ScopedAStatus::ok();
}

}  // namespace helloworld
}  // namespace automotive
}  // namespace hardware
}  // namespace android

service.cpp


#define LOG_TAG "android.hardware.automotive.occupant_awareness@1.0-service"

#include <unistd.h>

#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>

#include "OccupantAwareness.h"

using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
using ::ndk::ScopedAStatus;
using ::ndk::SharedRefBase;

const static char kHelloworldServiceName[] = "default";

int main() {
    ABinderProcess_setThreadPoolMaxThreadCount(0);
    LOG(INFO) << "Helloworld service is starting";
    std::shared_ptr<HelloworldHal> helloworldHal = SharedRefBase::make<HelloworldHal>();

    const std::string instance =
            std::string() + IHelloworldHal::descriptor + "/" + kHelloworldServiceName;

    binder_status_t status =
            AServiceManager_addService(helloworldHal->asBinder().get(), instance.c_str());
    if (status == STATUS_OK) {
        LOG(INFO) << "Service " << kHelloworldServiceName << " is ready";
        ABinderProcess_joinThreadPool();
    } else {
        LOG(ERROR) << "Could not register service " << kHelloworldServiceName
                   << ", status: " << status;
    }

    // In normal operation, we don't expect the thread pool to exit.
    LOG(ERROR) << "Helloworld service is shutting down";
    return 1;
}

helloworldhal/Android.bp

cc_binary {
    name: "android.hardware.automotive.helloworld@1.0-service",
    init_rc: ["android.hardware.automotive.helloworld@1.0-service.rc"],
    relative_install_path: "hw",
    vendor: true,
    srcs: [
        "service.cpp",
        "HelloworldHal.cpp",
    ],
    shared_libs: [
        "libbase",
        "libbinder_ndk",
        "libutils",
        "android.hardware.automotive.helloworld-ndk_platform",
    ],
}

Android.bp

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}

cc_defaults {
    name: "HelloworldHalDefaults",
    static_libs: [
        "libmath",
    ],
    shared_libs: [
        "libbase",
        "liblog",
        "libutils",
    ],
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wthread-safety",
    ],
    defaults: [
        "HelloworldHalInterfaceDefaults",
    ],
}

6. 编译
到 /hardware/interfaces/automotive/helloworld下,运行:

mm -j8

将会在 /out/target/product/trout_arm64/vendor/bin/hw 目录生成如下文件:

android.hardware.automotive.helloworld@1.0-service
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值