AIDL Hal 开发指南10 —— AIDL HAL 的升级

1,917 阅读5分钟

HAL 最后一篇教程,我们来看看 aidl hal 的升级。

我们之前写的 aidl hal 没有指定版本,默认版本为 V1。如果我们想要修改 aidl hal 就需要对 aidl hal 进行升级操作。

修改 aidl

第一步修改 aidl,在修改 aidl 之前需要执行以下命令冻结 aidl:

m android.hardware.hello-freeze-api

执行命令后,目录结构中会多一个名为 1 的文件夹:

20240418090025

接下来就可以修改 hardware/interfaces/hello_aidl_hal/aidl/android/hardware/hello/IHelloHal.aidl 了:

package android.hardware.hello;

@VintfStability 
interface IHelloHal {
    void hello_write(String str);
    String hello_read();

    //增加一个接口
    void hello_init();
}

修改的时候,通常是增加接口,不动之前的接口,保持老版本的兼容性。

修改完成后,接着执行:

m android.hardware.hello-update-api

执行完成后,会在 out/soong/.intermediates/hardware/interfaces/hello_aidl_hal 目录下生成 V2 相关的库:

20240418092102

服务端类代码修改

执行完成后,就在修改服务端实现:

// hardware/interfaces/hello_aidl_hal/aidl/default/HelloHalImpl.h

#ifndef ANDROID_HARDWARE_HELLO_H
#define ANDROID_HARDWARE_HELLO_H

#include <aidl/android/hardware/hello/BnHelloHal.h>

namespace aidl::android::hardware::hello {

class HelloHalImpl : public BnHelloHal {
  public:
        ::ndk::ScopedAStatus hello_write(const std::string& in_str) override;

        ::ndk::ScopedAStatus hello_read(std::string* _aidl_return) override;

        ::ndk::ScopedAStatus hello_init() override;
};

}  

#endif
// hardware/interfaces/hello_aidl_hal/aidl/default/HelloHalImpl.cpp
#define LOG_TAG "HelloHalImpl"
#define LOG_NDEBUG 0

#include "HelloHalImpl.h"

#include <log/log.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

namespace aidl::android::hardware::hello {


::ndk::ScopedAStatus HelloHalImpl::hello_write(const std::string& in_str) {
    ALOGD("write %s", in_str.c_str());
    int fd;
    int len = in_str.size();
	fd = open("/dev/hello", O_RDWR);
    write(fd, in_str.c_str(), len); 
    close(fd);   
    return ::ndk::ScopedAStatus::ok();
}
  
::ndk::ScopedAStatus HelloHalImpl::hello_read(std::string* _aidl_return)  {
    
    int fd;
    char buf[1024];
	fd = open("/dev/hello", O_RDWR);
    read(fd, buf, 1024);
    *_aidl_return = buf;
    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus HelloHalImpl::hello_init() {
     ALOGD("Hello hal init");
    return ::ndk::ScopedAStatus::ok();
}

}  

hello_init 中就简单打印一个日志。

客户端代码修改

