iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
1
Mobile Development

Android Pie 底層開發學習心得系列 第 9

[Day-09] Android HIDL (4) hidl-gen

  • Guide:
    • Treble 是什麼?
    • Treble 架構
    • HIDL 概述
    • HIDL 編碼規範
    • HIDL 中的 hidl-gen 使用
    • HIDL interface 和 package
    • HIDL import & inheritance
    • HIDL 實作

hidl-gen

首先看一下使用方法,然後再來大致解析一下用法和緣由吧。

一般在 AOSP 環境下要先執行下面命令才可以使用:

$ source build/envsetup.sh
$ lunch <DEVICE_NAME>

舉例這次 <DEVICE_NAME> 是用 aosp_marlin-userdebug

再加上 -h 參數就可以看到用法如下:

$ hidl-gen -h
usage: hidl-gen [-p <root path>] -o <output path> -L <language> [-O <owner>] (-r <interface root>)+ [-v] [-d <depfile>] FQNAME...

Process FQNAME, PACKAGE(.SUBPACKAGE)*@[0-9]+.[0-9]+(::TYPE)?, to create output.

         -h: Prints this menu.
         -L <language>: The following options are available:
            check           : Parses the interface to see if valid but doesn't write any files.
            c++             : (internal) (deprecated) Generates C++ interface files for talking to HIDL interfaces.
            c++-headers     : (internal) Generates C++ headers for interface files for talking to HIDL interfaces.
            c++-sources     : (internal) Generates C++ sources for interface files for talking to HIDL interfaces.
            export-header   : Generates a header file from @export enumerations to help maintain legacy code.
            c++-impl        : Generates boilerplate implementation of a hidl interface in C++ (for convenience).
            c++-impl-headers: c++-impl but headers only
            c++-impl-sources: c++-impl but sources only
            c++-adapter     : Takes a x.(y+n) interface and mocks an x.y interface.
            c++-adapter-headers: c++-adapter but helper headers only
            c++-adapter-sources: c++-adapter but helper sources only
            c++-adapter-main: c++-adapter but the adapter binary source only
            java            : (internal) Generates Java library for talking to HIDL interfaces in Java.
            java-constants  : (internal) Like export-header but for Java (always created by -Lmakefile if @export exists).
            vts             : (internal) Generates vts proto files for use in vtsd.
            makefile        : (removed) Used to generate makefiles for -Ljava and -Ljava-constants.
            androidbp       : (internal) Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter.
            androidbp-impl  : Generates boilerplate bp files for implementation created with -Lc++-impl.
            hash            : Prints hashes of interface in `current.txt` format to standard out.
         -O <owner>: The owner of the module for -Landroidbp(-impl)?.
         -o <output path>: Location to output files.
         -p <root path>: Android build root, defaults to $ANDROID_BUILD_TOP or pwd.
         -r <package:path root>: E.g., android.hardware:hardware/interfaces.
         -v: verbose output.
         -d <depfile>: location of depfile to write to.

update-makefiles.sh

在 Android 8.0 以上的版本中,改寫了大部分的 HAL 架構為 HIDL。

hardware/interfaces/update-makefiles.sh 可以創建編譯 HIDL 文件的 Android.bp

	1 #!/bin/bash
  2  
  3 source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh
  4  
  5 do_makefiles_update \
  6   "android.hardware:hardware/interfaces" \
  7   "android.hidl:system/libhidl/transport"
  8

可以看到 hidl-gen 真正的程式碼位置是在 system/tools/hidl/

通過 update-makefiles.sh 可以創建和編輯 HIDL 文件的 Android.bp

假設我們創建一個叫 helloworld 的模塊,
hardware/interfaces 底下建立一個 helloworld/1.0/IHelloWorld.hal

	1 package android.hardware.helloworld@1.0;                                                               
  2                                                                                                                                                                             
  3 interface IHelloWorld {                                                                                
  4     justTest(string name);                                                                             
  5 };

之後回到 AOSP 根目錄執行 update-makefiles.sh

$ ./hardware/interfaces/update-makefiles.sh

就可以在 hardware/interfaces/helloworld/1.0/ 底下生成 Android.bp

	1 // This file is autogenerated by hidl-gen -Landroidbp.                                                                                                                               
  2  
  3 hidl_interface {
  4     name: "android.hardware.helloworld@1.0",
  5     root: "android.hardware",
  6     vndk: {
  7         enabled: true,
  8     },
  9     srcs: [
 10         "IHelloWorld.hal",
 11     ],
 12     interfaces: [
 13         "android.hidl.base@1.0",
 14     ],
 15     gen_java: true,
 16 }
 17

name:FQname 的全名
root:定義好的 package root 名稱
interfaces:編譯過程中依賴的接口名稱,就像 C 中的 Library
gen_java:是否編譯為 JAVA 使用的接口
當然還有其他參數,例如 gen_java_constants 設為 true 的時候,
會生成為 Java 使用的 Constants 類。

update-files.sh

IHelloWorld.hal 和對應的 Android.bp 創建好後,
就可以根據需要實現 FQName-impl 和 FQName-service所需要的文件,
而這些文件也是通過 hidl-gen 創建的,就是新增下面這個腳本。

1 #! /bin/bash
2 PACKAGE=android.hardware.helloworld@1.0
3 LOC=$ANDROID_BUILD_TOP/hardware/interfaces/helloworld/1.0/default/
4
5 hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
6 -randroid.hidl:system/libhidl/transport $PACKAGE
7 hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
8 -randroid.hidl:system/libhidl/transport $PACKAGE

執行後就會產生出 default 底下的檔案:

.
└── 1.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── HelloWorld.cpp
│ └── HelloWorld.h
└── IHelloWorld.hal

稍微看一下裡面的 Android.bp:

 1 cc_library_shared {
 2     // FIXME: this should only be -impl for a passthrough hal.
 3     // In most cases, to convert this to a binderized implementation, you should:
 4     // - change '-impl' to '-service' here and make it a cc_binary instead of a
 5     // cc_library_shared.
 6     // - add a *.rc file for this module.
 7*     *// - delete HIDL_FETCH_I* functions.
 8     // - call configureRpcThreadpool and registerAsService on the instance.
 9     // You may also want to append '-impl/-service' with a specific identifier like
10     // '-vendor' or '-<hardware identifier>' etc to distinguish it.
11     name: "android.hardware.helloworld@1.0-impl",
12     relative_install_path: "hw",
13     // FIXME: this should be 'vendor: true' for modules that will eventually be
14     // on AOSP.
15     proprietary: true,
16     srcs: [
17         "HelloWorld.cpp",
18     ],
19     shared_libs: [
20         "libhidlbase",
21         "libhidltransport",
22         "libutils",
23         "android.hardware.helloworld@1.0",
24     ],
25 }

如註釋部分,可以根據特殊的需要進行修改,
例如 vendor 需要設為true,這樣編譯出來的so位於vendor下面,而不是system。
也可以使用同樣的方式為 FQName-service 創建對應的規則。


上一篇
[Day-08] Android HIDL (3) 編碼規範
下一篇
[Day-10] Android HIDL (5) interface & package
系列文
Android Pie 底層開發學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言