    // hardware/interfaces/hello_aidl_hal/test_aidl_hal/main.cpp
    int main() {
        std::shared_ptr<IHelloHal> service = IHelloHal::fromBinder(ndk::SpAIBinder(AServiceManager_getService("android.hardware.hello.IHelloHal/default")));
        ALOGD("get service = %p\n",service.get());

        if (service == nullptr) {
            return -1;
        }
        // 添加 init
        service->hello_init();
        service->hello_write("hello");
        fflush(stdout);
        return EXIT_FAILURE;  // should not reach
    }

编译文件修改

接着,修改 Android.bp:

// hardware/interfaces/hello_aidl_hal/aidl/default/Android.bp

cc_binary {
    name: "android.hardware.hello.example",
    relative_install_path: "hw",
    vendor: true,
    init_rc: ["android.hardware.hello.rc"],
    vintf_fragments: ["hellohal-default.xml"],
    shared_libs: [
        // 改成 v2
        "android.hardware.hello-V2-ndk", 
        "liblog",
        "libbase",
        "libcutils",
        "libutils",
        "libbinder_ndk",
    ],
    srcs: [
        "main.cpp",
        "HelloHalImpl.cpp",
    ],
}
// hardware/interfaces/hello_aidl_hal/test_aidl_hal/Android.bp
cc_binary {
    name: "test_aidl_hal",
    vendor: true,
    shared_libs: [
        "android.hardware.hello-V2-ndk", 
        "liblog",
        "libbase",
        "libcutils",
        "libutils",
        "libbinder_ndk",
    ],
    srcs: [
        "main.cpp",
    ],
}

编译运行

最后编译运行:

source build/envsetup.sh
lunch aosp_cf_x86_64_phone-eng
m
cvd start  -kernel_path=/home/zzh0838/Project/aosp/kernel/out/virtual_device_x86_64/dist/bzImage  -initramfs_path=/home/zzh0838/Project/aosp/kernel/out/virtual_device_x86_64/dist/initramfs.img

adb shell 
test_aidl_hal
logcat | grep hello

log 信息如下:

04-18 17:31:06.700     0     0 W         : drivers/char/hello_driver.c hello_init line 69
04-18 17:31:07.913     0     0 I init    : Parsing file /vendor/etc/init/android.hardware.hello.rc...
04-18 17:31:12.555     0     0 I init    : starting service 'vendor.hellohal-default'...
04-18 17:31:12.565     0     0 I init    : ... started service 'vendor.hellohal-default' has pid 339
04-18 17:31:12.644     0     0 I servicemanager: Found android.hardware.hello.IHelloHal/default in device VINTF manifest.
04-18 17:31:19.401   560   560 I SystemServiceManager: Starting com.android.server.hello.HelloService
04-18 17:31:19.441     0     0 I servicemanager: Found android.hardware.hello.IHelloHal/default in device VINTF manifest.
04-18 17:31:19.422   560   560 D SystemServerTiming: OnBootPhase_100_com.android.server.hello.HelloService
04-18 17:31:19.422   560   560 V SystemServerTiming: OnBootPhase_100_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:21.769   560   560 D SystemServerTiming: OnBootPhase_200_com.android.server.hello.HelloService
04-18 17:31:21.769   560   560 V SystemServerTiming: OnBootPhase_200_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:36.456   560   560 D SystemServerTiming: OnBootPhase_480_com.android.server.hello.HelloService
04-18 17:31:36.456   560   560 V SystemServerTiming: OnBootPhase_480_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:36.517   560   560 D SystemServerTiming: OnBootPhase_500_com.android.server.hello.HelloService
04-18 17:31:36.517   560   560 V SystemServerTiming: OnBootPhase_500_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:36.876   560   560 D SystemServerTiming: OnBootPhase_520_com.android.server.hello.HelloService
04-18 17:31:36.876   560   560 V SystemServerTiming: OnBootPhase_520_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:36.957   560   560 D SystemServerTiming: OnBootPhase_550_com.android.server.hello.HelloService
04-18 17:31:36.957   560   560 V SystemServerTiming: OnBootPhase_550_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:38.655   560   560 D SystemServerTiming: OnBootPhase_600_com.android.server.hello.HelloService
04-18 17:31:38.655   560   560 V SystemServerTiming: OnBootPhase_600_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:38.769   560   560 D SystemServerTimingAsync: ssm.onStartUser-0_com.android.server.hello.HelloService
04-18 17:31:38.769   560   560 V SystemServerTimingAsync: ssm.onStartUser-0_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:43.730   560   587 D ActivityManagerTiming: OnBootPhase_1000_com.android.server.hello.HelloService
04-18 17:31:43.730   560   587 V ActivityManagerTiming: OnBootPhase_1000_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:44.105   560   594 D SystemServerTimingAsync: ssm.onUnlockingUser-0_com.android.server.hello.HelloService
04-18 17:31:44.105   560   594 V SystemServerTimingAsync: ssm.onUnlockingUser-0_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:45.150     0     0 W         : drivers/char/hello_driver.c hello_drv_open line 44
04-18 17:31:45.151     0     0 W         : drivers/char/hello_driver.c hello_drv_write line 37
04-18 17:31:45.151     0     0 W         : drivers/char/hello_driver.c hello_drv_close line 50
04-18 17:31:45.982   560   594 D SystemServerTimingAsync: ssm.onUnlockedUser-0_com.android.server.hello.HelloService
04-18 17:31:45.982   560   594 V SystemServerTimingAsync: ssm.onUnlockedUser-0_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:31:51.034   560  2617 D SystemServerTimingAsync: ssm.onCompletedEventUser-0_{|Unlocked|}_com.android.server.hello.HelloService
04-18 17:31:51.034   560  2617 V SystemServerTimingAsync: ssm.onCompletedEventUser-0_{|Unlocked|}_com.android.server.hello.HelloService took to complete: 0ms
04-18 17:34:48.428   339   339 D HelloHalImpl: write hello
04-18 17:34:48.467     0     0 W         : drivers/char/hello_driver.c hello_drv_open line 44
04-18 17:34:48.468     0     0 W         : drivers/char/hello_driver.c hello_drv_write line 37
04-18 17:34:48.468     0     0 W         : drivers/char/hello_driver.c hello_drv_close line 50

打印信息可以看出访问到了驱动代码。

参考资料